Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08a5db55df | ||
|
|
67ee52624c | ||
|
|
0d2e573e0d | ||
|
|
bd416f7327 | ||
|
|
23e52c80de | ||
|
|
84084bba37 | ||
|
|
efd7d788d9 | ||
|
|
b1c510a097 | ||
|
|
5f3680a0fb | ||
|
|
4ff91e8d6e | ||
|
|
5f3a7f5975 | ||
|
|
043ffdfad6 |
@@ -30,3 +30,7 @@ coverage/
|
||||
data/
|
||||
sessions/
|
||||
workspace-registry/
|
||||
|
||||
.tht/
|
||||
|
||||
deploy/local/
|
||||
|
||||
@@ -7,6 +7,11 @@ on:
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "mkdocs.yml"
|
||||
- "scripts/build-docs.sh"
|
||||
- "scripts/verify-public-docs.py"
|
||||
- "scripts/test-verify-public-docs.py"
|
||||
- "scripts/verify-auth-docs.py"
|
||||
- "scripts/test-verify-auth-docs.py"
|
||||
- "docs/requirements.txt"
|
||||
- ".gitea/workflows/publish-docs.yml"
|
||||
workflow_dispatch:
|
||||
@@ -34,14 +39,25 @@ jobs:
|
||||
with:
|
||||
python-version: "3.x"
|
||||
cache: pip
|
||||
cache-dependency-path: docs/requirements.txt
|
||||
cache-dependency-path: docs/requirements.lock
|
||||
|
||||
- name: Install MkDocs dependencies
|
||||
run: python -m pip install -r docs/requirements.txt
|
||||
run: python -m pip install -r docs/requirements.lock
|
||||
|
||||
- name: Test public documentation boundary
|
||||
run: python scripts/test-verify-public-docs.py
|
||||
|
||||
- name: Test current authentication documentation
|
||||
run: |
|
||||
python scripts/verify-auth-docs.py auth
|
||||
python scripts/verify-auth-docs.py dwh
|
||||
python scripts/test-verify-auth-docs.py auth
|
||||
python scripts/test-verify-auth-docs.py dwh
|
||||
|
||||
- name: Build documentation
|
||||
# Some documented source files intentionally live outside docs/.
|
||||
run: mkdocs build
|
||||
run: |
|
||||
mkdocs build --strict
|
||||
python scripts/verify-public-docs.py
|
||||
|
||||
- name: Publish generated site to the pages branch
|
||||
working-directory: site
|
||||
|
||||
@@ -118,6 +118,15 @@ ritrovamento di una card tramite un collegamento non ne implica l'approvazione.
|
||||
espliciti, che contribuisce alla consultazione di contenuti pertinenti. La sua
|
||||
rimozione non comporta la cancellazione delle card collegate.
|
||||
|
||||
## Esempi didattici
|
||||
|
||||
**Example workspace** — Un workspace destinato alla pratica con ThothII, associato
|
||||
a dati di esempio, schema descritto ed Evidence curate, pronto per iniziare una sessione.
|
||||
|
||||
**Practice question** — Una domanda di accompagnamento a un Example workspace,
|
||||
proposta come spunto per il percorso human in the loop e priva di soluzione attesa.
|
||||
_Avoid_: Solved Question, caso di valutazione del benchmark.
|
||||
|
||||
## Evidence
|
||||
|
||||
**Context specialist** — La persona competente sul dominio che redige e cura il
|
||||
|
||||
@@ -1,704 +1,95 @@
|
||||
# ThothII — Project State
|
||||
|
||||
Last updated: 2026-09-14.
|
||||
|
||||
This file is the short operational snapshot. Stable commands and the architecture mental model
|
||||
live in `AGENTS.md`; current design and runtime contracts live under `docs/architecture/`,
|
||||
`docs/contracts/`, `docs/adr/`, and `docs/evidence.md`. Superseded plans and reports are
|
||||
available from Git history rather than duplicated in the working tree.
|
||||
|
||||
The guarded server migration from a legacy checkout to the schema-v2 installation, Gitea source,
|
||||
Authentik, internal catalog/embedding services, and the PSD workspace repository is documented in
|
||||
`docs/operations/server-upgrade-gitea-workspace-v2.md`. Treat its operator gates and rollback
|
||||
requirements as mandatory; do not replace the running server stack in place.
|
||||
|
||||
## Session review layout deployed — 2026-09-14
|
||||
|
||||
Session-only dialogs now use the visible app bounds: artifact/column review grows
|
||||
up to 80rem wide and the available height; short confirmations grow to 40rem.
|
||||
Existing primary actions appear above and below session forms and review content,
|
||||
with shared handlers, validation and pending state. Stop/delete focus Cancel;
|
||||
rename focuses the name field. Administration surfaces are unchanged. The activity
|
||||
shortcut is relabelled To Administration / Vai all’Amministrazione, retaining its
|
||||
workspace-management destination. 778 frontend tests, five responsive browser
|
||||
scenarios, typecheck, translations and the production build passed. The owner
|
||||
authorized deployment and the server frontend was recreated at 18:09 CEST with tag `b1723c34-session-dialogs-20260914`. Frontend is healthy,
|
||||
Omics serves the new assets, and doctor passes 13/13 checks. Core and Omics web
|
||||
were not restarted. See DESIGN.md for the layout contract and
|
||||
`docs/reports/2026-09-14-session-dialogs-release.md` for provenance and rollback.
|
||||
|
||||
## Session composer and empty Memory fix deployed — 2026-09-14
|
||||
|
||||
The embedded shell now caps its height at the portal mount height, keeping steering
|
||||
and Stop & save visible. Empty authoritative Memory archives return zero results
|
||||
without requiring embedding/BM25; SQL-rule embedding is lazy and shared. The live
|
||||
empty PSD archive reproduces 503 with the current image and succeeds with the
|
||||
candidate. 54 Memory tests, 90 frontend tests, five browser scenarios and both image
|
||||
builds passed. The owner authorized the restart and core/frontend were recreated on
|
||||
2026-09-14 at 17:18 CEST with tags `49333a2d-session-memory-fix`, from code committed
|
||||
as `d6cdffea`. Both are healthy; production Memory search returns `[]`, Omics serves
|
||||
the corrected CSS, native doctor passes 13/13 checks, and admissions are reopened.
|
||||
Session inventory is preserved. Backups and rollback images are retained. Native
|
||||
CLI diagnostics must run as installation owner UID 10001 with access to Compose;
|
||||
see `docs/reports/2026-09-14-session-layout-memory-fix.md` for exact commands and
|
||||
the remaining interactive browser acceptance.
|
||||
|
||||
## Full/embedded shell and bilingual interface
|
||||
|
||||
Full/embedded shell, EN/IT UI, immutable session interaction language, dark theme,
|
||||
fullscreen and full-mode logout are implemented. The local Mac descriptor explicitly
|
||||
sets `shell.mode: full` and `shell.defaultLocale: en`; the native `tht` and local
|
||||
core/frontend images were updated on 2026-09-13. Omics uses embedded with server-side
|
||||
identity verification and a replaceable presentation-only PortalAdapter; this does
|
||||
not mean this branch was verified on the production server. Its changes are
|
||||
in Omics commit `95154e1`; production deployment remains pending.
|
||||
See `docs/operations/shell-and-localization.md` for integration and installation
|
||||
instructions and `docs/reports/2026-09-13-full-shell-implementation.md` for tests,
|
||||
independent reviews, local browser checks and rollback details.
|
||||
|
||||
### Documentation handoff before branch closure — 2026-09-13
|
||||
|
||||
Current rendering architecture is in `docs/architecture/application-shell.md`;
|
||||
the exact portal identity/proxy contract is in `docs/install/authentication-upstream.md`.
|
||||
`docs/operations/server-codex-handoff.md` is the current server delivery/deploy
|
||||
runbook, including Omics source integration from GitHub, configuration, tests and
|
||||
rollback. It supersedes the earlier Omics repository-relay instructions. The acceptance matrix is
|
||||
`docs/testing/authentication-manual-acceptance.md`. README, documentation navigation,
|
||||
user/installation/authentication guides and descriptor examples point to these
|
||||
paths. Local examples explicitly use full/en; the projected server example is
|
||||
for standalone OIDC, not Omics upstream. No runtime configuration or deployment
|
||||
was changed by that documentation pass. The 2026-09-14 delivery is prepared for
|
||||
promotion to main; the actual merge is recorded in Git. PSD acceptance remains pending.
|
||||
|
||||
### Navigation readiness and session accordions — 2026-09-13
|
||||
|
||||
The Workspace navigation button now carries an accessible green/red readiness
|
||||
dot instead of a separate text row. Green requires a selected workspace and a
|
||||
successful, current `ready` response; checking, unavailable and other states are
|
||||
red, with the state exposed through the tooltip and accessible description.
|
||||
The backend readiness gate is unchanged.
|
||||
|
||||
Active sessions (non-archived) and Archive both start collapsed. Their adjacent
|
||||
headers are the only visible content below the scope tabs: no Sessions heading
|
||||
or external selection toolbar. Each nonempty panel owns its Select all and
|
||||
bulk-delete controls, scoped to that list and preserving the other's selection.
|
||||
As of 2026-09-14, only one section can be open at a time, and either can be
|
||||
collapsed. Empty lists show only "No sessions yet." The open section uses the
|
||||
remaining sidebar height, with scrolling content capped at `min(18rem, 35dvh)`. The mobile
|
||||
navigation dialog also provides a bounded height. Keyboard controls and labels
|
||||
are retained. See `DESIGN.md` and `docs/guida-utente.md` for the UI contract.
|
||||
|
||||
Verification: 768 frontend unit tests, 20 browser scenarios (including 80 mocked
|
||||
sessions at 390/1280px), TypeScript and the production frontend build passed.
|
||||
Only the Mac frontend was recreated; it is healthy at `127.0.0.1:8080`.
|
||||
Core, catalog, Qdrant and embedding containers were not changed. The prior
|
||||
frontend image is retained as
|
||||
`thothii-frontend:before-single-session-accordion-20260914` for rollback.
|
||||
|
||||
### Current Omics delivery and server handoff — 2026-09-14
|
||||
|
||||
The owner corrected the delivery requirement: Omics is obtained from GitHub,
|
||||
not relayed to another repository as part of this deployment. Any optional
|
||||
server-side repository copy is solely the owner's separate concern. This
|
||||
supersedes the 2026-09-13 relay agreement, including historical delivery notes
|
||||
in the Omics branch. Do not make another remote publication a prerequisite.
|
||||
|
||||
GitHub branch `codex/thothii-embedded-shell` at
|
||||
`https://github.com/Dallavilla-Tiziano/omics_portal.git` was reverified at
|
||||
`fca10901a73666ca257d8f4cc4b77066295c400a` (functional commit `95154e1`).
|
||||
The server operator integrates it with the current code in the confirmed Omics
|
||||
checkout, normally `/home/chirone/omics_portal`, preserving later server changes.
|
||||
`docs/operations/server-codex-handoff.md` is the authoritative ordered procedure:
|
||||
inventory, source verification, native CLI and installation projections,
|
||||
embedded/upstream auth, Omics templates/static assets/proxy, coordinated rollout,
|
||||
acceptance and rollback. Server deployment and real IdP acceptance remain pending.
|
||||
|
||||
## Current product shape
|
||||
|
||||
### Shared Memory/Evidence typography — 2026-09-13
|
||||
|
||||
Both detail readers now share Manrope and fixed reading roles: 24px card title,
|
||||
20px section headings, 16px/1.65 narrative text, and 14px metadata/code. Authored
|
||||
Markdown subheadings remain subordinate to field headings; inline/fenced code no
|
||||
longer shrinks cumulatively. Full-width layout, paragraph separation and isolated
|
||||
FAKE examples are retained. All 762 frontend tests and 18 browser scenarios pass,
|
||||
including computed typography checks at 390/1280/2400px; typecheck, i18n and Docker
|
||||
build pass. Only Mac frontend was recreated: `87fca0dc5e19`, image `19f1704b6bb2`,
|
||||
healthy. Core and data services are unchanged. Rollback image:
|
||||
`thothii-frontend:before-knowledge-typography-20260913`. See
|
||||
`docs/reports/2026-09-13-knowledge-typography.md`. No PSD/Omics deployment.
|
||||
|
||||
### Knowledge reading and isolated fake Memory examples — 2026-09-13
|
||||
|
||||
Memory/Evidence details now use all available width, with display-only paragraph
|
||||
splitting for long plain prose and preserved code/Markdown/source data. Evidence
|
||||
provenance renders Markdown; copy controls are accessible two-sheet icons.
|
||||
Memory's separate Formatting examples section contains four FAKE cards (one per
|
||||
family), automatically expanded for an empty archive. These client-side examples
|
||||
cannot be edited/saved/indexed and are never submitted to the model or Memory API.
|
||||
No real archive content was changed. 762 tests, 18 browser scenarios, typecheck,
|
||||
i18n and Docker build pass. Only the Mac frontend was recreated: `fc4286b5406d`,
|
||||
image `cbe0fe0dce55`, healthy; other services unchanged. Rollback image:
|
||||
`thothii-frontend:before-knowledge-reading-20260913`. Details in
|
||||
`docs/reports/2026-09-13-knowledge-reading.md`; no PSD/Omics deployment.
|
||||
|
||||
### Unified Session entry and complete tab borders — 2026-09-13
|
||||
|
||||
The sidebar has one Session/Sessione button: return to the current unfinished
|
||||
session (including pending creation) without resetting/reconnecting it; otherwise
|
||||
prepare a new question with existing readiness and dirty-edit guards. Creation
|
||||
still requires submitting a question. A cold document panel is not a running session.
|
||||
Session tabs now have 11px horizontal/3px vertical padding, at least 38px height,
|
||||
and matching 1px borders on every side (gray inactive, red active), with no shared
|
||||
baseline or overlapping bottom border. This supersedes the earlier border removal.
|
||||
757 frontend tests, 15 browser scenarios, typecheck, i18n and Docker build pass.
|
||||
Mac frontend `2844778d311c`, image `d58dccfee3f9`, is healthy; only that service
|
||||
was recreated. Core/data services are unchanged, with no Omics or server deploy.
|
||||
Rollback image: `thothii-frontend:before-session-navigation-20260913`.
|
||||
|
||||
### Login copy and language-selector focus — 2026-09-13
|
||||
|
||||
Removed the redundant login eyebrow/icon and installation-account explanation;
|
||||
the main sign-in heading remains. The full-header language select no longer
|
||||
shows an outer focus ring after pointer interaction; keyboard focus remains
|
||||
visible, including after returning with Tab. EN/IT login and both themes are
|
||||
covered by 36 targeted tests and 14 browser scenarios; typecheck/build pass.
|
||||
Only the Mac frontend was rebuilt/recreated: `204efd40d3eb`, image `7dd0752ff823`,
|
||||
healthy. Other containers are unchanged. Rollback image:
|
||||
`thothii-frontend:before-login-focus-20260913`. No production deployment.
|
||||
|
||||
### Full-header and layout refinements — 2026-09-13
|
||||
|
||||
The owner's four visual adjustments are implemented: full header uses Omics
|
||||
`#CB333B` in both themes with a light complete wordmark/controls; Database status
|
||||
has 16px clearance below its top divider; workspace/model/Done share a compact
|
||||
desktop row; session-scope tabs have no bottom border. Embedded has no extra header.
|
||||
Verified with 71 targeted frontend tests, 11 browser scenarios, typecheck and
|
||||
Docker production build. The Mac frontend was recreated alone and is healthy
|
||||
(`8a1608ad7fc6`, image `a2f489ebe9de`); Core/data-service containers are unchanged.
|
||||
Full/en is retained. Rollback image: `thothii-frontend:before-header-layout-20260913`.
|
||||
See `docs/reports/2026-09-13-header-layout-refinements.md` for validation and rollback.
|
||||
|
||||
### Visual review integrated with the full/embedded shell
|
||||
|
||||
At the owner's request, the seven commits through `a59624a6` from
|
||||
`codex/ui-visual-review` are integrated with the shell/i18n work in this checkout,
|
||||
`codex/prototype-administration-pages`. Both branches started at `2d1b714e`; the
|
||||
first full-shell build omitted that lateral branch and regressed the installed UI.
|
||||
The integrated source retains bundled Manrope, shared type roles, catalog/context
|
||||
alignment, wordmark sizes and composer autosizing alongside full/embedded and EN/IT.
|
||||
|
||||
Local Docker was updated at 12:54 UTC on 2026-09-13: frontend image `605a6e6bba68`,
|
||||
healthy; Core and all data-service containers were unchanged. Mac remains full/en.
|
||||
The immediate pre-merge frontend is retained as
|
||||
`thothii-frontend:before-visual-shell-merge-20260913`.
|
||||
|
||||
Verification: 755 frontend tests, 11 Playwright visual/interaction scenarios at five
|
||||
widths, translation-catalog checks, typecheck and production build. See
|
||||
`docs/reports/2026-09-13-visual-shell-integration.md` for delivery, provenance and
|
||||
rollback details. The separate visual-review worktree and its rollback images are
|
||||
retained. No merge to `main`, push or production deployment is part of this delivery.
|
||||
|
||||
Gitea #28–#31 follow-up is implemented in this checkout: Workspace's four tabs,
|
||||
Database list-first entry without the preparation footer, full-height Pi instructions
|
||||
with installation-host OS selection, and short Admin navigation labels. Core and
|
||||
session behavior are retained. At the owner's request, these changes were rebuilt into
|
||||
local Docker on 2026-09-12 at 18:31 UTC. Core/frontend are healthy and the UI at
|
||||
`http://127.0.0.1:8080` serves the updated bundle. The host projection now supplies
|
||||
`THT_HOST_PLATFORM=darwin`, so Pi selects macOS rather than the container's Linux OS.
|
||||
Persistent dependency containers and volumes were unchanged. Rollback images are tagged
|
||||
`thothii-core:before-admin-28-31-20260912` and
|
||||
`thothii-frontend:before-admin-28-31-20260912`. See
|
||||
`docs/reports/2026-09-12-admin-issues-28-31.md` for verification and deployment details.
|
||||
|
||||
The latest context-shelf A and five Administration pages are implemented locally.
|
||||
At the owner's request, local Docker project `thothii-18998cca7b0a` was rebuilt and
|
||||
its core/frontend recreated on 2026-09-12. The real UI at `http://127.0.0.1:8080`
|
||||
serves shelf A; both services and their existing dependencies are healthy.
|
||||
Runtime model projections were regenerated as schema v2 with the single
|
||||
`zai/glm-5.3` interaction default. Persistent services/volumes were not recreated.
|
||||
The local launcher `/private/tmp/thothii-memory-preview.sh` now adds
|
||||
`/private/tmp/thothii-context-a.compose.yaml` last, building from this checkout
|
||||
instead of the earlier Memory worktree. Previous images are retained under
|
||||
`thothii-core:before-context-a-20260912` and
|
||||
`thothii-frontend:before-context-a-20260912`. Remote server deployment remains pending.
|
||||
Core/session behavior is retained; one independently remembered workspace/model
|
||||
pair controls both Core and Admin. Unsaved Admin changes block navigation and
|
||||
context changes; operation activity locks the selectors. See
|
||||
`docs/reports/2026-09-12-context-shelf-a-implementation.md` for verification and the
|
||||
remaining server/Omics integration gate. Prototype alternatives remain untouched.
|
||||
|
||||
ThothII is a human-in-the-loop datamart builder with three independently built layers:
|
||||
|
||||
```text
|
||||
frontend (React/SSE) → backend (Fastify) → pi --mode rpc → tht/harness → DWH (read-only)
|
||||
```
|
||||
|
||||
The harness owns the deterministic eight-phase NL→SQL workflow and all session persistence.
|
||||
The backend remains a process/RPC/SSE bridge for sessions and now also owns an isolated PostgreSQL
|
||||
metadata catalog for administrative database configuration. The frontend renders the review gates
|
||||
and keeps the live transcript in memory. See
|
||||
`docs/architecture/components.md` for the detailed component and data-flow map.
|
||||
|
||||
## Memory M1–M3, Evidence E1–E3 and joint workflow repair X1 implemented
|
||||
|
||||
Browser authorization now derives permissions from validated session roles using the current
|
||||
catalog. This fixes Memory/Evidence navigation remaining disabled for administrators whose
|
||||
remembered login predates those permissions; refreshing the page loads the updated permissions.
|
||||
|
||||
The owner requested two independent administration projects: Memory management and Evidence
|
||||
management. Their navigation entries must sit immediately after Database management, as peers;
|
||||
neither page belongs to Database management. Both require complete browsing, filtering, and CRUD
|
||||
without an active core session. Shared requirements and the two project briefs are linked from
|
||||
`docs/plans/2026-09-08-memory-evidence-administration.md`. Memory administration is implemented;
|
||||
Evidence administration is implemented through external file editing and explicit consolidation.
|
||||
Evidence editing requires an explicit evolution of the current authoring/publication contract.
|
||||
The M1 specification is at `docs/plans/2026-09-08-memory-m1-spec.md` and published as
|
||||
[M1 — Archivio autorevole e amministrazione delle Memory Card](https://git.tylconsulting.it/mptyl/ThothII/issues/27)
|
||||
with the `ready-for-agent` and `enhancement` labels.
|
||||
It covers the authoritative store, administrative CRUD, projection recovery, and current
|
||||
Memory/exemplar producer integration. Its accepted test boundaries are the public harness
|
||||
service, Fastify APIs, and the AppShell page, joined by a focused real-stack browser path.
|
||||
The owner confirmed those boundaries and authorized publication on 2026-09-08.
|
||||
M1 is implemented locally: PostgreSQL authority in `thoth_memory`, versioned installation
|
||||
migrations, admin CRUD for all four families, structured dependencies and links, explicit
|
||||
projection recovery, verified recall and current workflow producers. The page requires no
|
||||
active session or DWH binding. The existing `catalog-migrate` preparation service now runs
|
||||
Memory migrations as well. Existing installations need that preparation before using M1;
|
||||
the initial implementation did not deploy or migrate the owner's stacks.
|
||||
The integrated browser check passed with real authentication, Fastify, ThtRunner, harness,
|
||||
PostgreSQL and Qdrant; embeddings were deterministic and unrelated Pi/session activity used
|
||||
test fixtures. See `docs/plans/2026-09-08-memory-m1-validation.md` for results and commands.
|
||||
M2 is implemented locally: Memory dense/BM25 fusion, physical and business scope filters,
|
||||
bounded outgoing-link expansion and joint ranking, all resolved against current PostgreSQL
|
||||
authority. Migration `002_hybrid_projection.sql` makes old dense projections pending until
|
||||
explicit retry/rebuild; Reference remains separate. The real retrieval check uses the configured
|
||||
`qwen3-embedding:0.6b` model, a separate Ollama process with a read-only model-volume mount,
|
||||
and isolated PostgreSQL/Qdrant resources. See `docs/plans/2026-09-09-memory-m2-validation.md`.
|
||||
M3 is implemented: editable F8 summary grounded in effective approved decisions, explicit
|
||||
updates with concurrent-edit protection, selected-card/link transactions and durable review
|
||||
receipts. Finalization no longer saves exemplars implicitly. SQL rules and explained errors
|
||||
are consulted in the existing F4/F6/F7 gates. Successful Catalog physical synchronization
|
||||
performs dependency cleanup, preserving the original removals for recovery across restarts.
|
||||
Migration `003_review_receipts.sql` is required. Validation includes a real GLM 5.3 generation
|
||||
case against synthetic PostgreSQL data; see `docs/plans/2026-09-09-memory-m3-validation.md`.
|
||||
Evidence administration and the joint X1 conflict-repair increment are now implemented.
|
||||
The same local preview was subsequently rebuilt with M3 and migration 003 applied.
|
||||
Core and frontend now include the final Memory review and physical dependency cleanup.
|
||||
On 2026-09-09, at the owner's request, the local PSD Docker installation
|
||||
`thothii-18998cca7b0a` was updated from this worktree. Core/frontend images were rebuilt,
|
||||
Catalog and Memory migrations completed, and all five services became healthy. The UI is at
|
||||
`http://127.0.0.1:8080`, using the existing local authentication and persistent volumes.
|
||||
The `psd-clinical` authoritative Memory archive is initially empty (no legacy import).
|
||||
The existing installation configuration remains in `/Users/mp/projects/ThothII/deploy/psd/`;
|
||||
`/private/tmp/thothii-memory-preview.sh` invokes its Compose files with a final build-context
|
||||
and migration-command override from this worktree. A future build from the main checkout
|
||||
will use that checkout's code, so retain the worktree override until the changes are integrated.
|
||||
Memory revision history and compatibility with existing development sessions are not requirements.
|
||||
The agreed Memory scope includes reusable domain clarifications, SQL construction rules, solved
|
||||
questions, and explained, approved mistakes to avoid. This extends the current runtime's
|
||||
`concept_clarified`-only reusable Memory contract. The owner also approved an editable final summary
|
||||
for proposed additions/updates and Memory consumption in the relevant existing review gates.
|
||||
Further agreed behavior includes persistent corrections for Memory/Evidence conflicts through
|
||||
explicit choices, deletion of Memory with invalid dependencies after successful physical schema
|
||||
synchronization, and bounded functional/regression tests instead of a general quality benchmark.
|
||||
In-house Memory evolution is approved, including hybrid Qdrant retrieval and explicit card links
|
||||
traversed in core, without a dedicated graph database. Both capabilities belong to the current
|
||||
scope. PostgreSQL is the agreed authority for Memory Cards, links, and schema dependencies;
|
||||
Qdrant is a rebuildable index. Links are reviewed with cards and editable in Administration;
|
||||
deleting a card removes its incident links while preserving the other cards. The accepted,
|
||||
implemented architecture is recorded in
|
||||
`docs/adr/0018-use-postgres-for-memory-and-qdrant-for-retrieval.md`.
|
||||
For Evidence administration, Q12 rejects a separate editorial publication workflow.
|
||||
The final R0 direction uses external editors and a manual consolidation command that
|
||||
validates structure, reports required corrections, updates derived metadata, and
|
||||
activates the local Evidence index. The operator then checks the diff and runs Git
|
||||
commit/push manually. No watcher, automated Git, or web editor is required.
|
||||
The owner's later simplification
|
||||
instruction removes the requirement to support administrative edits while core work
|
||||
is in progress. Deliberate corrections made by the workflow itself remain supported.
|
||||
The context specialist writes Evidence drafts independently of the installation and
|
||||
without PostgreSQL access; the system refines them and stores them locally for use
|
||||
and maintenance. The revised Q11 recommendation separates external drafts from a
|
||||
durable local canonical file archive, removing automatic commit/push from CRUD.
|
||||
The owner has now accepted local files and requires discoverable, editable Markdown
|
||||
for nontechnical domain specialists, with no JSONL management surface. Editors on
|
||||
Mac/PC or vim/nano on the server are the chosen R0 editing surface. Evidence
|
||||
management keeps browsing/filtering/detail and clearly identifies the persistent
|
||||
working tree, each Markdown file's actual host path, and the manual commands.
|
||||
E1 implements editable Curated Evidence v4, deterministic legacy conversion, persistent
|
||||
local files and a consolidation API with immutable candidates, manual provenance,
|
||||
deletion records and recoverable activation. E2 connects its installed command, runtime source
|
||||
selection and administration page. The operator completes Git steps manually.
|
||||
All 35 PSD units were converted on an isolated copy with identical IDs and typed content.
|
||||
Tests exercise visible edits through normalization, indexing and recall with real Qdrant;
|
||||
see `docs/plans/2026-09-09-evidence-e1-validation.md` and
|
||||
`docs/contracts/curated-evidence-v4.md`. E2 is now running on the local Docker preview:
|
||||
all 35 PSD units were converted and indexed through the installed command. The editable
|
||||
host archive is `/Users/mp/projects/ThothII/deploy/psd/evidence-registry/repo/psd-clinical/evidence`.
|
||||
The original registry-volume checkout and original author repository were retained.
|
||||
The installation descriptor now includes `workspace-bindings.yaml` and `evidence-host.yaml`
|
||||
so native maintenance uses the same volumes and checkout as the preview. Descriptor backup:
|
||||
`/private/tmp/thothii-installation-before-e2.yaml`; previous native binary: `/private/tmp/tht-before-e2`.
|
||||
The launcher remains `bash /private/tmp/thothii-memory-preview.sh`; its worktree build override
|
||||
is still required until integration. Runtime lease filenames now include rendered bytes so
|
||||
upgrading the Evidence renderer does not collide with old immutable configs; Catalog
|
||||
input fingerprints and readiness are unchanged. See `docs/plans/2026-09-09-evidence-e2-validation.md`.
|
||||
E3 adds explicit source acquisition/refinement and durable comparisons in Evidence management.
|
||||
Local drafts go in `evidence/incoming/`; original local documents and configured HTTP/S3
|
||||
sources are reacquired only by **Import or refresh sources** or installed
|
||||
`tht workspace evidence refresh --workspace <id>`. Keep/replace decisions, including the
|
||||
native `workspace evidence decide` command, activate through the existing archive/index
|
||||
path and have durable retry state. Acquired source versions and remote provenance stay
|
||||
local; old documentary lineage can coexist with current manual declarations.
|
||||
The installed preview's 35 PSD sources were verified unchanged with no new proposals.
|
||||
The previous native CLI is backed up at `/private/tmp/tht-before-e3`.
|
||||
See `docs/plans/2026-09-09-evidence-e3-validation.md` for tests and validation limits.
|
||||
X1 adds `reviewer_archive_repair`: closed alternatives with complete before/after content,
|
||||
explicit rejection/reformulation, admin-only application, durable session receipts and
|
||||
retry of saved but inactive corrections. The coordinator uses the canonical Memory and
|
||||
Evidence services; phase approval remains separate. Migration `004_archive_repairs.sql`
|
||||
is required. See `docs/contracts/archive-repair.md` for authorization and recovery limits.
|
||||
X1 validation is recorded in `docs/plans/2026-09-09-archive-repair-x1-validation.md`:
|
||||
both archives were corrected and retrieved through the actual CLI with real PostgreSQL
|
||||
and Qdrant; desktop/mobile widget behavior and permission failures were verified separately.
|
||||
The local preview images include X1 and migration 004 is applied. Follow-up technical
|
||||
acceptance passed with configured GLM 5.3 generating closed conflict alternatives and
|
||||
the chosen Memory correction persisted and retrieved. An authenticated browser test
|
||||
also verified both administration pages, navigation order, Evidence filtering, workspace
|
||||
404s, desktop/mobile layout, and Evidence survival after Memory deletion. All approved
|
||||
technical increments/checks are complete. A real PSD domain-conflict session remains
|
||||
the reviewer's semantic acceptance check; automated cases did not modify PSD knowledge.
|
||||
The joint browser inspection also fixed mobile archive navigation: below 768px,
|
||||
Memory and Evidence keep the full content width and open navigation in the shared
|
||||
accessible dialog. Desktop retains its sidebar; the local frontend image includes this fix.
|
||||
The owner accepted the remaining simplifications and requested explicit clarification
|
||||
of the core format change and the simple terminal-based Git check. E1 must adapt
|
||||
the Evidence parser, renderer, authoring, validation, and normalization; convert
|
||||
existing files and reindex; and verify that visible edits reach core consumption.
|
||||
Preserve the internal typed model where possible. This precedes the administrative
|
||||
page and is not merely a presentation change. Human inspection uses normal Git
|
||||
status and optional line-level diff commands; no custom diff viewer or mandatory
|
||||
double review is required.
|
||||
The suggestion of making PostgreSQL the Evidence authority was withdrawn after this
|
||||
clarification; it was never implemented or accepted as a replacement for Q11.
|
||||
Q13 keeps manual corrections active when updated sources contradict them, until an
|
||||
administrator resolves the comparison; deleted Evidence must not be regenerated
|
||||
automatically. Q14 allows direct manual creation and records a manual declaration
|
||||
as the current source, preserving any original document as distinct provenance.
|
||||
Q15 refreshes external sources only on explicit administrator request; normal saves
|
||||
and lookups do not reacquire them. These decisions, now implemented through E1–E3, are recorded in
|
||||
`docs/adr/0019-author-evidence-in-app-with-automatic-activation.md`.
|
||||
The decision-by-decision review is recorded in
|
||||
`docs/plans/2026-09-08-memory-evidence-simplification-review.md`; it distinguishes the
|
||||
new constraints from the revised technical recommendations. It also specifies a
|
||||
sequential save with minimal durable retry state and direct Memory cleanup after
|
||||
successful schema synchronization, without new queues or event infrastructure.
|
||||
The delivery order remains Memory, Evidence, and persistent conflict repair between
|
||||
both modules. Local curated Evidence must survive preprocessing Clear and be backed
|
||||
up as primary data; the Qdrant projection remains rebuildable.
|
||||
No runtime gate change or administrative page is implemented yet.
|
||||
|
||||
## Evidence restructuring — accepted
|
||||
|
||||
The evidence restructuring and PSD migration completed real acceptance on 2026-08-25.
|
||||
|
||||
- The curated PSD revision contains 35 approved Evidence units and 60 review items.
|
||||
- The PSD authoring repository publishes all 35 units using Curated unit schema v3. Its table-free
|
||||
presentation uses hidden canonical metadata, wrapping Markdown scope lists, list-based enum
|
||||
values, and collapsed technical provenance. Long domain rules now have a deterministic
|
||||
human-readable presentation while retaining their exact canonical text for vector ingestion.
|
||||
`tht evidence migrate <workspace-root>` performs the deterministic v1/v2 upgrade and older-v3
|
||||
presentation rewrite without model calls. The structured-rule PSD rewrite is currently local and
|
||||
pending commit/publication.
|
||||
- The accepted snapshot is
|
||||
`psd-clinical-675990d90eae51da6f2bd51b1ae2609f245772ef-snapshot`.
|
||||
- The active generation is `gen:f968b3bd7a553dbfef3cf47093698f2bc7f95f11`.
|
||||
- Retrieval acceptance reached 20/20 Hit@10.
|
||||
- A real session, `20301df7-cad7-403d-a4c1-9f35c9d07b66`, completed F1–F8 with five
|
||||
receipts, three CTEs, and a final result of 78 patients.
|
||||
- The durable acceptance record is
|
||||
`docs/testing/evidence/evidence-restructuring-psd-acceptance-2026-08-25.md`.
|
||||
|
||||
The canonical authoring, validation, publication, materialization, and preprocessing flow is
|
||||
documented in `docs/evidence.md`. The governing contracts are
|
||||
`docs/contracts/workspace-evidence-v3.md` and
|
||||
`docs/contracts/workspace-preprocessing-cli.md`.
|
||||
The incremental server procedure for the `260906-preprocessing-complete` release is
|
||||
`docs/operations/server-handoff-260906-preprocessing-complete.md`.
|
||||
|
||||
## Workspace preprocessing and configuration
|
||||
|
||||
The native host CLI `tht` is the operator surface. Workspace preprocessing runs through:
|
||||
|
||||
```sh
|
||||
tht --installation /absolute/path/thothii-installation.yaml \
|
||||
workspace preprocess run --workspace <workspace-id>
|
||||
```
|
||||
|
||||
This complete one-shot command uses the profile-gated `workspace-maintenance` service. Partial DWH,
|
||||
schema, Evidence, and vector mutation commands are retired.
|
||||
|
||||
The right Administration sidebar invokes that same operation for the selected workspace. It shows
|
||||
only current readiness or the latest bounded failure diagnostic; there is no preprocessing history.
|
||||
Known non-ready state disables **Session** when it would start a new question,
|
||||
while backend admission remains authoritative.
|
||||
The same control exposes an inline-confirmed **Clear** action to remove replaceable reference
|
||||
vectors, LSH, corpus, and checkpoints while preserving the separate Memory collection. The host CLI
|
||||
equivalent is `workspace preprocess clear`.
|
||||
|
||||
Each workspace now uses `<workspace>-reference` for Schema, relationships, and Evidence and
|
||||
`<workspace>-memory` for `memory` and `solved_question`. Clear and preprocessing own only the former.
|
||||
LSH ownership additionally binds the Catalog database ID and Metadata Content Revision, so derived
|
||||
values cannot be reused across database identities or Catalog revisions.
|
||||
|
||||
Workspace descriptors use schema v4 and contain only workspace identity and optional Evidence.
|
||||
PostgreSQL Metadata Catalog owns database identity, binding, schema, descriptions, sensitivity, and
|
||||
relationships; model, provider, embedding, and vector-store configuration is installation-owned. For
|
||||
PSD, workspace content and runtime roots point to the
|
||||
separate uncommitted repository `/Users/mp/projects/tht-workspace-psd`. Secrets remain outside
|
||||
Git and are supplied only through installation-local protected files.
|
||||
|
||||
## Installation Model Catalog
|
||||
|
||||
`thothii-installation.yaml` schema version 2 is the only operator-authored source for session,
|
||||
metadata-generation, and embedding models. The host `tht` lifecycle validates `modelCatalog` and
|
||||
regenerates the backend catalog, Pi `models.json`/`settings.json`, and Compose override under the
|
||||
installation-local `generated/` directory. Those projections are replaceable runtime adapters:
|
||||
they are not edited, backed up, or treated as configuration.
|
||||
|
||||
Core and Administration now share one canonical `modelCatalog.defaults.interaction` per installation,
|
||||
independent of workspace. Runtime catalog schema v2 contains only `defaultInteraction`; apply the host,
|
||||
backend, and regenerated projections together. Equal legacy defaults normalize on read; conflicting
|
||||
ones require an explicit operator choice. With Admin AI configured, selectable models are the
|
||||
intersection of the Pi and LiteLLM adapters; Core-only installations remain supported without Admin AI.
|
||||
The existing Core and Database controls share the operational selection. Explicit model choices are
|
||||
remembered per authenticated user/application mount in this browser, not in installation settings.
|
||||
Resume uses that selection/default while preserving the historical workspace/revision and manifest.
|
||||
Every model must be manually exercised in both Core and Admin as documented in
|
||||
`docs/general/pi-configuration.md`; validation is not a live model certification.
|
||||
These changes and shelf A are now deployed to local Docker; remote deployment remains pending.
|
||||
|
||||
PSD DeepSeek Pro/Flash now share canonical `deepseek/...` identities across native Pi and LiteLLM,
|
||||
using the existing `DEEPSEEK_API_KEY` bundle entry. Its value was confirmed identical to the working
|
||||
Pi key without exposing it; no secret files were changed. The duplicate `deepseek-metadata` descriptor
|
||||
is removed locally and the tracked example uses the shared provider. `secret_env` overrides legacy
|
||||
Pi auth only inside temporary runtime snapshots and fails closed if the bundle key is missing.
|
||||
The original auth store/history and `zai/glm-5.3` default are preserved. Local Docker projections
|
||||
and core/frontend were updated together on 2026-09-12. Regenerate projections with
|
||||
the matching release for the separate server deployment.
|
||||
|
||||
Provider authentication declares
|
||||
one explicit mode (`secret_env`, `pi_auth`, or `none`); `secret_env` names a protected bundle key.
|
||||
The backend settings store now owns only the selected workspace and thinking level. Existing v1
|
||||
installations use the explicit catalog migration command; schema-v3 workspace descriptors are
|
||||
converted deterministically in their curator-owned repository before commit. Strict runtime loading
|
||||
does not silently infer or merge legacy sources. ADR 0013 and
|
||||
`docs/plans/2026-09-02-installation-model-catalog.md` record the decision and implementation.
|
||||
|
||||
## Database management
|
||||
|
||||
The database, table, and authoritative physical-schema catalog slices are implemented. Database
|
||||
Management now opens the Fleet Ledger presentation by default inside `AppShell`, lists every YAML
|
||||
workspace, creates at most one PostgreSQL database configuration per workspace, edits direct
|
||||
PostgreSQL, REST API, or SSH-tunnel installation bindings, replaces write-only encrypted secrets,
|
||||
and tests supported connector bindings. The surface keeps one responsive AG Grid visible at a time:
|
||||
databases lead to tables, tables lead to columns, and relationships are a sibling database view.
|
||||
Parent navigation remains explicit through the breadcrumb and emphasized back control.
|
||||
|
||||
Selection-scoped operations use one action selector plus an explicit **Run** control; ineligible
|
||||
actions remain visible with their disabled reason, while row-scoped actions stay in the pinned final
|
||||
column. The KPI strip reads installation-wide or selected-database aggregates from
|
||||
`GET /catalog/metrics`. Database configuration, metadata editors, synchronization history,
|
||||
description history, and sensitive-field review/history use the production APIs in right-side
|
||||
drawers rather than prototype fixtures; closing a history drawer does not stop its background run.
|
||||
|
||||
Sensitive-field review is now driven by the versioned local `sensitivity-v4` policy, not by a
|
||||
catalog model. The backend reads selected source tables through read-only, database-specific
|
||||
adapters and makes every `sensitive | non_sensitive` draft decision in the TypeScript
|
||||
`SensitivityClassifier`. A single validated match protects the column. Tables up to 1,000 rows are
|
||||
fully scanned; larger tables use breadth-first 300, 1,000, and text-only 3,000-value targets, with a
|
||||
five-second limit per source query and no global request deadline. Source failures fail the run
|
||||
instead of yielding `unknown`; coverage remains visible separately from the proposal. Draft
|
||||
assessments remain transient until an administrator explicitly saves them. Optional GLiNER2
|
||||
evidence is CPU-only, offline, opt-in, and never replaces the deterministic decision point; see
|
||||
`docs/operations/sensitivity-analysis.md`. The earlier v1 PSD shadow comparison kept NER disabled by
|
||||
default; see `docs/reports/2026-09-02-psd-sensitivity-shadow.md`. The v2 comparison completed all
|
||||
2,275 columns: CPU NER added 18 sensitive proposals and increased warm runtime from 50.1 to 61.3
|
||||
seconds; see `docs/reports/2026-09-03-psd-progressive-sensitivity-shadow.md`.
|
||||
Version 4 excludes declared `bigint` primary-key columns and conventionally named `pk bigint`
|
||||
columns before source inspection, reporting both as non-informative structural identifiers while
|
||||
distinguishing declared constraints from inferred roles.
|
||||
|
||||
Physical membership, source
|
||||
comments, column types/default/nullability/PK positions, and constraint-level ordered FK pairs are
|
||||
projections of the external schema. They cannot be created, renamed, or structurally edited by
|
||||
hand, but administrators can explicitly clear catalog tables, columns, or relationships without
|
||||
touching the source database, binding, configuration, or secrets. Table deletion cascades through
|
||||
columns and relationships; table-scoped relationship cleanup includes incoming and outgoing
|
||||
relationships. Curated and generated descriptions are editable; generated descriptions start null
|
||||
and Database Management can generate or consolidate them for selected tables, selected columns,
|
||||
all targets, or only targets whose Generated Description is missing.
|
||||
|
||||
Relationship Management is now reachable directly from each configured Fleet database. One
|
||||
Relationship Map shows read-only Physical Relationships together with Generated and Manual Logical
|
||||
Relationships, with Active, Excluded, and All filters. Administrators can add a single-column
|
||||
relationship, run deterministic name/PK/type inference, exclude or restore a logical relationship,
|
||||
or delete it permanently. Exclusion retains a tombstone that a rebuild cannot reactivate; permanent
|
||||
deletion allows a later rebuild to infer the same endpoints again. Inference uses no LLM, embedding,
|
||||
or source values. It supports normalized table-qualified names, unique non-generic PK names,
|
||||
composite-PK source columns, and the `*time_key -> dim_time.<single PK>` warehouse convention while
|
||||
ignoring bare generic names. Explicit table/column metadata cleanup remains a destructive boundary: it removes
|
||||
the attached logical relationships and exclusions and requires a full schema synchronization before
|
||||
inference or runtime publication can continue.
|
||||
|
||||
The previous Database Management renderer remains a temporary comparison fallback for development
|
||||
and staging only: `?db-ui=legacy` is honored in Vite development or when
|
||||
`VITE_DB_MANAGEMENT_LEGACY=true`; it is not a production presentation. The standalone Fleet Ledger
|
||||
prototype on port `5173` also remains temporary until owner acceptance of the integrated surface,
|
||||
after which both migration aids can be removed.
|
||||
|
||||
Schema refresh is one durable asynchronous engine with database-table, selected-table-column,
|
||||
relationship, and full-database actions. Database-level menus expose only the table, relationship,
|
||||
and full scopes; selecting tables exposes column synchronization plus manual column and relationship cleanup for that subset. Database selections
|
||||
also expose manual table and relationship cleanup. Cleanup selections are atomic and share the
|
||||
one-active-operation-per-database exclusion with synchronization. Runs have leases and
|
||||
restart recovery, atomic apply, destructive-diff confirmation with re-scan, cancellation before
|
||||
apply, retained history, and a live SSE log with polling fallback. Null metadata renders blank
|
||||
rather than as a placeholder.
|
||||
|
||||
Direct PostgreSQL and strict known-host-verified OpenSSH use `pg_catalog`. REST bindings use the
|
||||
typed full-snapshot `POST /rpc/schema_snapshot` contract when available. Servers such as the
|
||||
current PSD endpoint that exposes only `POST /rpc/run_query` use one catalog-owned read-only query
|
||||
to return the exact same strict v1 snapshot in a single round trip. Both paths remain fail-closed:
|
||||
an absent capability, query error, partial result, or invalid snapshot applies no catalog changes.
|
||||
SSH is not yet enabled for NL→SQL session runtime.
|
||||
|
||||
The catalog runs in the internal `catalog-db` PostgreSQL service. Kysely migrations are an explicit
|
||||
one-shot `catalog-migrate` operation; `scripts/run-stack.sh` runs it before local startup. Runtime
|
||||
sessions consume an immutable Catalog JSON snapshot tied to the runtime-config lease. It contains
|
||||
the tables, columns, effective descriptions, sensitivity flags, and active relationships used by
|
||||
the harness; PostgreSQL is the exclusive runtime authority for database metadata. Authored
|
||||
workspace YAML remains limited to workspace identity and optional Evidence configuration. The
|
||||
accepted design is recorded in ADR 0016 and the contracts under `docs/contracts/`.
|
||||
|
||||
Semantic aliases, value descriptions, synonyms, and concepts remain deferred to their dedicated
|
||||
slices.
|
||||
|
||||
AI Description Generation uses the catalog's human-owned Sensitive Data Flag. The flag defaults to
|
||||
`false`, including for newly synchronized columns. An administrator may request a local sensitivity
|
||||
analysis for one selected database, selected tables, or selected columns. One deterministic
|
||||
TypeScript classifier combines metadata, bounded source-content rules, and optional CPU-only NER;
|
||||
no generative model decides the result. Its `sensitive` or `non_sensitive` assessments remain an
|
||||
unsaved draft until the human reviews and saves any chosen flag changes, including a downgrade to
|
||||
non-sensitive. Coverage is reported separately; interrupted history may count unprocessed columns.
|
||||
Each started analysis records a separate Sensitivity Analysis Run with aggregate counters and safe
|
||||
ordered events. The progress drawer opens before the synchronous request completes, polls the run,
|
||||
and displays sanitized source-scan and local-NER phase/batch activity while classification is in
|
||||
progress. This operational history never stores per-column assessments, source values,
|
||||
matched spans, prompts, or free-form diagnostics. Saving a sensitive decision persists a sanitized
|
||||
Sensitivity Reason as column Catalog Metadata alongside the human-owned flag; clearing the flag
|
||||
clears that reason. Reloading still discards an unsaved review draft.
|
||||
For unprotected columns, up to five source rows and five representative non-null values may be sent
|
||||
transiently to the configured model provider. Protected columns are omitted from source reads and
|
||||
replaced in the prompt by deterministic plausible values derived only from their metadata. Existing
|
||||
descriptions are not regenerated when a flag changes.
|
||||
|
||||
The accepted AI-description design is recorded in
|
||||
`docs/plans/2026-08-28-ai-catalog-description-generation.md`, with the formal specification in the
|
||||
adjacent `-spec.md` document and Gitea issue #4. Gitea issues #5–#11 deliver the implementation.
|
||||
The runtime deliberately keeps ThothAI's simple operating model: one installation-wide sequential
|
||||
run owned by the backend, one short-lived Python/LiteLLM completion helper per request, and
|
||||
persistence limited to the run, its safe ordered text events, and each Generated Description as
|
||||
soon as it succeeds. The helper performs at most one provider retry and never falls back to another
|
||||
model. Stop terminates the current helper and retains prior results; three consecutive exhausted
|
||||
technical batches fail the run. Startup marks stale queued/running work interrupted, and Unlock is
|
||||
available only when no local start, worker, or helper is live. Runs remain inspectable through a
|
||||
live SSE log with ordered polling fallback; there is no automatic resume or user-facing generation
|
||||
CLI. ADRs 0009–0010 record the runtime and source-sampling decisions.
|
||||
|
||||
The Installation Model Catalog accepts the protected `DEEPSEEK_API_KEY` and `ZAI_API_KEY`
|
||||
references for metadata-generation providers.
|
||||
It also accepts a model with no secret reference only when its OpenAI-compatible endpoint is
|
||||
explicit; this covers the VPN-only AritmoLab Qwen 3.6 server without creating a fake operator
|
||||
credential. The Python client supplies only its fixed non-secret compatibility placeholder.
|
||||
The AritmoLab entry also sets `disableThinking: true`, mapped to the endpoint's chat-template flag,
|
||||
because its default reasoning prose would violate the worker's exact JSON response contract.
|
||||
|
||||
Logical relationship integration with core schema-linking is complete: session creation and resume
|
||||
materialize the active physical/generated/manual map, retrieval-pack generation and Pi receive the
|
||||
same runtime config, and snapshot validation fails closed on a declared missing, invalid, or orphaned
|
||||
endpoint. Broader publication of other Catalog metadata to schema-linking remains a separate future
|
||||
slice.
|
||||
|
||||
**Deferred follow-up — Sensitive Data Policy in schema-linking.** The policy is first delivered
|
||||
and tested in catalog description generation. Its enforcement for core schema-linking remains
|
||||
out of scope until the current tickets are closed and the owner has completed the acceptance test.
|
||||
At that gate, resume the design: `tht` must receive a read-only projection of the current Sensitive
|
||||
Data Flags and exclude values from columns marked sensitive from every LSH result before it is
|
||||
given to Pi. Do not start this integration before the owner gives final approval after that test.
|
||||
|
||||
## Active deployment work and manual gates
|
||||
|
||||
### PSD server deployment program
|
||||
|
||||
The approved design and executable entry point are:
|
||||
|
||||
- `docs/plans/2026-08-20-psd-server-deployment-program-design.md`
|
||||
- `docs/plans/2026-08-20-psd-server-deployment-program.md`
|
||||
- `docs/plans/2026-08-20-psd-server-survey.md`
|
||||
- `docs/plans/2026-08-20-psd-server-project-a-standalone.md`
|
||||
- `docs/plans/2026-08-20-psd-server-project-b-authentik.md`
|
||||
|
||||
Last recorded state:
|
||||
|
||||
- survey: `SURVEY_NO_GO`;
|
||||
- Project A: `BLOCKED_BY_SURVEY_AND_MUTATION_GATE`;
|
||||
- Project B: `BLOCKED_BY_PROJECT_A_AND_PRE_B_GATE`.
|
||||
|
||||
The deployment is a clean replacement: legacy sessions, indexes, and application configuration
|
||||
are not migration inputs. The existing stack remains intact until its documented mutation and
|
||||
rollback gates are explicitly approved. Shared Omics/LocalLLM networks, ETL Evidence, DWH,
|
||||
`dwh-auth`, Supabase, Authentik, Superset, and Aritmolab are outside cleanup scope.
|
||||
|
||||
Human acceptance guides and sanitized report templates live under `docs/testing/` and
|
||||
`docs/testing/evidence/`. The remediation checklist is
|
||||
`docs/operations/psd-server-survey-remediation-checklist.md`.
|
||||
|
||||
### Authentication
|
||||
|
||||
The local/OIDC authentication remediation passed its automated review on 2026-08-18. Release and
|
||||
PSD mutation gates remain governed by:
|
||||
|
||||
- `docs/architecture/authentication.md`;
|
||||
- `docs/plans/2026-08-18-thothii-authentication-acceptance-and-psd-deployment.md`;
|
||||
- `docs/operations/psd-dwh-auth-rollout.md`;
|
||||
- `docs/testing/authentication-manual-acceptance.md`.
|
||||
|
||||
Do not infer authorization for server, Nginx, Authentik, database, credential, or cutover changes
|
||||
from an automated PASS.
|
||||
|
||||
## Verification status
|
||||
|
||||
- The P1.1 workspace-directory registry and P2–P6 preprocessing workstreams are implemented and
|
||||
have automated coverage.
|
||||
- Evidence restructuring has a real PSD acceptance PASS as recorded above.
|
||||
- AI Description Generation has automated coverage across installation setup, model selection,
|
||||
generation/consolidation scopes, bounded sampling, cancellation/recovery, history, SSE/polling,
|
||||
and the LiteLLM helper boundary.
|
||||
- L2 tests requiring real providers or remote databases remain opt-in.
|
||||
- Server deployment, release, and owner-operated acceptance steps remain pending wherever the
|
||||
referenced runbooks require explicit approval.
|
||||
|
||||
Run the layer-specific checks documented in `AGENTS.md`. For release-sensitive changes, also run
|
||||
the repository contract scripts in `scripts/` and build the MkDocs site.
|
||||
|
||||
## Operational invariants
|
||||
|
||||
- `tht`'s `-c`/`--config` option follows the subcommand; it is not a global option.
|
||||
- `--json` commands write pristine JSON to stdout.
|
||||
- Persisted phase documents and the decision ledger are the source of session truth; chat is not.
|
||||
- UI chrome is English; workspace document content retains the workspace language.
|
||||
- The backend refuses resume for finalized or archived sessions.
|
||||
- A resume must send `/riprendi-sessione <id>`; a new session must send `/nuova-domanda`.
|
||||
- DWH access is read-only.
|
||||
# Project state
|
||||
|
||||
Updated: 2026-09-15. This is a current snapshot, not a release diary. Stable commands
|
||||
and invariants are in [AGENTS.md](AGENTS.md); prior snapshots remain in Git.
|
||||
|
||||
## Current contracts
|
||||
|
||||
- React supports full/embedded rendering independently of local/OIDC/upstream auth,
|
||||
with EN/IT UI and immutable session interaction language. See
|
||||
[application shell](docs/architecture/application-shell.md) and
|
||||
[localization](docs/operations/shell-and-localization.md).
|
||||
- PostgreSQL Metadata Catalog owns database identity, binding, schema, descriptions,
|
||||
sensitivity and relationships for all core consumers. Workspace schema v4 contains
|
||||
identity and optional Evidence only. Installation schema v2 is the authored model
|
||||
catalog source. See [overview](docs/architecture/overview.md) and
|
||||
[model configuration](docs/general/pi-configuration.md).
|
||||
- The harness owns workflow persistence; chat is not the durable session record.
|
||||
Memory uses PostgreSQL authority and derived Qdrant dense/BM25 search. Editable
|
||||
Evidence has local archive authority and manual consolidation. File save, search
|
||||
activation and Git publication have distinct outcomes. See
|
||||
[Memory](docs/gestione-memory.md), [Evidence](docs/contracts/curated-evidence-v4.md)
|
||||
and [consolidated release evidence](docs/reports/knowledge-archives-release.md).
|
||||
- Reference preprocessing must not clear Memory. Use the installation-scoped
|
||||
`tht --installation /absolute/path/thothii-installation.yaml workspace preprocess run`
|
||||
and its [contract](docs/contracts/workspace-preprocessing-cli.md).
|
||||
- DWH sessions are read-only. SSH tunnels support database-management diagnostics
|
||||
and metadata synchronization, not NL→SQL session creation; use direct or REST
|
||||
transport for sessions.
|
||||
|
||||
## Installation and workspace boundaries
|
||||
|
||||
Fresh standalone installations follow the manual terminal procedures in
|
||||
[Italian](docs/install/standalone-manual-it.md) or
|
||||
[English](docs/install/standalone-manual-en.md), without an installer or launcher.
|
||||
The [Compose reference](docs/operations/compose-reference.md) is for maintainers,
|
||||
not another quick start. Catalog and Memory migrations are explicit.
|
||||
|
||||
Descriptors, authentication, provider credentials, certificates and runtime bindings
|
||||
stay in protected installation-local paths. Do not copy secrets into examples or
|
||||
workspace Git. Legacy runtime snapshots may use absolute paths and protected
|
||||
`harness/.env`; do not silently relocate them.
|
||||
|
||||
PSD authoring is separate at `/Users/mp/projects/tht-workspace-psd`. Its GitHub
|
||||
repository was copied to private Gitea
|
||||
[workspace_psd](https://git.tylconsulting.it/mptyl/workspace_psd), preserving both
|
||||
branches. It is a copy, not automatic synchronization. Running installations were
|
||||
not repointed to a different workspace remote.
|
||||
|
||||
## Recorded deployments and server authority
|
||||
|
||||
Use the ordered [server handoff](docs/operations/server-codex-handoff.md) for
|
||||
coordinated ThothII/Omics upgrades. Omics integration uses GitHub
|
||||
`Dallavilla-Tiziano/omics_portal`, with no Gitea relay prerequisite. Omics uses
|
||||
embedded/upstream identity, not another ThothII OIDC login. Read
|
||||
[upstream authentication](docs/install/authentication-upstream.md) before changes.
|
||||
|
||||
Last recorded application deliveries (not a fresh runtime attestation):
|
||||
|
||||
- [Session dialogs](docs/reports/2026-09-14-session-dialogs-release.md):
|
||||
`b1723c34-session-dialogs-20260914`, frontend-only.
|
||||
- [Session layout/Memory fix](docs/reports/2026-09-14-session-layout-memory-fix.md):
|
||||
`49333a2d-session-memory-fix`, core/frontend.
|
||||
|
||||
Keep those reports and rollback instructions while operator gates remain open.
|
||||
A later deployment does not prove every earlier acceptance item passed.
|
||||
|
||||
## Remaining acceptance and design gates
|
||||
|
||||
- Fresh-machine Mac, Windows/WSL2 and Linux installation acceptance, including real
|
||||
DWH/model endpoints, remains a separate operator exercise.
|
||||
- Real IdP/portal login, logout, embedded interaction and PSD semantic acceptance
|
||||
follow the [manual matrix](docs/testing/authentication-manual-acceptance.md) and
|
||||
delivery reports; synthetic tests do not close them.
|
||||
- [Security hardening](docs/plans/2026-09-08-security-hardening-prd.md) is a draft.
|
||||
Revalidate SEC01–12 and obtain design approval before implementation or real
|
||||
server/IdP/DWH mutation.
|
||||
- Optional NER remains opt-in; labeled Italian quality, benchmark and licensing
|
||||
acceptance are not implied by document cleanup.
|
||||
- Semantic aliases, value descriptions, synonyms/concepts, dialect and multi-schema
|
||||
extensions remain explicit design work. Current sensitivity delivery follows the
|
||||
Catalog contract; additional policies require their own acceptance.
|
||||
- Legacy database UI fallback (`?db-ui=legacy`, dev/staging) and prototype removal
|
||||
remain subject to owner acceptance.
|
||||
|
||||
## Documentation maintenance
|
||||
|
||||
MkDocs publishes only 20 product/operator pages and five approved assets.
|
||||
Architecture, contracts, ADRs, plans, research, tests and release evidence are
|
||||
excluded from HTML and search. The repository itself is public: editorial exclusion
|
||||
is not confidentiality.
|
||||
|
||||
The [cleanup record](docs/maintenance/2026-09-15-documentation-cleanup.md) records
|
||||
retired sources and retained gates. Main contains source; Actions generates the
|
||||
`pages` branch. The live site requires the separate explicit deployment described
|
||||
in [public manual publication](docs/operations/public-docs-publication.md).
|
||||
|
||||
@@ -25,69 +25,31 @@ For the clone-based manual standalone installation test on macOS, Windows, and L
|
||||
[Italian procedure](docs/install/standalone-manual-it.md) or the
|
||||
[English procedure](docs/install/standalone-manual-en.md).
|
||||
|
||||
## Docker Compose: local startup
|
||||
The [public manual](https://git.tylconsulting.it/thothii-docs/) covers the product,
|
||||
installation, use and administration. Developer architecture, contracts, ADRs, tests,
|
||||
plans and release records remain in this repository but are excluded from MkDocs
|
||||
pages and search. This is an editorial boundary, not an access restriction on the
|
||||
public repository. See the [documentation cleanup review](docs/maintenance/2026-09-15-documentation-cleanup.md)
|
||||
for the executed consolidation and the inventory of historical sources retained in Git.
|
||||
|
||||
Requirements: Docker Engine with Compose v2. The mandatory stack is `frontend`, `core`,
|
||||
`catalog-db`, `qdrant`, `embedding`, and the one-shot `embedding-model-init`. DWH and LLM remain external,
|
||||
configurable endpoints—even when they are co-located with ThothII.
|
||||
## Docker Compose and installation
|
||||
|
||||
From a fresh clone, run these commands from the repository root:
|
||||
For a fresh installation, follow the guided terminal procedure in
|
||||
[Italian](docs/install/standalone-manual-it.md) or
|
||||
[English](docs/install/standalone-manual-en.md). The single
|
||||
`tht setup --complete` command validates protected files, builds the images, runs
|
||||
Catalog migration, starts the stack and imports the configured workspace repository.
|
||||
There is no graphical installer or native launcher.
|
||||
|
||||
```sh
|
||||
cp deploy/env/local.env.example deploy/env/local.env
|
||||
# Copy docs/install/examples/thothii-installation.local.yaml to a protected operator path,
|
||||
# replace its placeholders, chmod it 600, and set that exact THT_INSTALLATION_CONFIG_SOURCE.
|
||||
# Edit deploy/env/local.env, including PI_AUTH_FILE, THT_SECRETS_FILE, and external endpoints.
|
||||
./scripts/run-stack.sh
|
||||
```
|
||||
The mandatory stack includes frontend, core, PostgreSQL catalog, Qdrant, Ollama
|
||||
and the embedding initializer. DWH and LLM endpoints remain external dependencies.
|
||||
Pi is included in the core image. Credentials and certificates belong in protected
|
||||
installation-local files, never in the workspace repository.
|
||||
|
||||
The low-level stack script builds the core, starts `catalog-db`, runs the explicit one-shot Kysely migrations,
|
||||
then runs the base+local stack in the foreground. Migrations never run implicitly in backend
|
||||
startup. The core image contains its Pi runtime; no host `pi` executable is used. For a server
|
||||
installation, build the image, start the catalog, and run the same migration service before the
|
||||
application rollout:
|
||||
|
||||
```sh
|
||||
cp deploy/env/server.env.example deploy/env/server.env
|
||||
# Prepare a mode-600 thothii-installation.yaml from the server example and set its exact
|
||||
# path as THT_INSTALLATION_CONFIG_SOURCE. Edit all remaining storage/secret/endpoint paths.
|
||||
sudo scripts/prepare-server-pi-state.sh /srv/thothii/pi-state 10001 10001
|
||||
docker compose --env-file deploy/env/server.env \
|
||||
-f compose.yaml -f deploy/compose.server.yaml \
|
||||
-f deploy/compose.session-server.yaml.example build core
|
||||
docker compose --env-file deploy/env/server.env \
|
||||
-f compose.yaml -f deploy/compose.server.yaml \
|
||||
-f deploy/compose.session-server.yaml.example up -d catalog-db
|
||||
docker compose --env-file deploy/env/server.env \
|
||||
-f compose.yaml -f deploy/compose.server.yaml \
|
||||
-f deploy/compose.session-server.yaml.example run --rm catalog-migrate
|
||||
docker compose --env-file deploy/env/server.env \
|
||||
-f compose.yaml -f deploy/compose.server.yaml \
|
||||
-f deploy/compose.session-server.yaml.example up --build -d
|
||||
```
|
||||
|
||||
The initializer is required for an empty or restored server Pi-state bind. It atomically creates
|
||||
the three regular targets hidden below the writable parent bind; protected Pi auth and tracked
|
||||
model/settings sources remain separate read-only mounts. See the server manual before substituting
|
||||
a root other than `/srv/thothii/pi-state`.
|
||||
|
||||
Workspace descriptors come from the Git remote configured by `THT_WORKSPACE_GIT_REMOTE`; their
|
||||
runtime endpoint and secret bindings remain installation-local. Open
|
||||
<http://127.0.0.1:8080> (set `THOTH_HTTP_PORT` in `deploy/env/local.env` to choose another
|
||||
loopback port).
|
||||
|
||||
Credentials and certificates are local protected files. Do not put them in environment examples,
|
||||
workspace YAML, URLs, or Compose interpolation values.
|
||||
|
||||
Application state is split across the named `settings`, `pi-state`, `workspace-registry`,
|
||||
`sessions`, `qdrant-data`, and `embedding-models` volumes. `docker compose down` keeps them.
|
||||
`qdrant-data` is a derived but persistent index store; `embedding-models` is an Ollama model
|
||||
cache for `qwen3-embedding:0.6b` with fixed `1024`-dimension embeddings. Only an explicit destructive command such as `docker compose
|
||||
down --volumes` removes them.
|
||||
|
||||
The frontend depends on the core health check and proxies `/health` and `/api/*` to it. The
|
||||
application health endpoint intentionally checks process readiness only; external dependency
|
||||
diagnostics are exposed by `tht doctor` and do not prevent the UI from starting.
|
||||
For developer topology, overlays and lifecycle details, see the internal
|
||||
[Compose reference](docs/operations/compose-reference.md). Ordinary stop/down keeps
|
||||
persistent data; removing volumes is destructive and is not an upgrade step.
|
||||
Process health is distinct from external dependency checks performed by doctor.
|
||||
|
||||
## Git-backed workspace repository
|
||||
|
||||
|
||||
@@ -41,8 +41,11 @@ const runtimeModelSchema = z.object({
|
||||
supportsReasoningEffort: z.boolean(),
|
||||
supportsStore: z.boolean(),
|
||||
maxTokensField: z.string().optional(),
|
||||
thinkingFormat: z.enum(["qwen", "qwen-chat-template"]).optional(),
|
||||
}).strict().optional(),
|
||||
}).strict().optional(),
|
||||
}).strict().refine((session) => !session.compatibility?.thinkingFormat || session.reasoning, {
|
||||
message: "thinkingFormat requires reasoning: true",
|
||||
}).optional(),
|
||||
metadataGeneration: z.object({ disableThinking: z.boolean() }).strict().optional(),
|
||||
}).strict();
|
||||
|
||||
|
||||
@@ -16,12 +16,16 @@ import { loadSettings } from "./settings/settings-store.js";
|
||||
import { ThtRunner, type SessionRow } from "./tht/tht-runner.js";
|
||||
import { WorkspaceRegistry } from "./workspaces/registry.js";
|
||||
import { WorkspaceSecretStore } from "./workspaces/secret-store.js";
|
||||
import { createProductionWorkspaceDiagnoser } from "./workspaces/diagnostics.js";
|
||||
import { resolveCatalogRuntimeBinding } from "./catalog/runtime-binding.js";
|
||||
import { CatalogService } from "./catalog/service.js";
|
||||
import { validateOperationalWorkspace } from "./workspaces/schema.js";
|
||||
import { createCatalogRepository } from "./catalog/repository.js";
|
||||
import type { CatalogRepository } from "./catalog/types.js";
|
||||
|
||||
type OperatorAction = "maintenance-activate" | "maintenance-deactivate" | "maintenance-status"
|
||||
| "session-inventory" | "workflow-doctor" | "workspace-integrity"
|
||||
| "pi-test" | "effective-settings";
|
||||
| "workspace-pull" | "workspace-test" | "pi-test" | "effective-settings";
|
||||
|
||||
const lifecyclePrincipal: PrincipalContext = {
|
||||
issuer: "tht-operator-command",
|
||||
@@ -119,6 +123,119 @@ async function workspaceIntegrity(config: AppConfig): Promise<{
|
||||
return { ready: true, ...integrity };
|
||||
}
|
||||
|
||||
async function workspacePull(config: AppConfig): Promise<{
|
||||
ready: boolean;
|
||||
status: "succeeded" | "degraded";
|
||||
branch: string;
|
||||
head?: string;
|
||||
degraded: boolean;
|
||||
}> {
|
||||
const status = await new WorkspaceRegistry(config.workspaceRegistry).pull();
|
||||
return {
|
||||
ready: !status.degraded,
|
||||
status: status.degraded ? "degraded" : "succeeded",
|
||||
branch: status.branch,
|
||||
...(status.head ? { head: status.head } : {}),
|
||||
degraded: status.degraded,
|
||||
};
|
||||
}
|
||||
|
||||
interface WorkspaceTestReport {
|
||||
id: string;
|
||||
status: "ready" | "failed";
|
||||
database: "reachable" | "not_configured" | "failed";
|
||||
diagnostics: string[];
|
||||
}
|
||||
|
||||
async function workspaceTest(config: AppConfig): Promise<{
|
||||
ready: boolean;
|
||||
workspaces: WorkspaceTestReport[];
|
||||
}> {
|
||||
if (!config.catalogDatabase) throw new Error("Catalog database is not configured");
|
||||
const registry = new WorkspaceRegistry(config.workspaceRegistry);
|
||||
const revisions = await registry.list();
|
||||
const repository = createCatalogRepository(config.catalogDatabase);
|
||||
try {
|
||||
const secretStore = new WorkspaceSecretStore({
|
||||
root: config.workspaceSecretStoreRoot,
|
||||
runtimeRoot: config.workspaceSecretRuntimeRoot,
|
||||
installationId: config.workspaceRegistry.installationId,
|
||||
});
|
||||
const catalogService = new CatalogService(
|
||||
repository,
|
||||
registry,
|
||||
secretStore,
|
||||
config.workspaceRegistry.secretRoots,
|
||||
config.workspaceDiagnosticTimeoutMs,
|
||||
);
|
||||
const diagnose = createProductionWorkspaceDiagnoser(config.workspaceDiagnosticTimeoutMs, undefined, {
|
||||
internalQdrantUrl: config.internalQdrantUrl,
|
||||
internalEmbeddingUrl: config.internalEmbeddingUrl,
|
||||
internalEmbeddingId: config.internalEmbeddingId,
|
||||
internalEmbeddingModel: config.internalEmbeddingModel,
|
||||
internalEmbeddingDimensions: config.internalEmbeddingDimensions,
|
||||
});
|
||||
const databases = await repository.list();
|
||||
const reports: WorkspaceTestReport[] = [];
|
||||
for (const revision of revisions) {
|
||||
const diagnostics: string[] = [];
|
||||
let workspace: ReturnType<typeof validateOperationalWorkspace>;
|
||||
try {
|
||||
workspace = validateOperationalWorkspace((await registry.read(revision.id)).workspace);
|
||||
} catch {
|
||||
reports.push({ id: revision.id, status: "failed", database: "not_configured", diagnostics: ["workspace_invalid"] });
|
||||
continue;
|
||||
}
|
||||
const database = databases.find((candidate) => candidate.workspaceId === revision.id);
|
||||
if (!database) {
|
||||
reports.push({ id: revision.id, status: "failed", database: "not_configured", diagnostics: ["database_binding_missing"] });
|
||||
continue;
|
||||
}
|
||||
let tested;
|
||||
try {
|
||||
tested = await catalogService.test(database);
|
||||
} catch {
|
||||
reports.push({ id: revision.id, status: "failed", database: "failed", diagnostics: ["database_unreachable"] });
|
||||
continue;
|
||||
}
|
||||
if (!tested || tested.connectionStatus !== "reachable") {
|
||||
reports.push({ id: revision.id, status: "failed", database: "failed", diagnostics: ["database_unreachable"] });
|
||||
continue;
|
||||
}
|
||||
let lease: ReturnType<typeof resolveCatalogRuntimeBinding>;
|
||||
try {
|
||||
lease = resolveCatalogRuntimeBinding({
|
||||
workspace,
|
||||
database: tested,
|
||||
environment: process.env,
|
||||
secretRoots: config.workspaceRegistry.secretRoots,
|
||||
secretStore,
|
||||
});
|
||||
} catch {
|
||||
reports.push({ id: revision.id, status: "failed", database: "reachable", diagnostics: ["binding_missing"] });
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
// CatalogService.test() above is the authoritative database probe and records its
|
||||
// outcome. The remaining diagnoser pass checks Evidence and internal semantic services;
|
||||
// skipping its legacy DWH probe avoids requiring a second response-shape contract for a
|
||||
// REST health endpoint.
|
||||
const result = await diagnose(lease.workspace, lease.bindings, { writeProbe: false, skipDwh: true });
|
||||
diagnostics.push(...result.diagnostics.map((diagnostic) => diagnostic.code));
|
||||
const ready = result.activatable;
|
||||
reports.push({ id: revision.id, status: ready ? "ready" : "failed", database: "reachable", diagnostics });
|
||||
} catch {
|
||||
reports.push({ id: revision.id, status: "failed", database: "reachable", diagnostics: ["connector_unavailable"] });
|
||||
} finally {
|
||||
lease.release();
|
||||
}
|
||||
}
|
||||
return { ready: reports.length > 0 && reports.every((report) => report.status === "ready"), workspaces: reports };
|
||||
} finally {
|
||||
await repository.close?.();
|
||||
}
|
||||
}
|
||||
|
||||
export async function runOperatorAction(
|
||||
action: OperatorAction,
|
||||
config: AppConfig,
|
||||
@@ -132,6 +249,8 @@ export async function runOperatorAction(
|
||||
if (action === "session-inventory") return await sessionInventory(config);
|
||||
if (action === "workflow-doctor") return await workflowDiagnostics(config);
|
||||
if (action === "workspace-integrity") return await workspaceIntegrity(config);
|
||||
if (action === "workspace-pull") return await workspacePull(config);
|
||||
if (action === "workspace-test") return await workspaceTest(config);
|
||||
const modelCatalog = loadRuntimeModelCatalog(config.modelCatalogFile);
|
||||
if (action === "effective-settings") {
|
||||
return effectiveSettings(config, loadSettings(config), modelCatalog);
|
||||
@@ -146,6 +265,7 @@ async function main(): Promise<void> {
|
||||
if (!action || ![
|
||||
"maintenance-activate", "maintenance-deactivate", "maintenance-status", "session-inventory",
|
||||
"workflow-doctor", "workspace-integrity", "pi-test", "effective-settings",
|
||||
"workspace-pull", "workspace-test",
|
||||
].includes(action)) throw new Error("invalid operator action");
|
||||
const result = await runOperatorAction(action, loadConfig(process.env));
|
||||
process.stdout.write(`${JSON.stringify(result)}\n`);
|
||||
|
||||
@@ -509,12 +509,15 @@ export function sessionRoutes(
|
||||
// registry snapshot. The legacy fallback stays available for sessions created before
|
||||
// the browser-local preference migration.
|
||||
let id: string;
|
||||
let sessionLanguage = language;
|
||||
try {
|
||||
({ id } = await runner.sessionNew({
|
||||
const created = await runner.sessionNew({
|
||||
question: b.question, name: b.name, workspaceConfigPath,
|
||||
workspaceId, workspaceRevision, provider, model, thinking,
|
||||
interactionLanguage: language,
|
||||
}));
|
||||
});
|
||||
id = created.id;
|
||||
sessionLanguage = created.interaction_language ?? language;
|
||||
manifestPersisted = true;
|
||||
if (revisionLease) {
|
||||
await revisionLease.markPersisted().catch((error: unknown) => {
|
||||
@@ -527,7 +530,7 @@ export function sessionRoutes(
|
||||
} catch { return storageFailure(reply); }
|
||||
const options = {
|
||||
provider, model, thinking,
|
||||
interactionLanguage: language,
|
||||
interactionLanguage: sessionLanguage,
|
||||
author: principal.displayName ?? principal.subject,
|
||||
principal,
|
||||
question: b.question,
|
||||
|
||||
@@ -507,7 +507,7 @@ export class ThtRunner {
|
||||
if (v) a.push(f, v);
|
||||
}
|
||||
a.push("--json");
|
||||
return this.json<{ id: string }>(a, o.workspaceConfigPath ?? o.workspace);
|
||||
return this.json<{ id: string; interaction_language?: string }>(a, o.workspaceConfigPath ?? o.workspace);
|
||||
}
|
||||
|
||||
/** Build and persist the deterministic F1 retrieval pack for a new session. */
|
||||
|
||||
@@ -95,6 +95,35 @@ test("returns empty catalogs when no runtime projection is configured", () => {
|
||||
expect(loadMetadataGenerationModels({}).catalog()).toEqual({ models: [], default: null });
|
||||
});
|
||||
|
||||
test.each([
|
||||
["qwen-chat-template", true, true],
|
||||
["qwen", true, true],
|
||||
["qwen-typo", true, false],
|
||||
["qwen-chat-template", false, false],
|
||||
])("validates Qwen thinking format %s with reasoning=%s", (thinkingFormat, reasoning, valid) => {
|
||||
const { catalogFile } = runtimeCatalog({
|
||||
defaultInteraction: "local/qwen",
|
||||
models: [{
|
||||
id: "local/qwen", provider: "local", model: "qwen", label: "Qwen",
|
||||
upstreamModel: "qwen", endpoint: { baseUrl: "http://localhost:8000/v1" },
|
||||
authentication: { mode: "none" }, sessionAdapter: { mode: "openai_compatible" },
|
||||
session: {
|
||||
reasoning, contextWindow: 32768, maxTokens: 8192,
|
||||
compatibility: {
|
||||
supportsDeveloperRole: false, supportsReasoningEffort: false,
|
||||
supportsStore: false, maxTokensField: "max_tokens", thinkingFormat,
|
||||
},
|
||||
},
|
||||
}],
|
||||
});
|
||||
if (valid) {
|
||||
expect(loadRuntimeModelCatalog(catalogFile).sessionModels()[0].session?.compatibility)
|
||||
.toMatchObject({ thinkingFormat });
|
||||
} else {
|
||||
expect(() => loadRuntimeModelCatalog(catalogFile)).toThrow("runtime model catalog is invalid");
|
||||
}
|
||||
});
|
||||
|
||||
test("rejects a drifted default and an unprotected projection", () => {
|
||||
const drifted = runtimeCatalog({ defaultInteraction: "zai/missing" });
|
||||
expect(() => loadRuntimeModelCatalog(drifted.catalogFile)).toThrow("interaction default is invalid");
|
||||
|
||||
@@ -36,6 +36,10 @@ vi.mock("../src/tht/tht-runner.js", () => ({
|
||||
|
||||
vi.mock("../src/workspaces/registry.js", () => ({
|
||||
WorkspaceRegistry: class {
|
||||
async pull() {
|
||||
return { branch: "main", head: "a".repeat(40), ahead: 0, behind: 0, degraded: false };
|
||||
}
|
||||
|
||||
async listRetainedSnapshots() {
|
||||
return [{ snapshotPath: "/data/workspace-registry/snapshots/revision/workspace.yaml" }];
|
||||
}
|
||||
@@ -98,3 +102,13 @@ test("workflow doctor gives schema-v4 runtime rendering a live Catalog repositor
|
||||
expect(fakes.releaseWorkspaceRuntime).toHaveBeenCalledOnce();
|
||||
expect(fakes.catalogRepository.close).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
test("workspace pull exposes only safe Git status", async () => {
|
||||
await expect(runOperatorAction("workspace-pull", config)).resolves.toEqual({
|
||||
ready: true,
|
||||
status: "succeeded",
|
||||
branch: "main",
|
||||
head: "a".repeat(40),
|
||||
degraded: false,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -140,6 +140,33 @@ test("resume rejects browser interaction language overrides", async () => {
|
||||
} finally { await app.close(); }
|
||||
});
|
||||
|
||||
test("new session starts Pi with the question language persisted by the harness", async () => {
|
||||
let runtime: any;
|
||||
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
|
||||
thtRunner: {
|
||||
sessionNew: async () => ({ id: "english-question", interaction_language: "en" }),
|
||||
searchPack: async () => {},
|
||||
},
|
||||
readiness: { ensure: async () => ({ ok: true }) },
|
||||
mgr: {
|
||||
get: () => undefined,
|
||||
createFor: (_id: string, options: any) => {
|
||||
runtime = options;
|
||||
return { bridge: { onClientEvent: () => {} } };
|
||||
},
|
||||
configure: async () => {}, start: () => {},
|
||||
},
|
||||
getSettings: () => ({ workspace: "default" }),
|
||||
});
|
||||
try {
|
||||
const response = await app.inject({ method: "POST", url: "/sessions", payload: {
|
||||
question: "How many patients were admitted last year?", interactionLanguage: "it",
|
||||
} });
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(runtime.interactionLanguage).toBe("en");
|
||||
} finally { await app.close(); }
|
||||
});
|
||||
|
||||
test("resume pins legacy interaction language using the resolved harness workspace", async () => {
|
||||
let pinnedWorkspace: string | undefined;
|
||||
let runtime: any;
|
||||
|
||||
@@ -8,6 +8,11 @@ cp deploy/secrets/thothii.secrets.example deploy/secrets/thothii.secrets
|
||||
chmod 600 deploy/secrets/thothii.secrets
|
||||
```
|
||||
|
||||
For a normal local installation, `tht setup --complete` creates the active bundle at
|
||||
`deploy/local/secrets/thothii.secrets` and creates the two Catalog password files beside it. The
|
||||
generated `deploy/local/operator.env` contains only absolute paths to those files; never copy
|
||||
secret values into `operator.env`.
|
||||
|
||||
The file uses strict `KEY=VALUE` lines (comments and blank lines are allowed). The supported
|
||||
installation keys are `THT_MODEL_API_KEY`, `THT_DWH_API_KEY`, `THT_CA`, `THT_SSL_CA`,
|
||||
`THT_OIDC_CLIENT_SECRET`, and `THT_AUTHENTIK_API_TOKEN`. Installation Model Catalog providers may
|
||||
@@ -29,6 +34,11 @@ Session and metadata-generation runtimes read only the provider key named by
|
||||
credential reference, not their execution lifecycle. Pi-owned authentication remains available only
|
||||
to session-only built-in providers through `authentication.mode: pi_auth`.
|
||||
|
||||
Workspace database credentials are intentionally not part of this global bundle. Configure each
|
||||
workspace's database binding, password/token, tunnel key and CA in Database Management; the
|
||||
installation stores those values in its encrypted workspace secret store. The workspace Git
|
||||
repository may declare database identity and Evidence, but must never contain these credentials.
|
||||
|
||||
Do not add vector or embedding endpoint credentials to the bundle. Active operator manuals use
|
||||
internal Qdrant and Ollama services, so vector/embedding runtime endpoint secrets are not part of
|
||||
the supported installation contract.
|
||||
|
||||
@@ -96,10 +96,15 @@ deve invece contenere `mode` e `defaultLocale`, altrimenti viene rifiutato.
|
||||
## Lingua, continuità e dati
|
||||
|
||||
La lingua UI traduce il testo dell'applicazione, non i contenuti di dominio.
|
||||
Alla creazione, la lingua UI viene acquisita come `interactionLanguage`; il
|
||||
manifest salva `interaction_language`, che governa domande e scelte del modello.
|
||||
Alla creazione, la lingua UI viene acquisita come `interactionLanguage` di ripiego.
|
||||
Il CLI riconosce la lingua della domanda originale e salva `interaction_language`
|
||||
nel manifest; usa il ripiego solo per input troppo brevi, ambigui o composti da codice.
|
||||
Questa lingua governa domande, spiegazioni, scelte e controlli HITL. Il gate la
|
||||
include nei descrittori e il frontend la applica al sottoalbero dei widget,
|
||||
senza cambiare la lingua della navigazione.
|
||||
Alla ripresa vale la lingua salvata, non l'ultima scelta dell'header. Per i manifest
|
||||
precedenti senza campo viene fissata la lingua workspace disponibile alla prima ripresa.
|
||||
precedenti senza campo viene riconosciuta e fissata la lingua della domanda,
|
||||
con la lingua workspace disponibile alla prima ripresa come ripiego.
|
||||
|
||||
Il cambio lingua Omics invia il form Django e ricarica la pagina. ThothII conserva
|
||||
solo l'ID della selezione in `sessionStorage`, separato per pathname, issuer e
|
||||
|
||||
@@ -81,20 +81,20 @@ The model proposes; a human reviewer decides at gates through widgets:
|
||||
|
||||
The frontend renders these widget descriptors (registry in `src/widgets/`). It rebuilds the live transcript in memory from the SSE stream (`src/store/sessionStore.ts`); it is **not persisted**.
|
||||
|
||||
## Curated and immutable Evidence
|
||||
## Evidence sources, local authority and search projections
|
||||
|
||||
The workspace repository is the publication boundary. The curator prepares `evidence/source/`,
|
||||
reviews units in `evidence/curated/`, validates them, and merges them. With `evidence.schema_version: 2`,
|
||||
the runtime materializes the full `evidence/` tree from the exact Git commit, but the renderer passes
|
||||
only `curated/**/*.md` from the immutable revision root to preprocessing. Sources, manifests, and
|
||||
evaluation data remain available for traceability. The runtime never modifies, stages, commits, or
|
||||
publishes the authoring repository.
|
||||
The workspace repository publishes revision-pinned workspace identities and Evidence sources.
|
||||
An initialized editable Evidence archive is maintained locally through external editors and
|
||||
explicit consolidation; normal preprocessing or source refresh must not overwrite its manual
|
||||
corrections. File save, active search generation and a later human Git commit/push are separate
|
||||
outcomes. See [the current Evidence contract](../contracts/curated-evidence-v4.md) and
|
||||
[source/publication boundaries](../contracts/workspace-evidence-v3.md).
|
||||
|
||||
Before indexing, the curated corpus from the pinned revision is validated. Each workspace has two
|
||||
physical Qdrant collections with different lifecycles. `reference` contains Schema, relationships,
|
||||
and Evidence and may be replaced or cleared by preprocessing; `memory` contains `memory` and
|
||||
`solved_question` records and is never preprocessing output. Only the `reference` collection has the
|
||||
sparse `bm25` vector with `idf`, and only the Evidence stage writes sparse values.
|
||||
Each workspace has separate Qdrant collections. `reference` contains Schema, relationships and
|
||||
Evidence and may be replaced or cleared by preprocessing. Memory uses its own dense/BM25
|
||||
projection, rebuilt from authoritative PostgreSQL cards rather than old vector payloads or
|
||||
session artifacts. Both collections can contain sparse vectors; their ownership and cleanup
|
||||
lifecycles remain separate. See [Memory](../gestione-memory.md).
|
||||
|
||||
The Administration control can clear the replaceable reference collection, LSH, corpus, and derived
|
||||
checkpoints. The operation preserves the memory collection and makes preprocessing required before
|
||||
@@ -115,6 +115,13 @@ the core can admit a new session.
|
||||
|
||||
## Runtime composition
|
||||
|
||||
PostgreSQL is the current database-metadata authority for all core consumers, not a deferred
|
||||
catalog-to-core integration. The historical research on a separate catalog service and
|
||||
`annotations.yaml` publication is superseded by ADRs 0004 and 0016. Preserve read-only DWH access,
|
||||
installation-local bindings/secrets, revision-pinned workspace identity, and fail-closed readiness
|
||||
when changing those boundaries. The exact snapshot interface is the
|
||||
[Catalog Schema Snapshot contract](../contracts/catalog-schema-snapshot.md).
|
||||
|
||||
The local stack is started by `./scripts/run-stack.sh` after the installation descriptor and
|
||||
`deploy/env/local.env` exist. `core` includes Pi. `catalog-db`, Qdrant, and the Ollama embedding
|
||||
service are internal Compose services; only the DWH and model-provider endpoint remain external.
|
||||
|
||||
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 186 KiB |
@@ -1,32 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Archify automated browser evidence · thothii-core-sequence.html</title>
|
||||
<style>
|
||||
*{box-sizing:border-box}body{margin:0;padding:24px;background:#e9eef5;color:#172033;font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}header{max-width:1500px;margin:0 auto 18px}h1{margin:0 0 6px;font-size:20px}p{margin:0;color:#526176}.grid{max-width:1500px;margin:auto;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}figure{margin:0;padding:10px;background:white;border:1px solid #c9d4e3;border-radius:12px;box-shadow:0 10px 30px rgba(15,23,42,.08)}img{display:block;width:100%;height:auto;border:1px solid #e2e8f0}figcaption{padding:9px 4px 2px;color:#526176}@media(max-width:900px){.grid{grid-template-columns:1fr}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header><h1>Automated browser evidence</h1><p>thothii-core-sequence.html · visual-check containment pass · perceptual visual review pending</p></header>
|
||||
<main class="grid">
|
||||
<figure>
|
||||
<img src="thothii-core-sequence.visual-check.1440x900.light.png" alt="light 1440 by 900">
|
||||
<figcaption><strong>LIGHT</strong> · 1440×900 · containment pass</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="thothii-core-sequence.visual-check.1440x900.dark.png" alt="dark 1440 by 900">
|
||||
<figcaption><strong>DARK</strong> · 1440×900 · containment pass</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="thothii-core-sequence.visual-check.2048x1320.light.png" alt="light 2048 by 1320">
|
||||
<figcaption><strong>LIGHT</strong> · 2048×1320 · containment pass</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="thothii-core-sequence.visual-check.2048x1320.dark.png" alt="dark 2048 by 1320">
|
||||
<figcaption><strong>DARK</strong> · 2048×1320 · containment pass</figcaption>
|
||||
</figure>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,548 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "visual-check",
|
||||
"evidenceKind": "automated-browser",
|
||||
"status": "pass",
|
||||
"visualReview": "pending",
|
||||
"artifact": {
|
||||
"path": "/Users/mp/projects/ThothII/docs/architecture/thothii-core-sequence.html",
|
||||
"sha256": "b521eb942f7889cfc3a5e29010546ba59eeab1cf485c22c533d271ccef9a28d5",
|
||||
"bytes": 716881
|
||||
},
|
||||
"state": {
|
||||
"detail": "read",
|
||||
"motion": "still"
|
||||
},
|
||||
"chrome": {
|
||||
"status": "available",
|
||||
"executable": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"containment": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1194,
|
||||
"diagramWidth": 1164,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1242,
|
||||
"diagramWidth": 1212,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1402,
|
||||
"diagramWidth": 1372,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1818,
|
||||
"diagramWidth": 1768,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"readability": {
|
||||
"status": "pass",
|
||||
"minimumProjectedNodeTextPx": 6,
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1194,
|
||||
"diagramWidth": 1164,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1242,
|
||||
"diagramWidth": 1212,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1402,
|
||||
"diagramWidth": 1372,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1818,
|
||||
"diagramWidth": 1768,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewerChrome": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1194,
|
||||
"diagramWidth": 1164,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1242,
|
||||
"diagramWidth": 1212,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1402,
|
||||
"diagramWidth": 1372,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1818,
|
||||
"diagramWidth": 1768,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"captures": {
|
||||
"status": "pass",
|
||||
"screenshots": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1194,
|
||||
"diagramWidth": 1164,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light",
|
||||
"file": "thothii-core-sequence.visual-check.1440x900.light.png"
|
||||
},
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "dark",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1194,
|
||||
"diagramWidth": 1164,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "dark",
|
||||
"file": "thothii-core-sequence.visual-check.1440x900.dark.png"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1818,
|
||||
"diagramWidth": 1768,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light",
|
||||
"file": "thothii-core-sequence.visual-check.2048x1320.light.png"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "dark",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1818,
|
||||
"diagramWidth": 1768,
|
||||
"viewBoxWidth": 1080,
|
||||
"minimumProjectedNodeTextPx": 7,
|
||||
"minimumProjectedNodeText": "browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "dark",
|
||||
"file": "thothii-core-sequence.visual-check.2048x1320.dark.png"
|
||||
}
|
||||
],
|
||||
"contactSheet": "thothii-core-sequence.visual-check.html"
|
||||
},
|
||||
"sidecars": {
|
||||
"receipt": "thothii-core-sequence.visual-check.json",
|
||||
"contactSheet": "thothii-core-sequence.visual-check.html"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 182 KiB |
@@ -1,32 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Archify automated browser evidence · thothii-runtime.html</title>
|
||||
<style>
|
||||
*{box-sizing:border-box}body{margin:0;padding:24px;background:#e9eef5;color:#172033;font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}header{max-width:1500px;margin:0 auto 18px}h1{margin:0 0 6px;font-size:20px}p{margin:0;color:#526176}.grid{max-width:1500px;margin:auto;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}figure{margin:0;padding:10px;background:white;border:1px solid #c9d4e3;border-radius:12px;box-shadow:0 10px 30px rgba(15,23,42,.08)}img{display:block;width:100%;height:auto;border:1px solid #e2e8f0}figcaption{padding:9px 4px 2px;color:#526176}@media(max-width:900px){.grid{grid-template-columns:1fr}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header><h1>Automated browser evidence</h1><p>thothii-runtime.html · visual-check containment pass · perceptual visual review pending</p></header>
|
||||
<main class="grid">
|
||||
<figure>
|
||||
<img src="thothii-runtime.visual-check.1440x900.light.png" alt="light 1440 by 900">
|
||||
<figcaption><strong>LIGHT</strong> · 1440×900 · containment pass</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="thothii-runtime.visual-check.1440x900.dark.png" alt="dark 1440 by 900">
|
||||
<figcaption><strong>DARK</strong> · 1440×900 · containment pass</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="thothii-runtime.visual-check.2048x1320.light.png" alt="light 2048 by 1320">
|
||||
<figcaption><strong>LIGHT</strong> · 2048×1320 · containment pass</figcaption>
|
||||
</figure>
|
||||
<figure>
|
||||
<img src="thothii-runtime.visual-check.2048x1320.dark.png" alt="dark 2048 by 1320">
|
||||
<figcaption><strong>DARK</strong> · 2048×1320 · containment pass</figcaption>
|
||||
</figure>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,548 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"ok": true,
|
||||
"command": "visual-check",
|
||||
"evidenceKind": "automated-browser",
|
||||
"status": "pass",
|
||||
"visualReview": "pending",
|
||||
"artifact": {
|
||||
"path": "/Users/mp/projects/ThothII/docs/architecture/thothii-runtime.html",
|
||||
"sha256": "ad19195852c7c643228663e5bf7f3cb273afb0456fedbe295d4df24bc345b6c7",
|
||||
"bytes": 724277
|
||||
},
|
||||
"state": {
|
||||
"detail": "read",
|
||||
"motion": "still"
|
||||
},
|
||||
"chrome": {
|
||||
"status": "available",
|
||||
"executable": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
||||
},
|
||||
"diagnostics": [],
|
||||
"containment": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 968,
|
||||
"diagramWidth": 938,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.20735294117647,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1009,
|
||||
"diagramWidth": 979,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.478676470588235,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1172,
|
||||
"diagramWidth": 1142,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 7.557352941176471,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1583,
|
||||
"diagramWidth": 1533,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 9,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"readability": {
|
||||
"status": "pass",
|
||||
"minimumProjectedNodeTextPx": 6,
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 968,
|
||||
"diagramWidth": 938,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.20735294117647,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1009,
|
||||
"diagramWidth": 979,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.478676470588235,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1172,
|
||||
"diagramWidth": 1142,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 7.557352941176471,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1583,
|
||||
"diagramWidth": 1533,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 9,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"viewerChrome": {
|
||||
"status": "pass",
|
||||
"viewports": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 968,
|
||||
"diagramWidth": 938,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.20735294117647,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1600,
|
||||
"height": 1000,
|
||||
"theme": "light",
|
||||
"innerWidth": 1600,
|
||||
"innerHeight": 1000,
|
||||
"scrollWidth": 1600,
|
||||
"scrollHeight": 1000,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1009,
|
||||
"diagramWidth": 979,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.478676470588235,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"theme": "light",
|
||||
"innerWidth": 1920,
|
||||
"innerHeight": 1080,
|
||||
"scrollWidth": 1920,
|
||||
"scrollHeight": 1080,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1172,
|
||||
"diagramWidth": 1142,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 7.557352941176471,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1583,
|
||||
"diagramWidth": 1533,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 9,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light"
|
||||
}
|
||||
]
|
||||
},
|
||||
"captures": {
|
||||
"status": "pass",
|
||||
"screenshots": [
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "light",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 968,
|
||||
"diagramWidth": 938,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.20735294117647,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light",
|
||||
"file": "thothii-runtime.visual-check.1440x900.light.png"
|
||||
},
|
||||
{
|
||||
"width": 1440,
|
||||
"height": 900,
|
||||
"theme": "dark",
|
||||
"innerWidth": 1440,
|
||||
"innerHeight": 900,
|
||||
"scrollWidth": 1440,
|
||||
"scrollHeight": 900,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 968,
|
||||
"diagramWidth": 938,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 6.20735294117647,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 51,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "dark",
|
||||
"file": "thothii-runtime.visual-check.1440x900.dark.png"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "light",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1583,
|
||||
"diagramWidth": 1533,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 9,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "light",
|
||||
"file": "thothii-runtime.visual-check.2048x1320.light.png"
|
||||
},
|
||||
{
|
||||
"width": 2048,
|
||||
"height": 1320,
|
||||
"theme": "dark",
|
||||
"innerWidth": 2048,
|
||||
"innerHeight": 1320,
|
||||
"scrollWidth": 2048,
|
||||
"scrollHeight": 1320,
|
||||
"overflowX": false,
|
||||
"overflowY": false,
|
||||
"ok": true,
|
||||
"readerWidth": 1583,
|
||||
"diagramWidth": 1533,
|
||||
"viewBoxWidth": 1360,
|
||||
"minimumProjectedNodeTextPx": 9,
|
||||
"minimumProjectedNodeText": "Browser",
|
||||
"minimumProjectedNodeTextDetail": "context",
|
||||
"minimumRequiredNodeTextPx": 6,
|
||||
"readabilityOk": true,
|
||||
"hasLegend": true,
|
||||
"hasNavigationDock": true,
|
||||
"legendDockIntersectionArea": 0,
|
||||
"dockStageIntersectionArea": 0,
|
||||
"dockStageGap": 10.21875,
|
||||
"requiredDockStageGap": 10,
|
||||
"viewerChromeStageOk": true,
|
||||
"viewerChromeReserve": 41,
|
||||
"viewerChromeActive": true,
|
||||
"viewerChromeOk": true,
|
||||
"resolvedTheme": "dark",
|
||||
"file": "thothii-runtime.visual-check.2048x1320.dark.png"
|
||||
}
|
||||
],
|
||||
"contactSheet": "thothii-runtime.visual-check.html"
|
||||
},
|
||||
"sidecars": {
|
||||
"receipt": "thothii-runtime.visual-check.json",
|
||||
"contactSheet": "thothii-runtime.visual-check.html"
|
||||
}
|
||||
}
|
||||
@@ -244,5 +244,5 @@ The first installed consolidation performs this conversion automatically when th
|
||||
legacy manifest is present, then validates and activates the result. Preserve the
|
||||
existing checkout in backups before upgrading. The E1 validation used an isolated
|
||||
copy; E2 also converted and indexed all 35 units on the running local preview.
|
||||
See the [E1 validation report](../plans/2026-09-09-evidence-e1-validation.md) and
|
||||
[E2 validation report](../plans/2026-09-09-evidence-e2-validation.md).
|
||||
See the [E1 validation report](../reports/knowledge-archives-release.md) and
|
||||
[E2 validation report](../reports/knowledge-archives-release.md).
|
||||
|
||||
@@ -4,7 +4,7 @@ This page describes the complete workspace Evidence lifecycle: where original ma
|
||||
|
||||
## Editable local Evidence
|
||||
|
||||
E1 adds [Curated Evidence v4 and a persistent local archive](contracts/curated-evidence-v4.md).
|
||||
E1 adds [Curated Evidence v4 and a persistent local archive](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/curated-evidence-v4.md).
|
||||
The visible title and payload fields are authoritative Markdown. New manual units need no
|
||||
external source; consolidation records their curator and distinguishes later corrections
|
||||
from original documentary provenance. The core archive API creates immutable candidates
|
||||
@@ -14,12 +14,12 @@ E2 adds **Administration → Evidence management**, actual host file paths, comp
|
||||
browsing and filtering, and the installed `tht workspace evidence consolidate
|
||||
--workspace <id>` command. Edit files externally, consolidate to activate them, then
|
||||
review and run Git manually. Runtime consumes only the active local snapshot.
|
||||
The [v4 contract](contracts/curated-evidence-v4.md#administration-and-installed-command)
|
||||
The [v4 contract](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/curated-evidence-v4.md#administration-and-installed-command)
|
||||
describes host mounting, first conversion, failure recovery and Clear behavior.
|
||||
The local PSD preview has 35 converted and indexed units. E3 adds explicit import/refresh
|
||||
from local drafts and configured HTTP/S3 sources, durable current/proposed comparisons,
|
||||
and keep/replace decisions with activation and retry. See
|
||||
[Import drafts and refresh sources](contracts/curated-evidence-v4.md#import-drafts-and-refresh-sources).
|
||||
[Import drafts and refresh sources](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/curated-evidence-v4.md#import-drafts-and-refresh-sources).
|
||||
Workflow gate corrections remain the subsequent shared increment, X1.
|
||||
|
||||
## Existing repository publication path
|
||||
@@ -92,7 +92,7 @@ Join orders using the order number, financial year and company.
|
||||
|
||||
Use `tht evidence migrate <workspace-root>` for deterministic legacy conversion. The
|
||||
conversion preserves typed content and initializes an archive baseline; it does not
|
||||
activate the local corpus. See the [v4 contract](contracts/curated-evidence-v4.md) for
|
||||
activate the local corpus. See the [v4 contract](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/curated-evidence-v4.md) for
|
||||
all eight kinds, provenance, file layout and the E1/E2 boundary.
|
||||
|
||||
## Legacy v3 representation
|
||||
@@ -262,5 +262,5 @@ Formulas use a format distinct from document Evidence. A formula proposed during
|
||||
|
||||
## Contract references
|
||||
|
||||
- [Workspace Evidence v3 contract](contracts/workspace-evidence-v3.md)
|
||||
- [Preprocessing CLI contract](contracts/workspace-preprocessing-cli.md)
|
||||
- [Workspace Evidence v3 contract](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/workspace-evidence-v3.md)
|
||||
- [Preprocessing CLI contract](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/workspace-preprocessing-cli.md)
|
||||
|
||||
@@ -128,6 +128,51 @@ endpoint expects a model name different from the catalog key.
|
||||
Provider integrations remain declarative. Do not register providers from
|
||||
`harness/.pi/extensions/`; those extensions implement the workflow and human gates only.
|
||||
|
||||
### Qwen 3.6 sessions and thinking controls
|
||||
|
||||
For Qwen served through a vLLM-compatible chat template, declare the following inside the
|
||||
model's `session` block, alongside its context and output limits:
|
||||
|
||||
```yaml
|
||||
reasoning: true
|
||||
compatibility:
|
||||
supportsDeveloperRole: false
|
||||
supportsReasoningEffort: false
|
||||
supportsStore: false
|
||||
maxTokensField: max_tokens
|
||||
thinkingFormat: qwen-chat-template
|
||||
```
|
||||
|
||||
This makes Pi send `chat_template_kwargs.enable_thinking` from the selected thinking level,
|
||||
with `preserve_thinking: true`. Choose **off** to explicitly disable thinking. The alternative
|
||||
`thinkingFormat: qwen` is for endpoints expecting top-level `enable_thinking`. Both formats
|
||||
require `reasoning: true`; declaring `reasoning: false` does not tell the server to disable
|
||||
thinking. Omit `thinkingFormat` to preserve Pi's default behavior for other providers.
|
||||
|
||||
Regenerate projections with the updated host CLI and recreate the local core container after
|
||||
rebuilding it. Do not add these fields directly to generated Pi files. These controls do not
|
||||
force tool calls or certify the workflow; perform the operator verification above.
|
||||
|
||||
```sh
|
||||
tht --installation /absolute/path/thothii-installation.yaml installation generate
|
||||
```
|
||||
|
||||
Use the model identifier exposed by your endpoint, such as `qwen3.6-35b-a3b`, and limits
|
||||
supported by that deployment. The thinking format configures the Pi session adapter;
|
||||
metadata generation continues to use its separate LiteLLM settings.
|
||||
|
||||
If a session displays text such as `{"type":"bash","command":"tht session show … --json"}`
|
||||
and never opens a review widget, that text is not an executed tool call. A verified cause
|
||||
was the Evidence JSON extension being loaded into interactive sessions and forcing
|
||||
`response_format: {type: "json_object"}`. Upgrade to the core image containing the fix:
|
||||
the extension belongs in `.pi/evidence-extensions/` and is loaded explicitly only by
|
||||
Evidence authoring. It must not also remain in the automatically loaded `.pi/extensions/`
|
||||
directory. Regenerating model configuration alone does not remove an extension from an old image.
|
||||
|
||||
After upgrading, reload the browser and resume the session. Verify that Pi executes
|
||||
`tht session show` and opens a review widget. This fix does not require changing the Qwen
|
||||
server, forcing every turn to call a tool, or teaching the model to print tool-call JSON.
|
||||
|
||||
## Authentication
|
||||
|
||||
Every provider chooses one explicit mode:
|
||||
|
||||
@@ -226,5 +226,5 @@ error. Preparation is repeatable and checks migration checksums.
|
||||
See [the M1 specification](plans/2026-09-08-memory-m1-spec.md) and
|
||||
[ADR 0018](adr/0018-use-postgres-for-memory-and-qdrant-for-retrieval.md) for the
|
||||
approved scope and acceptance boundaries.
|
||||
See [M2 implementation and validation](plans/2026-09-09-memory-m2-validation.md)
|
||||
See [M2 implementation and validation](reports/knowledge-archives-release.md)
|
||||
for the retrieval checks and real embedding test command.
|
||||
|
||||
@@ -90,4 +90,4 @@ happen from the workflow’s point of view.
|
||||
session does not become Evidence automatically: a curator must review and publish it in Git.
|
||||
- For login and access recovery, use [local authentication](install/authentication-local.md) or
|
||||
[OIDC authentication](install/authentication-oidc.md) for full, or contact the
|
||||
portal administrator for [embedded/upstream access](install/authentication-upstream.md).
|
||||
portal administrator for [embedded/upstream access](install/shell-and-language.md).
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
# ThothII documentation
|
||||
|
||||
ThothII is a human-reviewed datamart builder. It turns a question into validated SQL through an
|
||||
eight-phase workflow: the model proposes; a reviewer makes the decisions that are persisted.
|
||||
ThothII turns a natural-language question into reviewed SQL. The model proposes;
|
||||
a human reviewer decides which interpretations, sources and results to accept.
|
||||
|
||||
Start with the path that matches the work you need to do:
|
||||
This is the public product manual. Start with the task you need to perform:
|
||||
|
||||
| I need to… | Start here |
|
||||
| --- | --- |
|
||||
| Install or operate one instance | [Install and first start](install/first-start.md) |
|
||||
| Clone and manually install on macOS, Windows, or Linux | [Italian procedure](install/standalone-manual-it.md) · [English procedure](install/standalone-manual-en.md) |
|
||||
| Upgrade the server and integrate Omics Portal | [Codex server handoff](operations/server-codex-handoff.md) |
|
||||
| Choose full/embedded and configure the shell | [Shell and localization](operations/shell-and-localization.md) |
|
||||
| Reuse an authenticated server portal without a second login | [Upstream authentication](install/authentication-upstream.md) |
|
||||
| Understand how the two renderings share the same application | [Rendering architecture](architecture/application-shell.md) |
|
||||
| Validate login, logout and portal integration before release | [Acceptance matrix](testing/authentication-manual-acceptance.md) |
|
||||
| Add, update, or prepare a workspace | [Workspace operations](operations/workspaces.md) |
|
||||
| Ask a question and review the SQL workflow | [User guide](guida-utente.md) |
|
||||
| Configure and refresh an authoritative database catalog | [Database management](operations/database-management.md) |
|
||||
| Author and publish domain Evidence | [Evidence](evidence.md) |
|
||||
| Understand boundaries and persistence | [Architecture overview](architecture/overview.md) |
|
||||
| Understand the product and its boundaries | [What ThothII does](product-overview.md) |
|
||||
| Install on Mac, Windows through WSL2, or Linux | [Italian procedure](install/standalone-manual-it.md) · [English procedure](install/standalone-manual-en.md) |
|
||||
| Choose display mode and language | [Display mode and language](install/shell-and-language.md) |
|
||||
| Configure login | [Local accounts](install/authentication-local.md) · [OIDC](install/authentication-oidc.md) |
|
||||
| Configure model providers | [Model configuration](general/pi-configuration.md) |
|
||||
| Prepare a domain workspace | [Workspaces](operations/workspaces.md) |
|
||||
| Configure databases and reviewed descriptions | [Database management](operations/database-management.md) |
|
||||
| Ask a question and review SQL | [User guide](guida-utente.md) · [Workflow](skills.md) |
|
||||
| Maintain domain knowledge | [Evidence](evidence.md) · [Memory](usage/memory.md) |
|
||||
|
||||
## How the documentation is organised
|
||||
## Scope of this manual
|
||||
|
||||
- **Install and operate** documents host-side setup, authentication, lifecycle, workspaces, and
|
||||
Pi administration.
|
||||
- **Use ThothII** documents the two application paths: reviewed NL→SQL sessions and administrative
|
||||
database management.
|
||||
- **Architecture and contracts** explain why the system behaves as it does and define the
|
||||
machine-facing boundaries. Consult them when integrating or changing an implementation; they
|
||||
are not a substitute for an operator runbook.
|
||||
The manual covers the product, installation, use and administration. Architecture,
|
||||
code contracts, design decisions, implementation plans, test reports and site-specific
|
||||
deployment handoffs are developer/project material maintained in the repository;
|
||||
they are not pages of this site and are not included in its search index.
|
||||
|
||||
The host-side `tht` command is the operator interface. The Python `tht` inside `harness/` is a
|
||||
different, internal workflow CLI invoked by the core. In examples, use an absolute installation
|
||||
descriptor path whenever discovery is not unambiguous.
|
||||
The installation procedures distinguish checked documentation from platform and
|
||||
functional tests that still require execution. A clone does not transfer another
|
||||
installation's credentials, data or network access.
|
||||
|
||||
The host-side `tht` command operates an installation. The Python workflow CLI inside
|
||||
the runtime is a separate internal interface; do not substitute its commands for
|
||||
the host installation procedure.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Use local mode for a standalone PC or Mac, with `shell.mode: full` and
|
||||
`shell.defaultLocale: en` in the installation descriptor. Presentation and
|
||||
authentication are independent: selecting full does not create accounts. Omics
|
||||
embedded instead uses the [upstream guide](authentication-upstream.md), not local users.
|
||||
embedded instead uses the [upstream guide](shell-and-language.md), not local users.
|
||||
|
||||
Configure local authentication through `tht`; passwords are entered at an
|
||||
echo-free prompt or read from a protected `--password-file`, never from a command argument.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Use this guide for **ThothII's own login**, normally `shell.mode: full` on an
|
||||
autonomous server. It is not the integration procedure for an already logged-in
|
||||
Omics user. That deployment uses [embedded/upstream](authentication-upstream.md),
|
||||
Omics user. That deployment uses [embedded/upstream](shell-and-language.md),
|
||||
even when Omics's identity provider is Authentik.
|
||||
|
||||
OIDC mode supports a standards-based provider. The browser flow is generic: Authorization Code,
|
||||
@@ -104,7 +104,7 @@ Any authentication failure prevents activation according to the static or live s
|
||||
relevant diagnostic surface.
|
||||
|
||||
The complete closed diagnostic-code union and exact role-to-permission expansion are in the
|
||||
[authentication architecture](../architecture/authentication.md).
|
||||
[authentication architecture](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/architecture/authentication.md).
|
||||
|
||||
## Browser login and logout
|
||||
|
||||
@@ -114,4 +114,4 @@ password prompt, but this remains a distinct ThothII login/session, unlike Omics
|
||||
upstream. Full's name menu logs out of ThothII only. It does not revoke the
|
||||
provider session or log out other applications, so a subsequent login can return
|
||||
immediately through SSO. No provider token is placed in the UI adapter or browser
|
||||
storage. See the [manual acceptance matrix](../testing/authentication-manual-acceptance.md).
|
||||
storage. See the [manual acceptance matrix](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/testing/authentication-manual-acceptance.md).
|
||||
|
||||
@@ -8,7 +8,7 @@ For **embedded in Omics**, retain Omics's existing Authentik authentication and
|
||||
configure ThothII as upstream. Omics verifies `datamart_builder.access` and
|
||||
administrator status and the proxy supplies the identity; no additional ThothII
|
||||
OIDC client, login or local user is required for that path. Follow the
|
||||
[portal integration guide](authentication-upstream.md).
|
||||
[portal integration guide](shell-and-language.md).
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
@@ -1,98 +1,63 @@
|
||||
# Install and first start
|
||||
|
||||
For the ordered clone-to-start procedure on Mac, Windows WSL2 and Linux, use the
|
||||
[Italian manual guide](standalone-manual-it.md) or [English manual guide](standalone-manual-en.md),
|
||||
including protected credentials and the explicit initial catalog migration.
|
||||
Use the guided procedure for a fresh installation:
|
||||
|
||||
This is the supported local installation path. It creates an installation-local configuration and
|
||||
starts the Compose stack; it does not create a workspace repository or a database catalog entry.
|
||||
- [Italian guided installation](standalone-manual-it.md)
|
||||
- [English guided installation](standalone-manual-en.md)
|
||||
|
||||
## Prerequisites and boundaries
|
||||
The procedure covers Windows through Ubuntu WSL2, macOS, and Linux including an Omarchy/Arch-like
|
||||
host. It uses the application clone, one installation secret bundle, protected repository
|
||||
credentials when needed, and a terminal command. No host Node.js, Python or Pi installation is
|
||||
required.
|
||||
|
||||
Install Docker Engine with Compose v2, plus the host `tht` command. On macOS or Linux, install the
|
||||
host command from the repository with `./scripts/install-tht.sh`; Windows uses
|
||||
`./scripts/install-tht.ps1`. The installer builds or verifies the native command and checks that
|
||||
`tht` is resolvable on `PATH`.
|
||||
## What must be ready
|
||||
|
||||
The stack contains `frontend`, `core`, `catalog-db`, `qdrant`, `embedding`, and the one-shot
|
||||
`embedding-model-init` and `catalog-migrate` services. DWH and model-provider endpoints are
|
||||
external installation settings. Pi runs inside `core`; do not install a host Pi executable for
|
||||
the application runtime.
|
||||
You need Docker with Compose v2, Git, Bash, curl, OpenSSL and shasum. You also need access to the
|
||||
workspace repository and the values supplied by its owner: repository URL/branch, DWH endpoint,
|
||||
database/schema, transport, credentials or certificates, Evidence credentials when applicable,
|
||||
and LLM provider/API-key information.
|
||||
|
||||
Secrets, certificates, Pi authentication, and workspace endpoint bindings are protected
|
||||
installation-local files. Never put them in a workspace descriptor, an env file intended for
|
||||
version control, a URL, or a command line.
|
||||
The workspace repository and the THothII application repository are different. A workspace
|
||||
descriptor may declare Evidence, but database passwords and installation bindings are stored in
|
||||
the installation Catalog, not in Git.
|
||||
|
||||
## Create the local installation
|
||||
## One guided command
|
||||
|
||||
From the repository root, start the interactive setup and select the local profile:
|
||||
After cloning THothII, checking prerequisites and installing tht, run:
|
||||
|
||||
```sh
|
||||
tht setup --profile local --shell-mode full --shell-default-locale en
|
||||
```
|
||||
~~~
|
||||
tht setup --complete --profile local --shell-mode full --shell-default-locale en
|
||||
~~~
|
||||
|
||||
It writes the selected non-secret descriptor below `deploy/<installation-id>/`, the associated
|
||||
operator env file, and can create protected secret templates. Keep the descriptor path: pass it
|
||||
to commands as `--installation /absolute/path/thothii-installation.yaml` when more than one
|
||||
installation can be discovered.
|
||||
The first run creates protected placeholders under deploy/local/secrets/. Fill the required
|
||||
credential files and rerun the same command. The command validates the local files and paths,
|
||||
renders Compose, builds the images, starts catalog-db, runs catalog-migrate, starts the full
|
||||
stack, and pulls/activates the workspace repository. Evidence source files declared by the
|
||||
workspace are imported during activation.
|
||||
|
||||
The explicit shell options are important: compatibility defaults without them
|
||||
are embedded/en/omics-portal, which expects an Omics document. The Mac's standalone
|
||||
installation must use full, with English as its initial locale. Existing browser
|
||||
language preferences take precedence over that initial value. Full does not
|
||||
configure authentication; setup separately bootstraps local login.
|
||||
For an already configured installation:
|
||||
|
||||
For a server portal, use the [embedded/upstream procedure](authentication-upstream.md)
|
||||
instead of creating a second ThothII login. For a standalone server, use full
|
||||
with [direct OIDC](authentication-oidc.md). Shell mode does not follow `profile`
|
||||
automatically. See [configuration and regeneration](../operations/shell-and-localization.md)
|
||||
before modifying an existing installation.
|
||||
|
||||
If the descriptor is prepared manually instead, begin with
|
||||
[`thothii-installation.local.yaml`](examples/thothii-installation.local.yaml), set mode `0600` or
|
||||
`0400`, and ensure `THT_INSTALLATION_CONFIG_SOURCE` in the selected env file points to that exact
|
||||
file. Create the secret bundle from `deploy/secrets/thothii.secrets.example`, protect it, and set
|
||||
the file locations and external endpoints in the env file. The required settings include:
|
||||
|
||||
- `PI_AUTH_FILE`, `THT_SECRETS_FILE`, and the catalog password source files;
|
||||
- `THT_INSTALLATION_CONFIG_SOURCE` and the workspace Git remote/branch;
|
||||
- the DWH and model-provider endpoints; and
|
||||
- `THT_AUTH_CONFIG_ROOT` for local authentication or the OIDC configuration selected during setup.
|
||||
|
||||
For the supported secret names and the metadata-generation model credential boundary, see the
|
||||
`deploy/secrets/README.md` file in the installation checkout. It is intentionally not published
|
||||
as a documentation page because it describes a protected local-file contract.
|
||||
|
||||
## Start and verify
|
||||
|
||||
For the normal local path, use the launcher:
|
||||
|
||||
```sh
|
||||
./scripts/run-stack.sh
|
||||
```
|
||||
|
||||
It builds `core`, starts `catalog-db`, runs `catalog-migrate`, then keeps the base plus local
|
||||
Compose profile in the foreground. Database migrations are deliberately not a hidden backend
|
||||
startup action. Open `http://127.0.0.1:8080` unless `THOTH_HTTP_PORT` was changed.
|
||||
|
||||
In another terminal, verify the installation without changing it:
|
||||
|
||||
```sh
|
||||
tht --installation /absolute/path/thothii-installation.yaml doctor --json
|
||||
~~~
|
||||
tht --installation /absolute/path/thothii-installation.yaml status
|
||||
```
|
||||
tht --installation /absolute/path/thothii-installation.yaml doctor --json
|
||||
tht --installation /absolute/path/thothii-installation.yaml workspace test --json
|
||||
~~~
|
||||
|
||||
`/health` verifies application-process readiness; `tht doctor` is the diagnostic surface for
|
||||
Compose, configuration, workspace, workflow, and Pi prerequisites.
|
||||
doctor --json is the non-destructive general core test. workspace test also probes the configured
|
||||
database, Evidence, Qdrant and embedding service for every active workspace. It requires the
|
||||
workspace database to have been configured in Database Management first.
|
||||
|
||||
## Routine lifecycle and next steps
|
||||
## Installer-only completion
|
||||
|
||||
Use `tht start [--build]`, `tht stop`, `tht logs`, and `tht doctor` rather than composing ad-hoc
|
||||
container commands. Named volumes retain settings, Pi state, workspace registry, sessions,
|
||||
Qdrant data, and embedding models across `docker compose down`; removing them requires the
|
||||
explicit destructive `--volumes` form.
|
||||
The installer must still decide which LLMs and API keys are approved, configure and test each
|
||||
workspace database, synchronize its schema, generate and consolidate descriptions, create Qdrant
|
||||
entries, review naming-based FK suggestions alongside schema FKs, and load the approved
|
||||
relationships. The final declaration of completeness requires green doctor and workspace test
|
||||
results plus one real natural-language question completed through final SQL.
|
||||
|
||||
After the stack is healthy, configure authentication if setup did not do so, then continue with
|
||||
[Workspace operations](../operations/workspaces.md). For server profile, reverse proxy, backups,
|
||||
and recovery, use the deployment program and its manual gates; the server profile is not a
|
||||
drop-in replacement for the local command above.
|
||||
Migrations are part of setup --complete. Do not mix this installation’s descriptor or volumes with
|
||||
a different Compose environment. Preserve the descriptor, credentials, Catalog and persistent
|
||||
volumes; do not use docker compose down --volumes as a routine stop.
|
||||
|
||||
See the guides for the Windows/macOS/Linux prerequisite matrix, workspace repository explanation,
|
||||
secret layout and Gate A/Gate B acceptance checks.
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Display mode and language
|
||||
|
||||
ThothII can run with its own application header (**full**) or inside an integrated
|
||||
portal (**embedded**). Display mode and authentication are separate choices.
|
||||
|
||||
| Installation | Display | Authentication |
|
||||
| --- | --- | --- |
|
||||
| Standalone local instance | `full` | Local ThothII account |
|
||||
| Standalone server | `full` | Local accounts or configured OIDC provider |
|
||||
| Integrated portal | `embedded` | Identity verified by the portal's trusted server proxy |
|
||||
|
||||
## Standalone setup
|
||||
|
||||
Follow the complete [Italian](standalone-manual-it.md) or
|
||||
[English](standalone-manual-en.md) installation procedure. It explicitly selects
|
||||
`--shell-mode full --shell-default-locale en` and separates configuration, credentials,
|
||||
initial migrations and startup. Do not skip those steps by running setup alone.
|
||||
|
||||
The authored installation descriptor contains:
|
||||
|
||||
```yaml
|
||||
shell:
|
||||
mode: full
|
||||
defaultLocale: en
|
||||
```
|
||||
|
||||
Use `it` for an Italian initial interface. Existing browser language preferences can
|
||||
override that initial value. Full mode remembers language and theme in the browser.
|
||||
|
||||
For an existing installation, preserve the current descriptor and edit only the intended
|
||||
settings; do not rerun setup to overwrite it. With a current host `tht` binary:
|
||||
|
||||
```sh
|
||||
tht --installation /absolute/path/thothii-installation.yaml installation generate
|
||||
tht --installation /absolute/path/thothii-installation.yaml start
|
||||
tht --installation /absolute/path/thothii-installation.yaml status
|
||||
tht --installation /absolute/path/thothii-installation.yaml doctor --json
|
||||
```
|
||||
|
||||
Generation updates derived configuration; it does not start services. `start` applies
|
||||
the installation's normal lifecycle and is not guaranteed to touch only the frontend.
|
||||
Follow the deployment's maintenance procedure and retain its network, authentication and
|
||||
model settings. Do not edit generated files or remove persistent volumes.
|
||||
|
||||
## Authentication and embedded deployments
|
||||
|
||||
Full mode does not configure login by itself. See [local authentication](authentication-local.md)
|
||||
or [OIDC](authentication-oidc.md), with [Authentik](authentik.md) as a provider option.
|
||||
|
||||
Embedded mode requires a compatible portal integration, not just a descriptor toggle.
|
||||
The portal owns login/logout and supplies a server-verified identity. A presentation
|
||||
adapter does not authenticate users. The core must not be reachable by a route that
|
||||
bypasses the trusted proxy. Do not add a second OIDC login to an already authenticated
|
||||
upstream deployment.
|
||||
|
||||
Portal implementation details belong to the
|
||||
[developer integration reference in the repository](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/install/authentication-upstream.md),
|
||||
not to the standalone installation procedure.
|
||||
|
||||
## Three different languages
|
||||
|
||||
- **Interface language** controls labels, forms and application messages.
|
||||
- **Session interaction language** is captured when a session is created. Resuming it
|
||||
retains that language even if the interface language changes later.
|
||||
- **Workspace language** concerns domain content and retrieval; switching the interface
|
||||
does not translate Evidence, SQL, identifiers or database values.
|
||||
|
||||
In embedded mode the interface follows the portal's language and theme. A portal language
|
||||
change may reload the page. Saved session artifacts remain available, but resuming work
|
||||
is explicit; a reload does not by itself request a new model generation.
|
||||
@@ -1,324 +1,256 @@
|
||||
# Manual standalone installation
|
||||
# Guided standalone installation
|
||||
|
||||
[Versione italiana](standalone-manual-it.md)
|
||||
|
||||
This is the verification procedure for preparing THothII as a standalone application in `full`
|
||||
mode on macOS, Windows, and Linux.
|
||||
This is the fresh-machine installation procedure for THothII. THothII receives a natural-language
|
||||
question, queries an enterprise database read-only, and guides the user through SQL review. The
|
||||
core, PostgreSQL catalog, Qdrant, embedding service, and Pi run in Docker; Node.js, Python, and Pi
|
||||
are not required on the host.
|
||||
|
||||
In this document, “standalone” means that the user does not need to install Node.js, Python or Pi
|
||||
on the host: the application services and local semantic
|
||||
services run through Docker. DWH and LLM providers remain external endpoints configured by the
|
||||
installation; this is not an offline package.
|
||||
## Before you start: the two repositories
|
||||
|
||||
This path uses no graphical installer, native launcher, or Docker Hub image. It starts from a Gitea
|
||||
clone and uses explicit terminal commands. Publishing pre-built images is a later step.
|
||||
There are two separate repositories:
|
||||
|
||||
## Verification matrix
|
||||
1. the application repository cloned by the user:
|
||||
https://git.tylconsulting.it/mptyl/ThothII.git;
|
||||
2. the workspace repository supplied by the curator/installer. It is not the THothII repository
|
||||
and must not be cloned inside the application directory.
|
||||
|
||||
| System | Recommended terminal | Runtime | Test architecture |
|
||||
| --- | --- | --- | --- |
|
||||
| macOS supported by the installed Docker Desktop version | Bash in Terminal | Docker Desktop | Apple Silicon (`arm64`) |
|
||||
| Windows 11 | Ubuntu inside WSL2 | Docker Desktop with WSL2 integration | x64 (`amd64`) |
|
||||
| Ubuntu Linux 22.04 or 24.04 | Bash | Docker Engine + Compose v2 | x64 (`amd64`) |
|
||||
The workspace repository normally contains:
|
||||
|
||||
Intel macOS is excluded from the first verification campaign. ARM Linux may be tested when the
|
||||
machine’s Docker runtime reports `arm64`, but it is not part of the minimum matrix.
|
||||
~~~
|
||||
thoth-workspaces.yaml
|
||||
<workspace-id>/workspace.yaml
|
||||
<workspace-id>/evidence/** # when Evidence is declared
|
||||
~~~
|
||||
|
||||
Documentation and Mac prerequisite checks have passed. Complete fresh installations on all three
|
||||
systems remain pending; this matrix describes the tests to perform, not completed certification.
|
||||
workspace.yaml contains workspace identity, language and optional Evidence source. By design it does
|
||||
not contain database passwords. Database identity, transport (PostgreSQL, REST, or tunnel), user,
|
||||
password, token and certificates are installation-local settings stored encrypted by the Catalog.
|
||||
This prevents credentials from being committed to the workspace repository.
|
||||
|
||||
## Before you start
|
||||
## 0. Machine prerequisites
|
||||
|
||||
You need:
|
||||
### Windows
|
||||
|
||||
- access to the THothII Gitea repository and the workspace Git repository;
|
||||
- Git;
|
||||
- Docker Desktop on macOS and Windows, or Docker Engine with the Compose v2 plugin on Linux;
|
||||
- Bash, `curl`, OpenSSL and `shasum` (Ubuntu package: `libdigest-sha-perl`);
|
||||
- enough disk space to build the images and download the embedding model;
|
||||
- the DWH and LLM endpoints, plus the credentials required by the installation.
|
||||
- Windows 10/11 with Docker Desktop running and the WSL2 backend enabled.
|
||||
- Ubuntu in WSL2, with Docker Desktop integration enabled for that distribution.
|
||||
- Git, Bash, curl, OpenSSL and shasum inside WSL2.
|
||||
- Do not install Node.js, Python or Pi on the host for this procedure.
|
||||
|
||||
On Linux, the current user must be able to run Docker. If the system requires `sudo`, add the user
|
||||
to the Docker group according to local policy and open a new session before continuing.
|
||||
If WSL2 is not installed, use the company procedure or, in PowerShell:
|
||||
|
||||
On Windows, run every command in this guide from Ubuntu under WSL2. In Docker Desktop, enable WSL2
|
||||
integration for that distribution. Clone the project inside the WSL2 Linux filesystem, for example
|
||||
under `~/src`, rather than under `/mnt/c`: this avoids slow builds and path/line-ending issues. Pi
|
||||
does not need to be installed on the host.
|
||||
~~~
|
||||
wsl --install -d Ubuntu
|
||||
~~~
|
||||
|
||||
Check the runtime before or immediately after cloning:
|
||||
Run all commands inside Ubuntu WSL2, in a Linux directory such as $HOME/src, not under /mnt/c.
|
||||
scripts/install-tht.ps1 exists for advanced native PowerShell scenarios; use WSL2 for the
|
||||
reproducible test.
|
||||
|
||||
```sh
|
||||
docker version
|
||||
### macOS
|
||||
|
||||
- Docker Desktop installed and running, with several GB free for images and the embedding model.
|
||||
- Git, Bash, curl, OpenSSL and shasum.
|
||||
- Intel and Apple Silicon Macs are supported when Docker Desktop supports the architecture
|
||||
reported by the Docker server.
|
||||
- Do not install Node.js, Python or Pi on the host for this procedure.
|
||||
|
||||
### Linux, including Omarchy
|
||||
|
||||
- Git, Bash, curl, OpenSSL and shasum.
|
||||
- Docker Engine and the Docker Compose v2 plugin. On Omarchy, check first:
|
||||
|
||||
~~~
|
||||
command -v docker
|
||||
docker compose version
|
||||
docker info
|
||||
~~~
|
||||
|
||||
If Docker is missing, install Docker and Compose using the distribution-approved package procedure,
|
||||
then start the service. On an Arch-like distribution the typical route is:
|
||||
|
||||
~~~
|
||||
sudo pacman -S docker docker-compose
|
||||
sudo systemctl enable --now docker
|
||||
sudo usermod -aG docker "$USER"
|
||||
~~~
|
||||
|
||||
After adding the group, open a new session and repeat docker info. Node.js, Python and Pi are not
|
||||
needed on the host: they are in the Docker images.
|
||||
|
||||
On every system run:
|
||||
|
||||
~~~
|
||||
bash scripts/check-standalone-prerequisites.sh
|
||||
docker version --format '{{.Server.Arch}}'
|
||||
```
|
||||
~~~
|
||||
|
||||
The last command must return `amd64`, `x86_64`, `arm64`, or `aarch64`.
|
||||
The architecture must be amd64, x86_64, arm64, or aarch64. You also need access to the
|
||||
application Gitea repository, the workspace repository URL/branch and credentials, container
|
||||
reachability to DWH/LLM endpoints, and the credentials, tokens or certificates associated with
|
||||
the databases.
|
||||
|
||||
## 1. Clone a project revision
|
||||
## 1. What to clone
|
||||
|
||||
Use the project repository on Gitea:
|
||||
Clone only the application:
|
||||
|
||||
```sh
|
||||
~~~
|
||||
mkdir -p "$HOME/src"
|
||||
cd "$HOME/src"
|
||||
git clone https://git.tylconsulting.it/mptyl/ThothII.git
|
||||
cd ThothII
|
||||
git rev-parse --short HEAD
|
||||
```
|
||||
~~~
|
||||
|
||||
For an SSH clone, when the key is already authorized on Gitea:
|
||||
Record the revision. tht setup --complete downloads the workspace repository into a persistent
|
||||
Docker volume using the URL, branch and transport supplied during setup.
|
||||
|
||||
```sh
|
||||
git clone git@git.tylconsulting.it:mptyl/ThothII.git
|
||||
```
|
||||
|
||||
Record the hash printed by `git rev-parse` for a repeatable test. In a later campaign, use the
|
||||
maintainer-approved revision/tag rather than implicitly following a mutable `main` branch.
|
||||
|
||||
## 2. Check prerequisites and install the operator command
|
||||
## 2. Install the terminal command
|
||||
|
||||
From the clone root:
|
||||
|
||||
```sh
|
||||
~~~
|
||||
bash scripts/check-standalone-prerequisites.sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
THT_INSTALL_DIRECTORY="$HOME/.local/bin" bash scripts/install-tht.sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
tht version
|
||||
```
|
||||
~~~
|
||||
|
||||
`install-tht.sh` bootstraps only the native `tht` operator command; it does not install a desktop
|
||||
version of THothII. It uses the repository’s Docker builder, installs the binary for the current
|
||||
terminal environment, and installs it in the user directory. Persist `$HOME/.local/bin` in your
|
||||
shell PATH for new terminals too. An existing `tht` in this directory will be updated.
|
||||
tht is the only native component to install. It builds the binary with Docker and orchestrates
|
||||
Compose; it is not a second application runtime.
|
||||
|
||||
On Windows, run these commands inside WSL2. The installed `tht` binary is the Linux binary inside
|
||||
WSL2; the application runtime remains Docker Desktop. Do not use `scripts/install-tht.ps1` as the
|
||||
primary path for this test.
|
||||
## 3. Prepare a few secrets and run complete setup
|
||||
|
||||
## 3. Configure and start the local installation
|
||||
The first execution creates protected placeholders under deploy/local/secrets/ and stops if a
|
||||
required credential is missing. Fill in the requested files and rerun the same command; compatible
|
||||
configuration files are reused.
|
||||
|
||||
Run the remaining blocks in one Bash session from the physical clone root (`pwd -P`).
|
||||
First create two distinct catalog passwords, preserving any existing files:
|
||||
~~~
|
||||
tht setup --complete --profile local --shell-mode full --shell-default-locale en
|
||||
~~~
|
||||
|
||||
```bash
|
||||
umask 077
|
||||
mkdir -p deploy/local/secrets
|
||||
for name in catalog-runtime-password catalog-migrator-password; do
|
||||
target="deploy/local/secrets/$name"
|
||||
if [ ! -e "$target" ]; then
|
||||
(set -C; openssl rand -hex 32 > "$target") || exit 1
|
||||
fi
|
||||
done
|
||||
export THT_CATALOG_RUNTIME_PASSWORD_SOURCE="$(pwd -P)/deploy/local/secrets/catalog-runtime-password"
|
||||
export THT_CATALOG_MIGRATOR_PASSWORD_SOURCE="$(pwd -P)/deploy/local/secrets/catalog-migrator-password"
|
||||
```
|
||||
The setup asks only for information the computer cannot know:
|
||||
|
||||
Do not regenerate passwords for an initialized catalog. Configure without starting services:
|
||||
|
||||
```sh
|
||||
tht setup --profile local --shell-mode full --shell-default-locale en --configure-only
|
||||
```
|
||||
|
||||
Answer the prompts as follows:
|
||||
|
||||
| Prompt | Value or rule |
|
||||
| Request | What to provide |
|
||||
| --- | --- |
|
||||
| Installation ID | `local`, unless one clone hosts multiple installations |
|
||||
| Deployment profile | `local` |
|
||||
| DWH API endpoint | An `http(s)` URL without user, password, query, or fragment; may be empty for a smoke-only test |
|
||||
| LLM API endpoint | An `http(s)` URL without credentials; may be empty for a smoke-only test |
|
||||
| Workspace repository URL | The workspace repository URL, not the THothII source clone |
|
||||
| Workspace branch | Normally `main` |
|
||||
| Workspace access | `ssh` with a deploy key, or `https` with a protected credential file |
|
||||
| File paths | Accept the default paths under `deploy/local/secrets/` for the first test |
|
||||
| Secret templates | Answer `yes` when protected files do not exist yet |
|
||||
| Authentication | Configure the local login required by the installation; never put passwords on a command line |
|
||||
| Workspace repository | Data/configuration repository URL, not ThothII.git |
|
||||
| Branch | normally main |
|
||||
| Access | ssh with key and known_hosts, or https with credential file and CA |
|
||||
| DWH/LLM URL | endpoint without a token in the URL |
|
||||
| Local login | initial user and password requested by the prompt |
|
||||
|
||||
The generated configuration is local and ignored by Git:
|
||||
The setup generates random Catalog passwords and writes their paths, never their values, to
|
||||
operator.env. It runs docker compose config, builds images, starts the Catalog, runs
|
||||
catalog-migrate, starts the stack, and pulls the workspace repository. The pull also activates
|
||||
declared Evidence; at minimum source files present in the workspace are materialized locally.
|
||||
|
||||
```text
|
||||
deploy/local/thothii-installation.yaml
|
||||
deploy/local/operator.env
|
||||
deploy/local/auth/
|
||||
deploy/local/secrets/
|
||||
```
|
||||
### The file the user fills in
|
||||
|
||||
Edit secrets only in protected local files; never commit them. `deploy/env/local.env.example` is a tracked reference; the
|
||||
generated path `deploy/local/operator.env` is the active path for this installation.
|
||||
The main file is:
|
||||
|
||||
### Complete protected files
|
||||
~~~
|
||||
deploy/local/secrets/thothii.secrets
|
||||
~~~
|
||||
|
||||
If setup created blank templates, enter the values with a local editor:
|
||||
Add only NAME=VALUE lines needed by modelCatalog and installation adapters, such as an LLM API key
|
||||
(DEEPSEEK_API_KEY, OPENAI_API_KEY, or the key declared by the catalog) and, when applicable,
|
||||
THT_DWH_API_KEY. Allowed names are documented in deploy/secrets/README.md. Never put tokens in
|
||||
URLs, the repository, or copied shell commands.
|
||||
|
||||
```sh
|
||||
chmod 600 deploy/local/secrets/*
|
||||
"${EDITOR:-vi}" deploy/local/secrets/thothii.secrets
|
||||
```
|
||||
Two distinctions prevent common errors:
|
||||
|
||||
The bundle must contain only `KEY=VALUE` lines for credentials actually used by `modelCatalog`. The
|
||||
allowed names and credential boundary are documented in the local file
|
||||
`deploy/secrets/README.md`. Do not put tokens in URLs, the YAML
|
||||
descriptor, the Git repository, or commands copied into the shell.
|
||||
- when the catalog uses pi_auth, the LLM token belongs in the Pi pi-auth.json file created by
|
||||
setup; {} is only a placeholder and does not enable a model;
|
||||
- workspace database credentials (PostgreSQL password, REST API token, tunnel SSH key,
|
||||
known_hosts, CA) do not belong in the workspace repository. Enter them per workspace in
|
||||
Database Management, which stores them encrypted in the Catalog. The workspace declares
|
||||
database/schema and transport; the installer must obtain the actual values from the database owner.
|
||||
|
||||
For SSH workspace access, also provide the private key and `known_hosts` file requested by setup.
|
||||
For HTTPS access, provide the Git credential file and any required CA. Both must remain protected
|
||||
and outside version control.
|
||||
A private workspace repository also needs the Git files required by its transport: an SSH key and
|
||||
known_hosts, or an HTTPS credential file and CA. These are transport files, not a second bundle to
|
||||
commit. To minimize manual files, use SSH with an already-authorized deploy key.
|
||||
|
||||
Before starting, complete these additional configuration steps:
|
||||
## 4. Automatic checks and terminal tests
|
||||
|
||||
1. Add `THT_CATALOG_RUNTIME_PASSWORD_SOURCE` and `THT_CATALOG_MIGRATOR_PASSWORD_SOURCE` to
|
||||
`deploy/local/operator.env`, with the same absolute paths exported above. Setup does not persist
|
||||
these two variables. Store paths, not passwords.
|
||||
2. Replace the descriptor's generic `modelCatalog` with the approved provider/model configuration.
|
||||
The generated defaults do not replicate the existing Mac. See [Pi/model configuration](../general/pi-configuration.md)
|
||||
and the local example `deploy/psd/thothii-installation.yaml.example`.
|
||||
3. Populate the keys referenced by `authentication.apiKeyEnv` in `thothii.secrets`. Providers using
|
||||
`pi_auth` need valid credentials at `PI_AUTH_FILE`; the `{}` template is not authentication.
|
||||
4. Complete the workspace Git files. SSH requires an authorized deploy key and verified known-hosts;
|
||||
HTTPS requires the credential file and CA bundle expected by the overlay. Blank templates cannot
|
||||
provide repository access.
|
||||
Setup verifies files, permissions, descriptor, Compose, Docker, authentication, services, Pi and
|
||||
the workspace. After startup, run these commands at any time:
|
||||
|
||||
After editing generated configuration, do not rerun setup: it rejects different existing content.
|
||||
Generate the projections and run the explicit migration below. Use `THT_GIT_ACCESS=https` if that
|
||||
was selected during setup. This block targets the fresh `local` descriptor with only the Git overlay;
|
||||
custom installations must include their extra descriptor overlays in the same order.
|
||||
~~~
|
||||
INSTALLATION="$PWD/deploy/local/thothii-installation.yaml"
|
||||
tht --installation "$INSTALLATION" doctor --json
|
||||
tht --installation "$INSTALLATION" workspace pull --json
|
||||
tht --installation "$INSTALLATION" workspace test --json
|
||||
~~~
|
||||
|
||||
```bash
|
||||
INSTALLATION="$(pwd -P)/deploy/local/thothii-installation.yaml"
|
||||
tht --installation "$INSTALLATION" installation generate
|
||||
THT_PROJECT="thothii-$(printf '%s' "$INSTALLATION" | shasum -a 256 | cut -c 1-12)"
|
||||
THT_GIT_ACCESS=ssh
|
||||
compose=(
|
||||
docker compose --project-name "$THT_PROJECT" --project-directory "$(pwd -P)"
|
||||
--env-file "$(pwd -P)/deploy/local/operator.env"
|
||||
-f compose.yaml -f deploy/compose.local.yaml
|
||||
-f "deploy/compose.git-$THT_GIT_ACCESS.yaml"
|
||||
-f deploy/local/generated/compose.models.yaml
|
||||
)
|
||||
"${compose[@]}" config --quiet
|
||||
"${compose[@]}" build core frontend
|
||||
"${compose[@]}" up -d catalog-db
|
||||
"${compose[@]}" run --rm catalog-migrate
|
||||
tht --installation "$INSTALLATION" start
|
||||
```
|
||||
workspace test checks, for every active workspace, database binding and credentials, Evidence,
|
||||
Qdrant, and the embedding service. It exits non-zero when the database binding is missing or a
|
||||
connection is unusable. Before running it, the installer must configure the database in Database
|
||||
Management: the workspace repository cannot contain the password by itself.
|
||||
|
||||
Stop if a command fails. The project name matches the hash used by `tht`, preserving volume
|
||||
identity. `catalog-migrate` applies Catalog and Memory migrations; `tht start` does not run it
|
||||
automatically. Initial embedding-model download may take time. Use this installation-specific
|
||||
sequence, not `run-stack.sh` with a different environment/project name.
|
||||
doctor --json is the repeatable, non-destructive core verification. The final functional test must
|
||||
also open http://127.0.0.1:8080, sign in, and complete a real question through final SQL.
|
||||
|
||||
## 4. Verify the installation
|
||||
## Activities only the installer can complete
|
||||
|
||||
The descriptor generated for the default ID is:
|
||||
The procedure automates bootstrap, but it cannot invent enterprise decisions or authorizations.
|
||||
The installer must complete and record:
|
||||
|
||||
```sh
|
||||
INSTALLATION="$(pwd -P)/deploy/local/thothii-installation.yaml"
|
||||
test -f "$INSTALLATION"
|
||||
bash scripts/verify-standalone-install.sh "$INSTALLATION"
|
||||
```
|
||||
1. usable LLMs, the modelCatalog, and linked API keys; then run tht pi test and tht doctor;
|
||||
2. database configuration, connection test, schema synchronization, and description generation;
|
||||
3. human consolidation of generated descriptions;
|
||||
4. Qdrant semantic entries through workspace preprocess run;
|
||||
5. naming-based FK suggestions as a complement to schema FKs, human review, and loading approved
|
||||
relationships into Qdrant;
|
||||
6. recurring tht doctor --json and tht workspace test --json checks;
|
||||
7. one real question completed successfully without connection or model errors.
|
||||
|
||||
The verifier is read-only: it runs `tht doctor --json` and `tht status` without restarting the
|
||||
stack, regenerating configuration, or printing secret contents.
|
||||
Configuration is complete only when all applicable activities are done, decisions are recorded, and
|
||||
the two terminal tests are green. The core is usable only after the real question, not merely
|
||||
because the frontend answers /health.
|
||||
|
||||
### Gate A — platform smoke test on all three computers
|
||||
## Gate A and Gate B
|
||||
|
||||
Record the following for each machine:
|
||||
### Gate A — platform
|
||||
|
||||
```sh
|
||||
~~~
|
||||
uname -a
|
||||
docker version --format '{{.Server.Version}} {{.Server.Arch}}'
|
||||
tht version
|
||||
bash scripts/check-standalone-prerequisites.sh
|
||||
bash scripts/verify-standalone-install.sh "$INSTALLATION"
|
||||
```
|
||||
~~~
|
||||
|
||||
The gate passes when the clone is intact, Docker and Compose are reachable, `tht doctor` is OK, the
|
||||
stack is running, and the frontend responds at the default local URL `http://127.0.0.1:8080`.
|
||||
Doctor also checks workspace and Pi: record their failures separately rather than labeling every
|
||||
failure as a platform problem. Check HTTP readiness with:
|
||||
### Gate B — usability
|
||||
|
||||
```sh
|
||||
curl --fail --silent --show-error http://127.0.0.1:8080/health
|
||||
```
|
||||
|
||||
### Gate B — functional verification
|
||||
|
||||
Run this on at least one machine with available endpoints and credentials:
|
||||
|
||||
First follow [Workspace operations](../operations/workspaces.md) to import/prepare the workspace
|
||||
and configure the Database and local binding. The source clone does not transfer catalog data,
|
||||
secrets or sessions from the Mac. Connect any VPN required by DWH/model endpoints and verify
|
||||
that their names are reachable from containers too.
|
||||
|
||||
1. open `http://127.0.0.1:8080`;
|
||||
2. sign in with the configured local account;
|
||||
3. verify that the configured workspace is readable;
|
||||
4. start a real question and complete the review gates through final SQL;
|
||||
5. stop and restart the installation, then run `verify-standalone-install.sh` again.
|
||||
|
||||
A Gate B failure involving DWH, the LLM provider, workspace Git, or credentials does not by itself
|
||||
prove a Docker portability problem: record the failed endpoint or component separately.
|
||||
|
||||
## Daily lifecycle
|
||||
|
||||
Use the explicit descriptor when more than one installation may be discoverable:
|
||||
|
||||
```sh
|
||||
INSTALLATION="$PWD/deploy/local/thothii-installation.yaml"
|
||||
|
||||
tht --installation "$INSTALLATION" status
|
||||
tht --installation "$INSTALLATION" start
|
||||
tht --installation "$INSTALLATION" start --build
|
||||
tht --installation "$INSTALLATION" logs
|
||||
~~~
|
||||
tht --installation "$INSTALLATION" doctor --json
|
||||
tht --installation "$INSTALLATION" stop
|
||||
```
|
||||
tht --installation "$INSTALLATION" workspace test --json
|
||||
curl --fail --silent --show-error http://127.0.0.1:8080/health
|
||||
~~~
|
||||
|
||||
Use `start --build` after source changes or to rebuild images from the current checkout. `stop`
|
||||
preserves volumes, sessions, the catalog, Pi state, Qdrant data, and the embedding model. Do not
|
||||
use `docker compose down --volumes` during a normal test: it is destructive and removes local data.
|
||||
For upgrades requiring migrations, follow the release runbook before starting the new application.
|
||||
Then run a real question and stop/restart with tht stop and tht start. Do not use docker compose
|
||||
down --volumes: it deletes the Catalog, sessions, Qdrant data and the embedding model.
|
||||
|
||||
## Quick diagnosis
|
||||
|
||||
| Symptom | Check |
|
||||
| Symptom | Action |
|
||||
| --- | --- |
|
||||
| `Docker Engine is not reachable` | start Docker Desktop or the Docker service and rerun `docker info` |
|
||||
| Windows sees Docker but Bash fails | run the guide inside Ubuntu WSL2 and enable that distribution in Docker Desktop |
|
||||
| `tht: command not found` | open a new shell and check `command -v tht`; rerun the bootstrap if needed |
|
||||
| line-ending or executable-script errors | use a clone in the WSL2/Linux filesystem and rerun `bash scripts/...` |
|
||||
| unsupported architecture | check `docker version --format '{{.Server.Arch}}'`; the test requires `amd64` or `arm64` |
|
||||
| missing descriptor or env file | use `deploy/local/...` generated by `tht setup`, not an arbitrary copied file |
|
||||
| healthy stack but workflow failure | check external URLs, the credential bundle, workspace Git, and authentication separately |
|
||||
| data appears missing | check that `down --volumes` was not used; `stop` does not remove volumes |
|
||||
|
||||
## Acceptance checklist
|
||||
|
||||
- [ ] The clone comes from the expected Gitea repository and the revision is recorded.
|
||||
- [ ] Docker Desktop/Engine and Compose v2 are available.
|
||||
- [ ] The runtime reports an allowed architecture.
|
||||
- [ ] `tht` was built from the repository and responds to `tht version`.
|
||||
- [ ] Setup uses `profile: local`, `shell.mode: full`, and `shell.defaultLocale: en`.
|
||||
- [ ] The descriptor, `operator.env`, authentication, and secrets exist only under `deploy/local/`.
|
||||
- [ ] No secret appears in Git, URLs, public YAML, or recorded commands.
|
||||
- [ ] Gate A passes on Apple Silicon macOS, x64 Windows WSL2, and x64 Linux.
|
||||
- [ ] Gate B runs on at least one machine with DWH and LLM available.
|
||||
- [ ] Stop/start and final verification complete without deleting volumes.
|
||||
|
||||
## Out of scope for this release
|
||||
|
||||
The following remain future work:
|
||||
|
||||
- publishing pre-built images on Docker Hub;
|
||||
- reducing prompts through a dedicated non-interactive configuration;
|
||||
- creating DMG, MSI/EXE, AppImage, or other native installers;
|
||||
- providing an offline runtime or bundling a local DWH/LLM into the application.
|
||||
| Docker Engine is not reachable | start Docker Desktop or systemctl and repeat docker info |
|
||||
| Omarchy cannot find docker | install Docker/Compose, enable the service and open a new session |
|
||||
| Windows sees Docker but Bash fails | use Ubuntu WSL2 and enable its Docker Desktop integration |
|
||||
| workspace pull fails | check URL, branch, key/credential file and known_hosts from the container |
|
||||
| workspace test reports a missing binding | configure database, token/password and CA in Database Management |
|
||||
| Pi is not ready | fill pi-auth.json or the key declared by modelCatalog, then run tht pi test |
|
||||
|
||||
## Related documents
|
||||
|
||||
- [Install and first start](first-start.md)
|
||||
- [Shell and localization](../operations/shell-and-localization.md)
|
||||
- [Workspace operations](../operations/workspaces.md)
|
||||
- `deploy/secrets/README.md` (runtime secrets)
|
||||
- [Database Management](../operations/database-management.md)
|
||||
- [Model configuration](../general/pi-configuration.md)
|
||||
- deploy/secrets/README.md
|
||||
|
||||
Publishing images on Docker Hub and native DMG/MSI/AppImage installers remain later work: this
|
||||
procedure starts from the Gitea clone and does not require pre-published Docker Hub images.
|
||||
|
||||
@@ -1,329 +1,262 @@
|
||||
# Installazione manuale standalone
|
||||
# Installazione standalone guidata
|
||||
|
||||
[English version](standalone-manual-en.md)
|
||||
|
||||
Questa è la procedura di prova per predisporre THothII come applicazione autonoma in modalità
|
||||
`full` su macOS, Windows e Linux.
|
||||
Questa è la procedura per installare THothII da zero. THothII riceve una domanda in linguaggio
|
||||
naturale, interroga in sola lettura un database aziendale e accompagna l’utente nella revisione
|
||||
della SQL risultante. Il core, il catalogo PostgreSQL, Qdrant, il servizio di embedding e Pi vengono
|
||||
eseguiti in Docker; sul computer non servono Node.js, Python o Pi.
|
||||
|
||||
In questo documento “autonoma” significa che l’utente non deve installare Node.js, Python o Pi
|
||||
sull'host: i servizi applicativi e i servizi semantici
|
||||
locali vengono eseguiti con Docker. DWH e provider LLM restano endpoint esterni configurati
|
||||
dall’installazione; questa procedura non è un pacchetto offline.
|
||||
## Prima di iniziare: i due repository
|
||||
|
||||
Il percorso non usa installer grafici, launcher nativi o immagini Docker Hub. Si parte da un clone
|
||||
Gitea e si usano comandi espliciti da terminale. La pubblicazione di immagini pre-costruite è una
|
||||
fase successiva.
|
||||
Servono due repository distinti:
|
||||
|
||||
## Matrice di verifica
|
||||
1. il repository dell’applicazione, che l’utente clona:
|
||||
https://git.tylconsulting.it/mptyl/ThothII.git;
|
||||
2. il repository dei workspace, indicato dal curatore/installatore. Non è il repository di
|
||||
THothII e non va clonato manualmente nella directory dell’applicazione.
|
||||
|
||||
| Sistema | Terminale raccomandato | Runtime | Architettura della prova |
|
||||
| --- | --- | --- | --- |
|
||||
| macOS supportato dalla versione Docker Desktop installata | Bash nel Terminale | Docker Desktop | Apple Silicon (`arm64`) |
|
||||
| Windows 11 | Ubuntu dentro WSL2 | Docker Desktop con integrazione WSL2 | x64 (`amd64`) |
|
||||
| Linux Ubuntu 22.04 o 24.04 | Bash | Docker Engine + Compose v2 | x64 (`amd64`) |
|
||||
Il repository workspace contiene il catalogo e una directory per ogni workspace, normalmente:
|
||||
|
||||
Intel macOS non fa parte della prima campagna di verifica. ARM Linux può essere provato quando il
|
||||
runtime Docker della macchina restituisce `arm64`, ma non è un requisito della matrice minima.
|
||||
~~~
|
||||
thoth-workspaces.yaml
|
||||
<workspace-id>/workspace.yaml
|
||||
<workspace-id>/evidence/** # se il workspace dichiara Evidence
|
||||
~~~
|
||||
|
||||
Le verifiche documentali e dei prerequisiti Mac sono passate. Le installazioni complete da zero
|
||||
sui tre sistemi restano da eseguire: la matrice indica le prove previste, non una certificazione.
|
||||
Il file workspace.yaml descrive identità, lingua e, opzionalmente, la sorgente Evidence. Per scelta
|
||||
architetturale non contiene password del database. L’identità del database, il trasporto
|
||||
(PostgreSQL, REST o tunnel), username, password, token e certificati sono configurazione locale
|
||||
dell’installazione, conservata cifrata dal Catalog. Questo evita di committare credenziali nel
|
||||
repository workspace.
|
||||
|
||||
## Cosa serve prima di iniziare
|
||||
## 0. Prerequisiti della macchina
|
||||
|
||||
Servono:
|
||||
### Windows
|
||||
|
||||
- accesso al repository Gitea di THothII e al repository Git dei workspace;
|
||||
- Git;
|
||||
- Docker Desktop su macOS e Windows, oppure Docker Engine con il plugin Compose v2 su Linux;
|
||||
- Bash, `curl`, OpenSSL e `shasum` (su Ubuntu, pacchetto `libdigest-sha-perl`);
|
||||
- spazio disco sufficiente per compilare le immagini e scaricare il modello di embedding;
|
||||
- gli endpoint DWH e LLM, più le credenziali che l’installazione deve usare.
|
||||
- Windows 10/11 con Docker Desktop avviato e backend WSL2 abilitato.
|
||||
- Ubuntu in WSL2, con integrazione Docker Desktop abilitata per quella distribuzione.
|
||||
- Git, Bash, curl, OpenSSL e shasum nella distribuzione WSL2.
|
||||
- Non installare Node.js, Python o Pi sull’host per questa procedura.
|
||||
|
||||
Su Linux l’utente corrente deve poter eseguire Docker. Se il sistema richiede `sudo`, aggiungere
|
||||
l’utente al gruppo Docker secondo la policy locale e aprire una nuova sessione prima di continuare.
|
||||
In PowerShell, se WSL2 non esiste ancora, usare la procedura aziendale oppure:
|
||||
|
||||
Su Windows usare Ubuntu in WSL2 per tutti i comandi di questa guida. In Docker Desktop attivare
|
||||
l’integrazione WSL2 per quella distribuzione. Clonare il progetto nel filesystem Linux di WSL2,
|
||||
per esempio sotto `~/src`, e non sotto `/mnt/c`: si evitano rallentamenti e problemi di permessi o
|
||||
line ending. Non è necessario installare Pi sull’host.
|
||||
~~~
|
||||
wsl --install -d Ubuntu
|
||||
~~~
|
||||
|
||||
Verificare il runtime prima del clone o subito dopo:
|
||||
Eseguire poi tutti i comandi dentro Ubuntu WSL2, in una directory Linux come $HOME/src, non sotto
|
||||
/mnt/c. Il percorso nativo scripts/install-tht.ps1 esiste per scenari PowerShell avanzati; per la
|
||||
prova riproducibile usare WSL2.
|
||||
|
||||
```sh
|
||||
docker version
|
||||
### macOS
|
||||
|
||||
- Docker Desktop installato, avviato e con alcuni GB liberi per immagini e modello di embedding.
|
||||
- Git, Bash, curl, OpenSSL e shasum.
|
||||
- Sono supportati Mac Intel e Apple Silicon se Docker Desktop supporta l’architettura restituita
|
||||
dal Docker server.
|
||||
- Non installare Node.js, Python o Pi sull’host per questa procedura.
|
||||
|
||||
### Linux, incluso Omarchy
|
||||
|
||||
- Git, Bash, curl, OpenSSL e shasum.
|
||||
- Docker Engine e il plugin Docker Compose v2. Su Omarchy verificare prima:
|
||||
|
||||
~~~
|
||||
command -v docker
|
||||
docker compose version
|
||||
docker info
|
||||
~~~
|
||||
|
||||
Se Docker manca, installare Docker e Compose con il gestore pacchetti/procedura approvata dalla
|
||||
distribuzione, poi avviare il servizio. Su una distribuzione Arch-like il percorso tipico è:
|
||||
|
||||
~~~
|
||||
sudo pacman -S docker docker-compose
|
||||
sudo systemctl enable --now docker
|
||||
sudo usermod -aG docker "$USER"
|
||||
~~~
|
||||
|
||||
Dopo l’aggiunta al gruppo aprire una nuova sessione e ripetere docker info. Non installare Node.js,
|
||||
Python o Pi sull’host: sono dentro le immagini Docker.
|
||||
|
||||
Su tutti i sistemi il controllo finale è:
|
||||
|
||||
~~~
|
||||
bash scripts/check-standalone-prerequisites.sh
|
||||
docker version --format '{{.Server.Arch}}'
|
||||
```
|
||||
~~~
|
||||
|
||||
L’ultima istruzione deve restituire `amd64`, `x86_64`, `arm64` o `aarch64`.
|
||||
L’architettura deve essere amd64, x86_64, arm64 o aarch64. Servono inoltre accesso al repository
|
||||
Gitea dell’applicazione, URL/branch e credenziali del repository workspace, raggiungibilità dal
|
||||
container degli endpoint DWH/LLM e le credenziali, token o certificati associati ai database.
|
||||
|
||||
## 1. Clonare una revisione del progetto
|
||||
## 1. Cosa clonare
|
||||
|
||||
Usare il repository di progetto su Gitea:
|
||||
Clonare solo l’applicazione:
|
||||
|
||||
```sh
|
||||
~~~
|
||||
mkdir -p "$HOME/src"
|
||||
cd "$HOME/src"
|
||||
git clone https://git.tylconsulting.it/mptyl/ThothII.git
|
||||
cd ThothII
|
||||
git rev-parse --short HEAD
|
||||
```
|
||||
~~~
|
||||
|
||||
Per un clone SSH usare, se la chiave è già autorizzata su Gitea:
|
||||
Annotare la revisione. Il repository workspace verrà scaricato da tht setup --complete dentro un
|
||||
volume Docker persistente, usando URL, branch e trasporto indicati durante il setup.
|
||||
|
||||
```sh
|
||||
git clone git@git.tylconsulting.it:mptyl/ThothII.git
|
||||
```
|
||||
|
||||
Per una prova ripetibile annotare l’hash stampato da `git rev-parse`. In una campagna successiva
|
||||
usare la revisione/tag approvata dal maintainer invece di seguire implicitamente una `main` che
|
||||
può cambiare.
|
||||
|
||||
## 2. Verificare i prerequisiti e installare il comando operatore
|
||||
## 2. Installare il comando terminale
|
||||
|
||||
Dal root del clone:
|
||||
|
||||
```sh
|
||||
~~~
|
||||
bash scripts/check-standalone-prerequisites.sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
THT_INSTALL_DIRECTORY="$HOME/.local/bin" bash scripts/install-tht.sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
tht version
|
||||
```
|
||||
~~~
|
||||
|
||||
`install-tht.sh` è un bootstrap del solo comando operatore nativo `tht`; non installa una versione
|
||||
desktop di THothII. Usa il builder Docker del repository, installa il binario adatto all’ambiente
|
||||
del terminale e lo installa nella directory utente. Aggiungere `$HOME/.local/bin` al PATH della
|
||||
shell anche per i terminali successivi. Un `tht` già presente in quella directory viene aggiornato.
|
||||
Il comando tht è l’unico componente nativo da installare. Costruisce il binario con Docker e
|
||||
orchestra Compose; non è un secondo runtime dell’applicazione.
|
||||
|
||||
Su Windows, eseguire questi comandi dentro WSL2. Il binario `tht` installato è quello Linux di WSL2;
|
||||
il runtime dell’applicazione rimane Docker Desktop. Non usare `scripts/install-tht.ps1` come percorso
|
||||
principale di questa prova.
|
||||
## 3. Preparare pochi segreti e avviare il setup completo
|
||||
|
||||
## 3. Configurare e avviare l’installazione locale
|
||||
La prima esecuzione crea i placeholder protetti sotto deploy/local/secrets/ e si ferma se manca
|
||||
una credenziale necessaria. Compilare i file indicati e rilanciare lo stesso comando: i file di
|
||||
configurazione già compatibili vengono riutilizzati.
|
||||
|
||||
Eseguire i blocchi successivi nella stessa sessione Bash dal root fisico del clone (`pwd -P`).
|
||||
Creare prima le due password distinte del catalogo, conservando eventuali file già esistenti:
|
||||
~~~
|
||||
tht setup --complete --profile local --shell-mode full --shell-default-locale en
|
||||
~~~
|
||||
|
||||
```bash
|
||||
umask 077
|
||||
mkdir -p deploy/local/secrets
|
||||
for name in catalog-runtime-password catalog-migrator-password; do
|
||||
target="deploy/local/secrets/$name"
|
||||
if [ ! -e "$target" ]; then
|
||||
(set -C; openssl rand -hex 32 > "$target") || exit 1
|
||||
fi
|
||||
done
|
||||
export THT_CATALOG_RUNTIME_PASSWORD_SOURCE="$(pwd -P)/deploy/local/secrets/catalog-runtime-password"
|
||||
export THT_CATALOG_MIGRATOR_PASSWORD_SOURCE="$(pwd -P)/deploy/local/secrets/catalog-migrator-password"
|
||||
```
|
||||
Durante il setup servono solo le informazioni operative che il computer non può conoscere:
|
||||
|
||||
Non rigenerare le password di un catalogo già inizializzato. Configurare senza avviare i servizi:
|
||||
|
||||
```sh
|
||||
tht setup --profile local --shell-mode full --shell-default-locale en --configure-only
|
||||
```
|
||||
|
||||
Rispondere ai prompt nel seguente modo:
|
||||
|
||||
| Prompt | Valore o regola |
|
||||
| Richiesta | Cosa inserire |
|
||||
| --- | --- |
|
||||
| Installation ID | `local`, salvo necessità di più installazioni nello stesso clone |
|
||||
| Deployment profile | `local` |
|
||||
| DWH API endpoint | URL `http(s)` senza user, password, query o fragment; può restare vuoto per il solo smoke test |
|
||||
| LLM API endpoint | URL `http(s)` senza credenziali; può restare vuoto per il solo smoke test |
|
||||
| Workspace repository URL | URL del repository dei workspace, non il clone sorgente di THothII |
|
||||
| Workspace branch | normalmente `main` |
|
||||
| Workspace access | `ssh` se si usa una chiave deploy; altrimenti `https` con credential file protetto |
|
||||
| Percorsi dei file | accettare i percorsi predefiniti sotto `deploy/local/secrets/` nella prima prova |
|
||||
| Secret templates | rispondere `yes` quando i file protetti non esistono ancora |
|
||||
| Autenticazione | configurare il login locale richiesto dall’installazione; non inserire password in una riga di comando |
|
||||
| Repository workspace | URL del repository dati/configurazione, non ThothII.git |
|
||||
| Branch | normalmente main |
|
||||
| Accesso | ssh con chiave e known_hosts, oppure https con credential file e CA |
|
||||
| DWH/LLM URL | endpoint senza token nella URL |
|
||||
| Login locale | utente e password iniziale richiesti dal prompt |
|
||||
|
||||
La configurazione generata è locale e ignorata da Git:
|
||||
Il setup crea automaticamente le password casuali del Catalog e le scrive in operator.env come
|
||||
percorsi, non come valori. Esegue docker compose config, costruisce le immagini, avvia il Catalog,
|
||||
esegue catalog-migrate, avvia lo stack e importa il repository workspace. L’import attiva anche
|
||||
l’Evidence dichiarata: almeno i file source presenti nel workspace vengono materializzati nel
|
||||
registro locale.
|
||||
|
||||
```text
|
||||
deploy/local/thothii-installation.yaml
|
||||
deploy/local/operator.env
|
||||
deploy/local/auth/
|
||||
deploy/local/secrets/
|
||||
```
|
||||
### Il file da compilare
|
||||
|
||||
Modificare i segreti solo nei file locali protetti; non committarli. Il file `deploy/env/local.env.example` è un riferimento
|
||||
tracciato; il percorso generato da `tht setup`, `deploy/local/operator.env`, è quello da usare per
|
||||
questa installazione.
|
||||
Il file principale è:
|
||||
|
||||
### Completare i file protetti
|
||||
~~~
|
||||
deploy/local/secrets/thothii.secrets
|
||||
~~~
|
||||
|
||||
Se il setup ha creato template vuoti, inserire i valori con un editor locale:
|
||||
Inserire solo righe NOME=VALORE necessarie al modelCatalog e agli adapter, per esempio una API key
|
||||
LLM (DEEPSEEK_API_KEY, OPENAI_API_KEY o quella dichiarata dal catalogo) ed eventualmente
|
||||
THT_DWH_API_KEY. I nomi ammessi sono documentati in deploy/secrets/README.md. Non mettere token
|
||||
nelle URL, nel repository o nei comandi.
|
||||
|
||||
```sh
|
||||
chmod 600 deploy/local/secrets/*
|
||||
"${EDITOR:-vi}" deploy/local/secrets/thothii.secrets
|
||||
```
|
||||
Due precisazioni evitano gli errori più comuni:
|
||||
|
||||
Il bundle deve contenere solo righe `KEY=VALUE` per le credenziali effettivamente usate dal
|
||||
`modelCatalog`. I nomi ammessi e il confine delle credenziali sono descritti nel file locale
|
||||
`deploy/secrets/README.md`. Non mettere token nelle URL, nel
|
||||
descriptor YAML, nel repository Git o nei comandi copiati nella shell.
|
||||
- se il catalogo usa pi_auth, il token LLM va nel file Pi pi-auth.json creato dal setup; {} è solo
|
||||
un placeholder e non abilita alcun modello;
|
||||
- le credenziali specifiche di un database workspace (password PostgreSQL, API token REST, chiave
|
||||
SSH del tunnel, known_hosts, CA) non vanno nel repository workspace: si inseriscono per workspace
|
||||
in Database Management, che le conserva nel Catalog cifrato. Il workspace indica database/schema
|
||||
e trasporto; l’installatore deve ottenere dal proprietario il valore corretto.
|
||||
|
||||
Per accesso workspace SSH, predisporre anche la chiave privata e il file `known_hosts` indicati dal
|
||||
setup. Per accesso HTTPS, predisporre il credential file Git e l’eventuale CA. Entrambi devono
|
||||
restare protetti e fuori dal controllo versione.
|
||||
Per un repository workspace privato sono inoltre indispensabili i file Git richiesti dal trasporto:
|
||||
una chiave SSH e known_hosts, oppure credential file HTTPS e CA. Sono file di trasporto, non un
|
||||
secondo bundle da committare. Per ridurre i file da compilare, usare SSH con una deploy key già
|
||||
autorizzata.
|
||||
|
||||
Prima dell'avvio completare anche questi passaggi:
|
||||
## 4. Controlli automatici e test da terminale
|
||||
|
||||
1. Aggiungere `THT_CATALOG_RUNTIME_PASSWORD_SOURCE` e `THT_CATALOG_MIGRATOR_PASSWORD_SOURCE` a
|
||||
`deploy/local/operator.env`, con gli stessi percorsi assoluti esportati sopra. Il setup non salva
|
||||
queste due variabili. Inserire i percorsi, non le password.
|
||||
2. Sostituire il `modelCatalog` generico nel descriptor con la configurazione provider/modelli
|
||||
approvata. I default generati non replicano il Mac esistente. Vedere [configurazione Pi/modelli](../general/pi-configuration.md)
|
||||
e l'esempio locale `deploy/psd/thothii-installation.yaml.example`.
|
||||
3. Inserire in `thothii.secrets` le chiavi referenziate da `authentication.apiKeyEnv`. I provider
|
||||
`pi_auth` richiedono credenziali valide nel file `PI_AUTH_FILE`; il template `{}` non autentica.
|
||||
4. Completare i file Git del workspace. SSH richiede una chiave deploy autorizzata e known-hosts
|
||||
verificato; HTTPS richiede il credential file e il bundle CA previsti dall'overlay. I template
|
||||
vuoti non consentono l'accesso al repository.
|
||||
Il setup verifica file, permessi, descriptor, Compose, Docker, autenticazione, servizi, Pi e
|
||||
workspace. Dopo l’avvio usare questi comandi in qualunque momento:
|
||||
|
||||
Dopo aver modificato la configurazione generata, non rilanciare setup: rifiuta file esistenti con
|
||||
contenuti diversi. Generare le proiezioni ed eseguire la migrazione esplicita indicata sotto.
|
||||
Impostare `THT_GIT_ACCESS=https` se scelto nel setup. Il blocco usa il nuovo descriptor `local`
|
||||
con il solo overlay Git; per installazioni personalizzate includere gli overlay aggiuntivi
|
||||
nello stesso ordine del descriptor.
|
||||
~~~
|
||||
INSTALLATION="$PWD/deploy/local/thothii-installation.yaml"
|
||||
tht --installation "$INSTALLATION" doctor --json
|
||||
tht --installation "$INSTALLATION" workspace pull --json
|
||||
tht --installation "$INSTALLATION" workspace test --json
|
||||
~~~
|
||||
|
||||
```bash
|
||||
INSTALLATION="$(pwd -P)/deploy/local/thothii-installation.yaml"
|
||||
tht --installation "$INSTALLATION" installation generate
|
||||
THT_PROJECT="thothii-$(printf '%s' "$INSTALLATION" | shasum -a 256 | cut -c 1-12)"
|
||||
THT_GIT_ACCESS=ssh
|
||||
compose=(
|
||||
docker compose --project-name "$THT_PROJECT" --project-directory "$(pwd -P)"
|
||||
--env-file "$(pwd -P)/deploy/local/operator.env"
|
||||
-f compose.yaml -f deploy/compose.local.yaml
|
||||
-f "deploy/compose.git-$THT_GIT_ACCESS.yaml"
|
||||
-f deploy/local/generated/compose.models.yaml
|
||||
)
|
||||
"${compose[@]}" config --quiet
|
||||
"${compose[@]}" build core frontend
|
||||
"${compose[@]}" up -d catalog-db
|
||||
"${compose[@]}" run --rm catalog-migrate
|
||||
tht --installation "$INSTALLATION" start
|
||||
```
|
||||
workspace test prova, per ogni workspace attivo, il binding del database e le credenziali, Evidence,
|
||||
Qdrant e il servizio embedding. Restituisce exit code diverso da zero se manca il binding del
|
||||
database o una connessione non è utilizzabile. Prima di eseguirlo l’installatore deve aver
|
||||
configurato il database in Database Management: il workspace repository da solo non può contenere
|
||||
la password.
|
||||
|
||||
Fermarsi se un comando fallisce. Il nome progetto coincide con l'hash usato da `tht`, preservando
|
||||
l'identità dei volumi. `catalog-migrate` applica le migrazioni Catalog e Memory; `tht start` non
|
||||
lo esegue automaticamente. Il primo download del modello embedding può richiedere tempo.
|
||||
Usare questa sequenza legata all'installazione, non `run-stack.sh` con env/progetto diversi.
|
||||
Per una verifica generale del core, doctor --json è il test ripetibile e non distruttivo. Il test
|
||||
funzionale finale deve inoltre aprire http://127.0.0.1:8080, autenticarsi e completare una domanda
|
||||
reale fino alla SQL finale.
|
||||
|
||||
## 4. Verificare l’installazione
|
||||
## Attività che può svolgere solo l’installatore
|
||||
|
||||
Il descriptor generato per l’ID predefinito è:
|
||||
La procedura automatizza il bootstrap, non può inventare decisioni o autorizzazioni aziendali.
|
||||
L’installatore deve completare e registrare:
|
||||
|
||||
```sh
|
||||
INSTALLATION="$(pwd -P)/deploy/local/thothii-installation.yaml"
|
||||
test -f "$INSTALLATION"
|
||||
bash scripts/verify-standalone-install.sh "$INSTALLATION"
|
||||
```
|
||||
1. quali LLM sono utilizzabili, il relativo modelCatalog e le API key collegate; poi eseguire
|
||||
tht pi test e tht doctor;
|
||||
2. per ogni database: configurazione, test connessione, sincronizzazione dello schema e
|
||||
generazione delle descrizioni;
|
||||
3. consolidamento umano delle descrizioni generate;
|
||||
4. generazione delle entry semantiche in Qdrant tramite workspace preprocess run;
|
||||
5. generazione delle FK suggerite dal naming, come complemento alle FK lette dallo schema, revisione
|
||||
umana delle proposte e caricamento delle relazioni approvate in Qdrant;
|
||||
6. verifica periodica con tht doctor --json e tht workspace test --json;
|
||||
7. una domanda reale completata con successo, senza errori di connessione o modello.
|
||||
|
||||
Il verificatore è read-only: esegue `tht doctor --json` e `tht status`, senza ristartare lo stack,
|
||||
rigenerare la configurazione o stampare il contenuto dei segreti.
|
||||
La configurazione è dichiarata completa solo quando tutti i punti applicabili sono stati eseguiti,
|
||||
le decisioni sono state registrate e i due test terminali sono verdi. Il core è dichiarato usabile
|
||||
solo dopo la domanda reale, non perché il frontend risponde a /health.
|
||||
|
||||
### Gate A — smoke di piattaforma, su tutti e tre i computer
|
||||
## Gate A e Gate B
|
||||
|
||||
Registrare per ogni macchina:
|
||||
### Gate A — piattaforma
|
||||
|
||||
```sh
|
||||
~~~
|
||||
uname -a
|
||||
docker version --format '{{.Server.Version}} {{.Server.Arch}}'
|
||||
tht version
|
||||
bash scripts/check-standalone-prerequisites.sh
|
||||
bash scripts/verify-standalone-install.sh "$INSTALLATION"
|
||||
```
|
||||
~~~
|
||||
|
||||
Il gate passa quando il clone è integro, Docker e Compose sono raggiungibili, `tht doctor` è OK,
|
||||
lo stack è avviato e il frontend risponde sulla porta locale predefinita `http://127.0.0.1:8080`.
|
||||
Il doctor controlla anche workspace e Pi: registrare separatamente i loro errori senza attribuire
|
||||
ogni fallimento alla piattaforma. Verificare la disponibilità HTTP con:
|
||||
### Gate B — usabilità
|
||||
|
||||
```sh
|
||||
curl --fail --silent --show-error http://127.0.0.1:8080/health
|
||||
```
|
||||
|
||||
### Gate B — verifica funzionale
|
||||
|
||||
Eseguire almeno su una macchina con endpoint e credenziali disponibili:
|
||||
|
||||
Seguire prima [Workspace operations](../operations/workspaces.md) per importare/preparare il
|
||||
workspace e configurare Database e binding locale. Il clone sorgente non trasferisce catalogo,
|
||||
segreti o sessioni del Mac. Connettere l'eventuale VPN richiesta da DWH/modelli e verificare
|
||||
che i relativi nomi siano raggiungibili anche dai container.
|
||||
|
||||
1. aprire `http://127.0.0.1:8080`;
|
||||
2. autenticarsi con l’account locale configurato;
|
||||
3. verificare che il workspace configurato sia leggibile;
|
||||
4. avviare una domanda reale e completare i gate di revisione fino alla SQL finale;
|
||||
5. fermare e riavviare l’installazione, poi ripetere `verify-standalone-install.sh`.
|
||||
|
||||
Un fallimento del Gate B per DWH, provider LLM, Git workspace o credenziali non dimostra da solo un
|
||||
problema di portabilità Docker: registrare separatamente l’endpoint o il componente fallito.
|
||||
|
||||
## Ciclo di vita quotidiano
|
||||
|
||||
Usare il descriptor esplicito quando più installazioni possono essere scoperte:
|
||||
|
||||
```sh
|
||||
INSTALLATION="$PWD/deploy/local/thothii-installation.yaml"
|
||||
|
||||
tht --installation "$INSTALLATION" status
|
||||
tht --installation "$INSTALLATION" start
|
||||
tht --installation "$INSTALLATION" start --build
|
||||
tht --installation "$INSTALLATION" logs
|
||||
~~~
|
||||
tht --installation "$INSTALLATION" doctor --json
|
||||
tht --installation "$INSTALLATION" stop
|
||||
```
|
||||
tht --installation "$INSTALLATION" workspace test --json
|
||||
curl --fail --silent --show-error http://127.0.0.1:8080/health
|
||||
~~~
|
||||
|
||||
`start --build` è necessario dopo una modifica al codice o per ricostruire le immagini dal clone
|
||||
corrente. `stop` conserva volumi, sessioni, catalogo, stato Pi, dati Qdrant e modello embedding.
|
||||
Non usare `docker compose down --volumes` durante una prova normale: è un’operazione distruttiva
|
||||
che cancella i dati locali.
|
||||
Per aggiornamenti che richiedono migrazioni, seguire il runbook della release prima dell'avvio.
|
||||
Poi eseguire una domanda reale e fermare/riavviare con tht stop e tht start. Non usare docker
|
||||
compose down --volumes: cancella Catalog, sessioni, Qdrant e il modello embedding.
|
||||
|
||||
## Diagnosi rapida
|
||||
|
||||
| Sintomo | Controllo |
|
||||
| Sintomo | Azione |
|
||||
| --- | --- |
|
||||
| `Docker Engine is not reachable` | avviare Docker Desktop oppure il servizio Docker e ripetere `docker info` |
|
||||
| Windows vede Docker ma Bash fallisce | eseguire la guida dentro Ubuntu WSL2 e abilitare l’integrazione della distribuzione in Docker Desktop |
|
||||
| `tht: command not found` | aprire una nuova shell e verificare `command -v tht`; se necessario ripetere il bootstrap |
|
||||
| line ending o script non eseguibile | usare un clone nel filesystem WSL2/Linux e rieseguire `bash scripts/...` |
|
||||
| architettura non supportata | verificare `docker version --format '{{.Server.Arch}}'`; la prova richiede `amd64` o `arm64` |
|
||||
| descriptor o env file mancanti | usare il percorso `deploy/local/...` generato da `tht setup`, non un file copiato casualmente |
|
||||
| stack sano ma workflow fallisce | controllare separatamente URL, credential bundle, workspace Git e autenticazione |
|
||||
| dati apparentemente persi | verificare che non sia stato usato `down --volumes`; `stop` non rimuove i volumi |
|
||||
|
||||
## Checklist di accettazione
|
||||
|
||||
- [ ] Il clone proviene dal repository Gitea atteso e la revisione è stata annotata.
|
||||
- [ ] Docker Desktop/Engine e Compose v2 sono disponibili.
|
||||
- [ ] Il runtime restituisce un’architettura ammessa.
|
||||
- [ ] `tht` è stato costruito dal repository e risponde a `tht version`.
|
||||
- [ ] Il setup usa `profile: local`, `shell.mode: full` e `shell.defaultLocale: en`.
|
||||
- [ ] Descriptor, `operator.env`, autenticazione e segreti sono presenti solo in `deploy/local/`.
|
||||
- [ ] Nessun segreto compare in Git, URL, YAML pubblico o comandi registrati.
|
||||
- [ ] Gate A superato su macOS Apple Silicon, Windows WSL2/x64 e Linux x64.
|
||||
- [ ] Gate B eseguito almeno su una macchina con DWH e LLM disponibili.
|
||||
- [ ] Stop/start e verifica finale completati senza cancellare i volumi.
|
||||
|
||||
## Fuori perimetro di questa release
|
||||
|
||||
Restano attività successive:
|
||||
|
||||
- pubblicare immagini pre-costruite su Docker Hub;
|
||||
- ridurre ulteriormente i prompt tramite una configurazione non interattiva dedicata;
|
||||
- creare pacchetti DMG, MSI/EXE, AppImage o altri installer nativi;
|
||||
- fornire un runtime offline o un DWH/LLM locale incluso nell’applicazione.
|
||||
| Docker Engine is not reachable | avviare Docker Desktop o systemctl e ripetere docker info |
|
||||
| Omarchy non trova docker | installare Docker/Compose, abilitare il servizio e riaprire la sessione |
|
||||
| Windows vede Docker ma Bash fallisce | usare Ubuntu WSL2 e abilitarne l’integrazione in Docker Desktop |
|
||||
| pull workspace fallisce | controllare URL, branch, chiave/credential file e known_hosts dal container |
|
||||
| workspace test segnala binding mancante | configurare database, token/password e CA in Database Management |
|
||||
| Pi non è pronto | compilare pi-auth.json o la chiave dichiarata dal modelCatalog, poi eseguire tht pi test |
|
||||
|
||||
## Documenti collegati
|
||||
|
||||
- [Install and first start](first-start.md)
|
||||
- [Shell and localization](../operations/shell-and-localization.md)
|
||||
- [Workspace operations](../operations/workspaces.md)
|
||||
- `deploy/secrets/README.md` (runtime secrets)
|
||||
- [Installazione e primo avvio](first-start.md)
|
||||
- [Operazioni sui workspace](../operations/workspaces.md)
|
||||
- [Database Management](../operations/database-management.md)
|
||||
- [Configurazione dei modelli](../general/pi-configuration.md)
|
||||
- deploy/secrets/README.md
|
||||
|
||||
La pubblicazione di immagini su Docker Hub e gli installer nativi DMG/MSI/AppImage restano attività
|
||||
successive: questa procedura parte dal clone Gitea e non richiede immagini Docker Hub pre-pubblicate.
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
# Docker installation in the current operating contexts
|
||||
|
||||
Rendering and authentication are independent of these Docker contexts. Explicitly
|
||||
select full/en for the Mac, full/OIDC for an autonomous server, or
|
||||
embedded/upstream for Omics. The same frontend image supports both renderings;
|
||||
generated `config.js` and the host page decide the container, while the backend
|
||||
and trusted proxy decide identity. See [shell configuration and deploy](operations/shell-and-localization.md)
|
||||
and [server portal authentication](install/authentication-upstream.md). Do not
|
||||
apply the standalone server authentication projection to the Omics upstream path.
|
||||
|
||||
ThothII uses one Compose topology:
|
||||
|
||||
- `frontend`
|
||||
- `core`
|
||||
- `catalog-db`
|
||||
- `qdrant`
|
||||
- `embedding`
|
||||
- `embedding-model-init`
|
||||
- `catalog-migrate` (one-shot)
|
||||
|
||||
Qdrant and Ollama embedding are required internal Compose services. Only DWH and the LLM remain
|
||||
external. The fixed model is `qwen3-embedding:0.6b` with 1024 dimensions and cosine distance;
|
||||
`embedding-model-init` prepares it before `core` starts.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
INSTALL["Installation descriptor"] --> CONTEXT{Context}
|
||||
CONTEXT --> LOCAL["Local\nCompose local"]
|
||||
CONTEXT --> SERVER["Server\nCompose server"]
|
||||
CONTEXT --> SESSION["Session server\noperator services"]
|
||||
CONTEXT --> AUTH["Auth runtime\nprojection services"]
|
||||
LOCAL --> BUNDLE["Common secret bundle"]
|
||||
SERVER --> BUNDLE
|
||||
SESSION --> BUNDLE
|
||||
AUTH --> BUNDLE
|
||||
BUNDLE --> SERVICES["Frontend, core, catalog DB, vector, embedding"]
|
||||
```
|
||||
|
||||
## Short ownership contract
|
||||
|
||||
| Componente | Ownership | Contratto operativo |
|
||||
| --- | --- | --- |
|
||||
| DWH | External | External endpoint configured by the installation. |
|
||||
| LLM | External | Endpoint or policy outside the internal semantic infrastructure. |
|
||||
| Qdrant | Internal | Required internal Compose service with persistent `qdrant-data` volume. |
|
||||
| Ollama embedding | Internal | Required internal Compose service for `qwen3-embedding:0.6b`. |
|
||||
|
||||
## Local path: setup, migration, start
|
||||
|
||||
The normal local path is [Install and first start](install/first-start.md). It uses `tht setup`
|
||||
to create the selected installation-local descriptor and runs the catalog migration explicitly
|
||||
before application startup.
|
||||
|
||||
If an operator intentionally prepares the descriptor and protected files by hand, the equivalent
|
||||
foreground launch is:
|
||||
|
||||
```sh
|
||||
cp deploy/env/local.env.example deploy/env/local.env
|
||||
cp deploy/secrets/thothii.secrets.example deploy/secrets/thothii.secrets
|
||||
chmod 600 deploy/secrets/thothii.secrets
|
||||
|
||||
# Copy docs/install/examples/thothii-installation.local.yaml to a protected operator path,
|
||||
# replace every placeholder, chmod it 600, then set that exact path as
|
||||
# THT_INSTALLATION_CONFIG_SOURCE in deploy/env/local.env.
|
||||
|
||||
./scripts/run-stack.sh
|
||||
```
|
||||
|
||||
Set these values in `deploy/env/local.env`:
|
||||
|
||||
- `PI_AUTH_FILE`
|
||||
- `THT_SECRETS_FILE`
|
||||
- `THT_INSTALLATION_CONFIG_SOURCE` (the exact protected host `thothii-installation.yaml`)
|
||||
- `THT_WORKSPACE_GIT_REMOTE`
|
||||
- DWH endpoint
|
||||
- LLM endpoint
|
||||
|
||||
Do not put secrets in `.env`. Runtime secrets belong in the
|
||||
`deploy/secrets/thothii.secrets` bundle.
|
||||
|
||||
## Secret bundle
|
||||
|
||||
The documented and supported bundle keys are:
|
||||
|
||||
```dotenv
|
||||
THT_MODEL_API_KEY=...
|
||||
THT_DWH_API_KEY=...
|
||||
OPENAI_API_KEY=...
|
||||
```
|
||||
|
||||
`THT_MODEL_API_KEY` is available only as an explicitly declared catalog bundle key. A
|
||||
metadata-generation provider references one audited bundle name from `deploy/secrets/README.md`
|
||||
through `modelCatalog.providers.<provider>.authentication.apiKeyEnv`.
|
||||
`apiKeyEnv` may be omitted only for an explicit endpoint that accepts unauthenticated requests;
|
||||
hosted/default endpoints remain keyed.
|
||||
Provider/model/endpoint settings stay in the protected installation descriptor; raw keys do not.
|
||||
|
||||
Compose mounts exactly `THT_INSTALLATION_CONFIG_SOURCE` into `core` as a read-only config and sets
|
||||
the backend-only runtime path `THT_INSTALLATION_CONFIG_FILE` to
|
||||
`/run/thothii-installation/thothii-installation.yaml`. Do not set the runtime path in the host env.
|
||||
Descriptor and bundle changes are loaded only after application restart.
|
||||
|
||||
A private PEM CA remains outside the bundle and must be mounted through a reviewed Compose override.
|
||||
|
||||
## Preprocessing
|
||||
|
||||
Preprocessing runs through the native host CLI and the installation descriptor:
|
||||
|
||||
```sh
|
||||
tht --installation /percorso/assoluto/thothii-installation.yaml \
|
||||
workspace preprocess run --workspace <workspace-id>
|
||||
```
|
||||
|
||||
Per rimuovere soltanto gli indici e gli artifact ricostruibili, preservando Memory e domande risolte:
|
||||
|
||||
```sh
|
||||
tht --installation /percorso/assoluto/thothii-installation.yaml \
|
||||
workspace preprocess clear --workspace <workspace-id>
|
||||
```
|
||||
|
||||
The CLI runs the profile-gated `workspace-maintenance` service. See the
|
||||
[preprocessing contract](contracts/workspace-preprocessing-cli.md) and the
|
||||
[Evidence guide](evidence.md) for details.
|
||||
|
||||
## Server
|
||||
|
||||
For server installations, use the server profile with the session overlay:
|
||||
|
||||
```sh
|
||||
docker compose --env-file deploy/env/server.env \
|
||||
-f compose.yaml -f deploy/compose.server.yaml \
|
||||
-f deploy/compose.session-server.yaml.example up --build -d
|
||||
```
|
||||
|
||||
Also see [Workspace operations](operations/workspaces.md). Server deployment, reverse-proxy,
|
||||
backup, and recovery remain manual-gated operations; do not treat the local profile as a server
|
||||
replacement.
|
||||
@@ -0,0 +1,435 @@
|
||||
# Revisione e bonifica della documentazione
|
||||
|
||||
Data: 15 settembre 2026. Baseline: `6a4634dcf1b1df4ad29510a4da371245abd5c666`.
|
||||
Ambito: 121 Markdown e 23 altri file già presenti in `docs/`, navigazione, collegamenti
|
||||
locali, build e verificatori documentali. Il documento conserva la proposta iniziale
|
||||
e registra sotto l'esecuzione successivamente autorizzata dall'utente. È interno,
|
||||
non una pagina del manuale pubblico.
|
||||
|
||||
## Bonifica eseguita dopo approvazione
|
||||
|
||||
Ritirati 35 file dal working tree: 23 Markdown e 12 artefatti visuali generati
|
||||
(otto PNG, due HTML e due JSON). Recuperabili integralmente dalla revisione
|
||||
`5f3a7f5975b96fae1e1cdd0da08b4d60d41064cc`, precedente a questo intervento,
|
||||
mediante `git show REVISIONE:percorso`. Non eliminata né riscritta la storia Git.
|
||||
|
||||
- Dettagli Compose utili consolidati in [riferimento developer](../operations/compose-reference.md);
|
||||
README rinvia alle sole due procedure manuali IT/EN per installazioni nuove.
|
||||
- M1–M3, E1–E3, X1 e i piani Catalog/model già implementati consolidati nel
|
||||
[record di rilascio](../reports/knowledge-archives-release.md). Test storici non
|
||||
presentati come collaudi attuali; estensioni e accettazioni aperte conservate.
|
||||
- Prompt security assorbito nel PRD, senza approvare il progetto di hardening.
|
||||
- Snapshot di progetto riscritto; overview corretta su Catalog, Memory ed Evidence.
|
||||
- Verificatori auth/DWH e fixture riallineati ai documenti attuali: controlli su
|
||||
permessi, diagnostica, segreti, TLS, separazione dei servizi e link. Le simulazioni
|
||||
del vecchio journal scanner, non più presente nei documenti, non sono conservate
|
||||
come finto collaudo del runtime. Le suite applicative non vengono modificate.
|
||||
- Rimandi Markdown verificati; contratti, ADR (anche superati), progetti con
|
||||
decisioni ancora aperte e runbook/report con rollback o accettazione pendente
|
||||
restano nel repository, esclusi dal sito. Non spostati gate in nuove issue né
|
||||
dichiarati chiusi: lo snapshot corrente li rende espliciti. ADR 0019 conservato
|
||||
senza dedurre dal solo nome che tutte le sue estensioni siano implementate.
|
||||
- Pubblicazione effettiva distinta dal branch `pages`; procedura ripetibile nel
|
||||
[runbook del manuale](../operations/public-docs-publication.md).
|
||||
|
||||
File ritirati (percorsi dalla radice):
|
||||
|
||||
- `docs/architecture/thothii-core-sequence.visual-check.1440x900.dark.png`
|
||||
- `docs/architecture/thothii-core-sequence.visual-check.1440x900.light.png`
|
||||
- `docs/architecture/thothii-core-sequence.visual-check.2048x1320.dark.png`
|
||||
- `docs/architecture/thothii-core-sequence.visual-check.2048x1320.light.png`
|
||||
- `docs/architecture/thothii-core-sequence.visual-check.html`
|
||||
- `docs/architecture/thothii-core-sequence.visual-check.json`
|
||||
- `docs/architecture/thothii-runtime.visual-check.1440x900.dark.png`
|
||||
- `docs/architecture/thothii-runtime.visual-check.1440x900.light.png`
|
||||
- `docs/architecture/thothii-runtime.visual-check.2048x1320.dark.png`
|
||||
- `docs/architecture/thothii-runtime.visual-check.2048x1320.light.png`
|
||||
- `docs/architecture/thothii-runtime.visual-check.html`
|
||||
- `docs/architecture/thothii-runtime.visual-check.json`
|
||||
- `docs/installazione-docker-4-contesti.md`
|
||||
- `docs/plans/2026-08-26-metadata-catalog-from-thothai.md`
|
||||
- `docs/plans/2026-08-28-ai-catalog-description-generation-spec.md`
|
||||
- `docs/plans/2026-08-28-ai-catalog-description-generation.md`
|
||||
- `docs/plans/2026-09-02-installation-model-catalog.md`
|
||||
- `docs/plans/2026-09-08-memory-m1-validation.md`
|
||||
- `docs/plans/2026-09-08-security-hardening-resume-prompt.md`
|
||||
- `docs/plans/2026-09-09-archive-repair-x1-validation.md`
|
||||
- `docs/plans/2026-09-09-evidence-e1-validation.md`
|
||||
- `docs/plans/2026-09-09-evidence-e2-validation.md`
|
||||
- `docs/plans/2026-09-09-evidence-e3-validation.md`
|
||||
- `docs/plans/2026-09-09-memory-m2-validation.md`
|
||||
- `docs/plans/2026-09-09-memory-m3-validation.md`
|
||||
- `docs/research/2026-08-23-legacy-thothai-metadata-capabilities.md`
|
||||
- `docs/research/2026-08-23-postgresql-catalog-deployment-constraints.md`
|
||||
- `docs/research/2026-08-23-thothii-metadata-publication-qdrant-seams.md`
|
||||
- `docs/research/2026-09-07-antigravity-gemini-flash-value.md`
|
||||
- `docs/research/2026-09-07-deepseek-harness-terminal.md`
|
||||
- `docs/research/2026-09-07-omp-codex-zcode.md`
|
||||
- `docs/research/2026-09-07-pi-config-vs-oh-my-pi.md`
|
||||
- `docs/research/2026-09-07-zai-coding-plan-cli-quota.md`
|
||||
- `docs/research/2026-09-07-zed-acp-omp-pi.md`
|
||||
- `docs/research/text-to-sql-products.md`
|
||||
|
||||
Le sezioni successive e l'inventario fotografano la revisione iniziale: la presente
|
||||
sezione prevale per le azioni eseguite. Gli altri ritiri sono rinviati finché non
|
||||
si chiudono i relativi gate; non si cancellano documenti solo perché datati.
|
||||
|
||||
## Esito e modifica applicata
|
||||
|
||||
Il sito confondeva quattro funzioni: manuale del prodotto, riferimento del codice,
|
||||
progettazione e diario delle consegne. Il problema non era soltanto la lunghezza della nav:
|
||||
le pagine non elencate potevano comunque essere generate e indicizzate.
|
||||
|
||||
La configurazione ora pubblica soltanto 20 pagine e cinque asset esplicitamente ammessi.
|
||||
Il resto è escluso da HTML, file copiati e indice di ricerca. Le nuove pagine pubbliche
|
||||
sono `product-overview.md`, `install/shell-and-language.md` e `usage/memory.md`;
|
||||
i documenti tecnici da cui sono state ricavate restano intatti nel repository.
|
||||
Home e `install/first-start.md` sono state riscritte per dare un ingresso univoco.
|
||||
Non è stato cancellato alcun documento della baseline.
|
||||
|
||||
`exclude_docs` nega per default la pubblicazione: aggiungere un file a `docs/` non basta
|
||||
più a metterlo online. La build e la pipeline verificano corrispondenza tra nav ed
|
||||
eccezioni, pagine generate, asset e ricerca. I riferimenti tecnici ancora necessari
|
||||
al lettore rinviano esplicitamente ai sorgenti su Gitea, non a pagine interne del sito.
|
||||
|
||||
**Fuori dal manuale non significa privato.** Il repository ThothII è pubblico: questi
|
||||
file e la cronologia restano leggibili su Gitea. Per riservatezza reale occorrerebbe una
|
||||
decisione separata su repository/accessi e sulla storia già pubblicata. Questa bonifica
|
||||
non modifica autorizzazioni, altri repository o l'installazione applicativa.
|
||||
|
||||
## Tre destinazioni, con regole diverse
|
||||
|
||||
| Destinazione | Contenuto | Regola |
|
||||
| --- | --- | --- |
|
||||
| Manuale pubblico | Prodotto, uso, installazione, configurazione, amministrazione | Descrivere ciò che il lettore può fare oggi; distinguere prerequisiti e limiti verificati. |
|
||||
| Riferimento developer | Architettura, contratti, ADR, test ripetibili, integrazione | Conservare nel repository, fuori da MkDocs; un'autorità per ciascun contratto. |
|
||||
| Lavoro temporaneo o storico | Piani attuati, prompt di ripresa, survey, report di singola consegna | Estrarre decisioni, difetti aperti e rollback ancora necessari; poi ritirare dal working tree con Git come archivio. |
|
||||
|
||||
Un file datato non è automaticamente obsoleto. Un contratto con `v3` nel nome non è
|
||||
automaticamente sostituito da un descriptor v4: sono versioni di oggetti diversi.
|
||||
Un ADR superato conserva il motivo della decisione e il collegamento al successore.
|
||||
|
||||
## Rilievi prioritari, con motivazione
|
||||
|
||||
### 1. Percorsi di installazione concorrenti — corretto per il pubblico
|
||||
|
||||
`install/first-start.md` proponeva ancora setup senza `--configure-only` e avvio con
|
||||
`run-stack.sh`, mentre le guide manuali separano segreti, migrazione e avvio per lo
|
||||
stesso descriptor/progetto. Ora è un punto d'ingresso alle due procedure complete,
|
||||
non una terza ricetta. `installazione-docker-4-contesti.md` rimane interno: consolidarne
|
||||
i dettagli ancora esclusivi in una procedura developer di distribuzione, poi ritirarlo.
|
||||
Anche il percorso rapido nel README va riallineato prima di eliminare quei dettagli.
|
||||
|
||||
### 2. Ricerca architetturale presentata come stato corrente — ritirare dopo estrazione
|
||||
|
||||
`research/2026-08-23-thothii-metadata-publication-qdrant-seams.md` dichiara ancora il
|
||||
passaggio catalog-to-core «deferred» e descrive `annotations.yaml` come input corrente.
|
||||
ADR 0016 e gli attuali contratti registrano invece PostgreSQL come autorità per i
|
||||
consumatori del core. Non usarlo per implementare nuovi comportamenti.
|
||||
|
||||
`research/2026-08-23-postgresql-catalog-deployment-constraints.md` dichiara esplicitamente
|
||||
di essere parzialmente superato da ADR 0004. L'inventario legacy ThothAI del 23 agosto
|
||||
è esplicitamente storico. Estrarre soltanto vincoli non già presenti in ADR/contratti;
|
||||
poi eliminare i tre file dal working tree, conservandoli nella storia Git.
|
||||
|
||||
### 3. Decisioni correnti distribuite tra troppi piani — consolidare prima di eliminare
|
||||
|
||||
Per Memory/Evidence convivono piani di famiglia, M1, amministrazione comune, revisione
|
||||
di semplificazione e sette resoconti M1–M3/E1–E3/X1. Conservare gli invarianti nei
|
||||
contratti e gli scenari ripetibili in `testing/`; trasferire i gate non chiusi in issue.
|
||||
Solo dopo si possono ritirare piani e validazioni di incremento.
|
||||
|
||||
`adr/0019-author-evidence-in-app-with-automatic-activation.md` ha un nome che suggerisce
|
||||
editor in-app e attivazione automatica, ma il titolo descrive editor esterni e
|
||||
consolidamento manuale. Contiene anche «Implementation is pending»: non è un affidabile
|
||||
indicatore dello stato di tutte le parti della release. Conservare numero/decisione,
|
||||
correggere metadati e rimandi e distinguere eventuali estensioni ancora pendenti.
|
||||
|
||||
### 4. Report operativi e piani con stato non aggiornato — non cancellare in blocco
|
||||
|
||||
Il report `2026-09-12-ui-visual-review-delivery.md` apre con «non integrata in main»;
|
||||
le integrazioni successive sono documentate altrove. I piani full-shell dicono ancora
|
||||
«deploy server non eseguito», mentre esistono report di rilascio server del 14 settembre.
|
||||
Ciò prova che lo stato è distribuito, non che tutti i collaudi siano conclusi.
|
||||
|
||||
Consolidare report UI del 12–13 settembre in un record di rilascio per versione.
|
||||
Non ritirare i report del 14 settembre né i runbook di upgrade finché rollback,
|
||||
accettazione interattiva e finestra di osservazione non risultano chiusi dall'operatore.
|
||||
`server-handoff-260906-preprocessing-complete.md` va confrontato con il runbook corrente
|
||||
`server-codex-handoff.md`: estrarre eventuali passaggi di preprocessing esclusivi prima
|
||||
di ritirare la consegna datata.
|
||||
|
||||
### 5. Ricerca su strumenti personali estranea al manuale — candidata all'eliminazione
|
||||
|
||||
I sei confronti CLI/editor/provider del 7 settembre (Antigravity, DeepSeek/CyberArk,
|
||||
OMP/Codex/ZCode, Pi/Oh My Pi, quota Z.ai e Zed/ACP) non spiegano un contratto di ThothII.
|
||||
Prezzi, quote e confronti non sono stati riverificati in questa revisione. Proposta:
|
||||
toglierli dal repository del prodotto, mantenendoli in Git o trasferendoli, su scelta
|
||||
del proprietario, a una raccolta personale. Stessa destinazione proposta per
|
||||
`research/text-to-sql-products.md`, che è una ricognizione di mercato.
|
||||
|
||||
Non applicare automaticamente questa regola alla ricerca ERD, relationship e
|
||||
classificatore sensibile: prima verificare se documenta decisioni ancora aperte.
|
||||
|
||||
### 6. Controlli e snapshot già disallineati — debito da correggere
|
||||
|
||||
Due verificatori falliscono su file già assenti nella baseline, non per l'esclusione
|
||||
da MkDocs introdotta qui:
|
||||
|
||||
- `scripts/auth-docs-smoke.sh`: manca `docs/install/local.md`.
|
||||
- `scripts/verify-dwh-auth-docs.sh`: manca `docs/operations/psd-dwh-auth-rollout.md`.
|
||||
|
||||
Le relative suite di fixture conservano la vecchia struttura. Non ricreare documenti
|
||||
obsoleti per far passare i test: aggiornare i controlli ai contratti attuali, mantenendo
|
||||
le verifiche su segreti, modalità di autenticazione e TLS. Questo riallineamento è
|
||||
proposto, non eseguito in questa bonifica editoriale.
|
||||
|
||||
`PROJECT_STATE.md` cita nove percorsi `docs/*.md` non più esistenti, fra cui il programma
|
||||
server PSD del 20 agosto, l'accettazione Evidence del 25 agosto e il rollout dwh-auth.
|
||||
Inoltre accumula consegne anziché restare uno snapshot breve. Riscriverlo come stato
|
||||
attuale, gate aperti e rimandi esistenti. I normali link Markdown relativi dei documenti
|
||||
esistenti non presentano target mancanti nella verifica eseguita: i riferimenti rotti
|
||||
qui citati sono anche percorsi in backtick o imposti dagli script.
|
||||
|
||||
## Proposta operativa in ordine
|
||||
|
||||
0. **Collegare il sito servito al risultato della pipeline:** il controllo remoto descritto
|
||||
sotto ha rilevato una copia statica vecchia. Prima di dichiarare la bonifica online,
|
||||
aggiornare il percorso di pubblicazione sul server con accesso amministrativo verificato.
|
||||
1. **Separazione pubblica:** applicata; niente cancellazioni di sorgenti.
|
||||
2. **Riallineare le autorità:** snapshot, verificatori, ADR 0019, README e stato delle
|
||||
consegne; spostare gate aperti in issue senza marcarli completati.
|
||||
3. **Ritiro a basso rischio, previa approvazione:** confronti personali, ricerca già
|
||||
esplicitamente superata, prompt di ripresa dopo assorbimento nel PRD, output visuali
|
||||
rigenerabili. Controllare prima i riferimenti in tutto il repository.
|
||||
4. **Consolidamento:** piani completati e report incrementali; non perdere criteri di
|
||||
accettazione, problemi aperti, provenienza delle immagini e rollback ancora validi.
|
||||
5. **Riorganizzazione eventuale:** `docs/` per il pubblico, `developer-docs/` per
|
||||
architettura/contratti/ADR/testing, `project-notes/` per lavoro in corso. È un secondo
|
||||
intervento: aggiornare insieme tutti i link in README, AGENTS, CONTEXT, script e codice.
|
||||
|
||||
Per ogni ritiro usare un commit dedicato con motivazione e documento sostitutivo.
|
||||
Non creare una cartella `archive/` piena di copie obsolete: la cronologia Git è già
|
||||
l'archivio, salvo una necessità operativa o di conservazione esplicita.
|
||||
|
||||
## Inventario e destinazione proposta
|
||||
|
||||
L'inventario seguente distingue l'azione proposta dalla sola esclusione già applicata
|
||||
al sito. «Consolidare» e «ritirare» non indicano cancellazioni eseguite.
|
||||
|
||||
<!-- inventory:start -->
|
||||
| File (relativo a `docs/`) | Destinazione | Azione proposta |
|
||||
| --- | --- | --- |
|
||||
| `adr/0001-postgres-metadata-catalog.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0002-workspace-database-secret-references.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0003-installation-local-database-bindings.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0004-fastify-kysely-metadata-catalog.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0005-hard-delete-catalog-tables-during-synchronization.md` | Developer | Conservare ADR superato e catena dei successori; non eliminarlo. |
|
||||
| `adr/0006-separate-physical-and-logical-relationships.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0007-durable-authoritative-schema-synchronization.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0008-allow-manual-catalog-metadata-cleanup.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0009-use-one-sequential-description-generation-run.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0010-allow-bounded-real-source-samples-for-description-generation.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0011-gate-source-samples-with-a-sensitive-data-flag.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0012-use-the-catalog-as-the-logical-relationship-authority.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0013-use-one-installation-model-catalog-with-runtime-projections.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0014-assess-sensitive-columns-locally-from-source-content.md` | Developer | Conservare ADR superato e catena dei successori; non eliminarlo. |
|
||||
| `adr/0015-use-progressive-sampling-for-sensitive-columns.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0016-use-postgres-metadata-for-all-core-consumers.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0017-separate-reference-vectors-from-runtime-memory.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0018-use-postgres-for-memory-and-qdrant-for-retrieval.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0019-author-evidence-in-app-with-automatic-activation.md` | Developer | Conservare; allineare nome/stato alla decisione manuale effettiva. |
|
||||
| `adr/0020-unify-administration-pages-and-use-namespaced-routes.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0021-separate-shell-modes-and-replaceable-portal-adapter.md` | Developer | Conservare decisione architetturale. |
|
||||
| `adr/0022-separate-ui-locale-from-session-interaction-language.md` | Developer | Conservare decisione architetturale. |
|
||||
| `agents/domain.md` | Developer | Conservare regole di contribuzione/agenti, fuori dal sito. |
|
||||
| `agents/issue-tracker.md` | Developer | Conservare regole di contribuzione/agenti, fuori dal sito. |
|
||||
| `agents/triage-labels.md` | Developer | Conservare regole di contribuzione/agenti, fuori dal sito. |
|
||||
| `architecture/application-shell.md` | Developer | Conservare riferimento corrente; distinguere il prodotto dalla struttura del codice. |
|
||||
| `architecture/authentication.md` | Developer | Conservare riferimento corrente; distinguere il prodotto dalla struttura del codice. |
|
||||
| `architecture/components.md` | Developer | Conservare riferimento corrente; distinguere il prodotto dalla struttura del codice. |
|
||||
| `architecture/overview.md` | Developer | Conservare riferimento corrente; distinguere il prodotto dalla struttura del codice. |
|
||||
| `architecture/thothii-core-sequence.html` | Developer/build | Conservare sorgente/diagramma tecnico; non pubblicare nel manuale. |
|
||||
| `architecture/thothii-core-sequence.visual-check.1440x900.dark.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-core-sequence.visual-check.1440x900.light.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-core-sequence.visual-check.2048x1320.dark.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-core-sequence.visual-check.2048x1320.light.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-core-sequence.visual-check.html` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-core-sequence.visual-check.json` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-core.sequence.json` | Developer/build | Conservare sorgente/diagramma tecnico; non pubblicare nel manuale. |
|
||||
| `architecture/thothii-runtime.architecture.json` | Developer/build | Conservare sorgente/diagramma tecnico; non pubblicare nel manuale. |
|
||||
| `architecture/thothii-runtime.html` | Developer/build | Conservare sorgente/diagramma tecnico; non pubblicare nel manuale. |
|
||||
| `architecture/thothii-runtime.visual-check.1440x900.dark.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-runtime.visual-check.1440x900.light.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-runtime.visual-check.2048x1320.dark.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-runtime.visual-check.2048x1320.light.png` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-runtime.visual-check.html` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `architecture/thothii-runtime.visual-check.json` | Transitorio | Ritirare output QA rigenerabili dopo conferma che non siano baseline uniche. |
|
||||
| `contracts/archive-repair.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `contracts/catalog-schema-snapshot.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `contracts/curated-evidence-v4.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `contracts/portal-shell-adapter-v1.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `contracts/tht-dwh.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `contracts/workspace-evidence-v3.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `contracts/workspace-preprocessing-cli.md` | Developer | Conservare contratto e versioni semantiche; aggiornare insieme a codice/test. |
|
||||
| `disambiguazione-iniziale.md` | Developer | Conservare invarianti di gate/ledger; il percorso utente è in skills.md. |
|
||||
| `evidence.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `general/pi-configuration.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `gestione-memory.md` | Developer | Conservare contratto di Memory; istruzioni pubbliche in usage/memory.md. |
|
||||
| `guida-utente.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `index.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/authentication-local.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/authentication-oidc.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/authentication-upstream.md` | Developer/integratore | Conservare integrazione e confine di fiducia; guida pubblica separata. |
|
||||
| `install/authentik.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/dwh-auth-client-enrollment.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/dwh-auth-server.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/dwh-auth-tls.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/examples/thothii-installation.local.yaml` | Asset pubblico | Conservare asset o esempio operativo. |
|
||||
| `install/examples/thothii-installation.server.yaml` | Asset pubblico | Conservare asset o esempio operativo. |
|
||||
| `install/examples/workspace-bindings.env.example` | Asset pubblico | Conservare asset o esempio operativo. |
|
||||
| `install/first-start.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/standalone-manual-en.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `install/standalone-manual-it.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `installazione-docker-4-contesti.md` | Misto/transitorio | Estrarre dettagli server unici, poi ritirare la ricetta duplicata. |
|
||||
| `javascripts/layout-init.js` | Asset pubblico | Conservare asset o esempio operativo. |
|
||||
| `operations/database-management.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `operations/docker-refresh.md` | Operazioni interne | Conservare finché descrive il contesto locale attivo; poi consolidare il lifecycle. |
|
||||
| `operations/sensitivity-analysis.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `operations/server-codex-handoff.md` | Operazioni interne | Conservare runbook finché migrazione e rollback sono operativamente necessari. |
|
||||
| `operations/server-handoff-260906-preprocessing-complete.md` | Operazioni/transitorio | Confrontare con server-codex-handoff, assorbire passaggi unici, poi ritirare. |
|
||||
| `operations/server-upgrade-gitea-workspace-v2.md` | Operazioni interne | Conservare runbook finché migrazione e rollback sono operativamente necessari. |
|
||||
| `operations/shell-and-localization.md` | Developer/integratore | Conservare integrazione e confine di fiducia; guida pubblica separata. |
|
||||
| `operations/workspaces.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `plans/2026-08-26-metadata-catalog-from-thothai.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-08-28-ai-catalog-description-generation-spec.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-08-28-ai-catalog-description-generation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-02-installation-model-catalog.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-evidence-management.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-memory-evidence-administration.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-memory-evidence-simplification-review.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-memory-m1-spec.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-memory-m1-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-memory-management.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-08-security-hardening-prd.md` | Progetto attivo | Conservare PRD aperto; risolvere decisioni/issue prima del ritiro. |
|
||||
| `plans/2026-09-08-security-hardening-resume-prompt.md` | Transitorio | Ritirare dopo trasferimento di istruzioni e questioni aperte nel PRD/issue. |
|
||||
| `plans/2026-09-09-archive-repair-x1-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-09-evidence-e1-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-09-evidence-e2-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-09-evidence-e3-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-09-memory-m2-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-09-memory-m3-validation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-10-administration-pages-spec.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-13-full-shell-and-portal-integration.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-13-full-shell-spec.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/2026-09-14-manual-standalone-installation.md` | Progetto attivo | Conservare fino alla verifica su tre piattaforme; poi assorbire gate e ritirare. |
|
||||
| `plans/administration-pages/01-navigation.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/administration-pages/02-workspace-readiness.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/administration-pages/03-workbench-family.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `plans/administration-pages/04-embedded-acceptance.md` | Progetto/transitorio | Consolidare invarianti in contratti e gate in issue/test; poi ritirare piano o resoconto. |
|
||||
| `reports/2026-09-02-psd-sensitivity-shadow.md` | Developer/benchmark | Conservare risultati aggregati come evidenza versionata, non garanzia corrente. |
|
||||
| `reports/2026-09-02-sensitivity-ner-license-inventory.md` | Developer/release | Conservare provenienza licenze della release; rigenerare quando cambiano le dipendenze. |
|
||||
| `reports/2026-09-03-psd-progressive-sensitivity-shadow.md` | Developer/benchmark | Conservare risultati aggregati come evidenza versionata, non garanzia corrente. |
|
||||
| `reports/2026-09-12-admin-issues-28-31.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-12-context-shelf-a-implementation.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-12-ui-survey-and-graphic-revision-plan.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-12-ui-visual-review-delivery.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-12-unified-interaction-model.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-13-full-shell-implementation.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-13-header-layout-refinements.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-13-knowledge-reading.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-13-knowledge-typography.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-13-shell-simplification-review.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-13-visual-shell-integration.md` | Progetto/transitorio | Consolidare in record di release; ritirare solo dopo trasferimento gate/rollback utili. |
|
||||
| `reports/2026-09-14-session-dialogs-release.md` | Operazioni/release | Conservare finché accettazione, osservazione e rollback non sono chiusi. |
|
||||
| `reports/2026-09-14-session-layout-memory-fix.md` | Operazioni/release | Conservare finché accettazione, osservazione e rollback non sono chiusi. |
|
||||
| `requirements.lock` | Developer/build | Conservare dipendenze e lock; esclusi dal sito. |
|
||||
| `requirements.txt` | Developer/build | Conservare dipendenze e lock; esclusi dal sito. |
|
||||
| `research/2026-08-23-legacy-thothai-metadata-capabilities.md` | Storico/superato | Estrarre vincoli non assorbiti da ADR/contratti, poi ritirare. |
|
||||
| `research/2026-08-23-postgresql-catalog-deployment-constraints.md` | Storico/superato | Estrarre vincoli non assorbiti da ADR/contratti, poi ritirare. |
|
||||
| `research/2026-08-23-thothii-metadata-publication-qdrant-seams.md` | Storico/superato | Estrarre vincoli non assorbiti da ADR/contratti, poi ritirare. |
|
||||
| `research/2026-08-31-browser-erd-library-options.md` | Developer/ricerca | Verificare decisioni ancora aperte; assorbire conclusioni in issue/ADR, poi ritirare. |
|
||||
| `research/2026-08-31-relationship-management-thothai-to-thothii.md` | Developer/ricerca | Verificare decisioni ancora aperte; assorbire conclusioni in issue/ADR, poi ritirare. |
|
||||
| `research/2026-09-02-local-sensitive-column-classifier-libraries.md` | Developer/ricerca | Verificare decisioni ancora aperte; assorbire conclusioni in issue/ADR, poi ritirare. |
|
||||
| `research/2026-09-07-antigravity-gemini-flash-value.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `research/2026-09-07-deepseek-harness-terminal.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `research/2026-09-07-omp-codex-zcode.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `research/2026-09-07-pi-config-vs-oh-my-pi.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `research/2026-09-07-zai-coding-plan-cli-quota.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `research/2026-09-07-zed-acp-omp-pi.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `research/text-to-sql-products.md` | Fuori prodotto | Proposta di ritiro dal working tree; Git o raccolta personale su scelta del proprietario. |
|
||||
| `skills.md` | Pubblico | Conservare; istruzioni di prodotto/operatore. |
|
||||
| `stylesheets/extra.css` | Asset pubblico | Conservare asset o esempio operativo. |
|
||||
| `testing/2026-08-29-ai-catalog-description-generation-acceptance.md` | Developer/QA | Conservare criteri ripetibili e gate; separare risultati di singola release. |
|
||||
| `testing/2026-08-31-metadata-privacy-description-test-plan.md` | Developer/QA | Conservare scenari; ridurre duplicazioni e distinguere test proposti da eseguiti. |
|
||||
| `testing/authentication-manual-acceptance.md` | Developer/QA | Conservare criteri ripetibili e gate; separare risultati di singola release. |
|
||||
| `testing/evidence-lifecycle-test-plan.md` | Developer/QA | Conservare criteri ripetibili e gate; separare risultati di singola release. |
|
||||
<!-- inventory:end -->
|
||||
|
||||
## Verifica iniziale, prima dell'esecuzione dei ritiri
|
||||
|
||||
- Build MkDocs con `--strict` e dipendenze bloccate: superata.
|
||||
- Verifica confine pubblico: 20 pagine, nessun file interno generato o indicizzato.
|
||||
- Otto fixture positive/negative del confine pubblico: superate.
|
||||
- Suite corrente installazione/workspace: superata.
|
||||
- Due verificatori legacy: fallimenti preesistenti descritti sopra; non dichiarati verdi.
|
||||
- Nessuna certificazione di nuova installazione o nuovo collaudo applicativo.
|
||||
|
||||
La pubblicazione remota va verificata separatamente dalla build locale: il ramo sorgente
|
||||
`main`, il ramo generato `pages` e il sito servito non sono la stessa prova.
|
||||
|
||||
### Primo esito remoto del 15 settembre 2026 — diagnosi storica
|
||||
|
||||
Il commit `043ffdfa` è stato pubblicato su `main`. La
|
||||
[pipeline 122](https://git.tylconsulting.it/mptyl/ThothII/actions/runs/122) è terminata
|
||||
con successo e il ramo `pages` contiene 20 pagine pubbliche, senza pagine interne
|
||||
nell'indice di ricerca verificato anonimamente.
|
||||
|
||||
L'URL `https://git.tylconsulting.it/thothii-docs/` serve però ancora la home precedente,
|
||||
con `Last-Modified: Wed, 26 Aug 2026 09:00:07 GMT`; il suo indice di ricerca include
|
||||
ancora architettura e contratti. La richiesta senza cache restituisce lo stesso risultato.
|
||||
Nel repository la pipeline aggiorna soltanto il ramo `pages`: non è documentato il
|
||||
collegamento alla directory effettivamente servita dal web server.
|
||||
|
||||
Il tentativo SSH in sola lettura con la configurazione locale non è proseguito:
|
||||
manca una host key ED25519 conosciuta per `git.tylconsulting.it`. Non è stata disabilitata
|
||||
la verifica dell'identità del server. Servono host/alias amministrativo verificato e
|
||||
percorso o meccanismo di pubblicazione prima di intervenire sul sito effettivo.
|
||||
Al momento di quella verifica la copia servita restava da aggiornare. L'accesso è
|
||||
stato poi risolto usando l'alias SSH già configurato e fidato `contabo`; nessuna
|
||||
host key è stata aggirata.
|
||||
|
||||
## Verifica della bonifica eseguita
|
||||
|
||||
- Build MkDocs strict e confine pubblico: superati, 20 pagine.
|
||||
- Otto fixture del confine pubblico: superate.
|
||||
- Contratti auth/DWH correnti e relative fixture di mutazione: superati.
|
||||
- Suite installazione/workspace, Compose canonico e contratto comandi deployment: superate.
|
||||
- Link Markdown locali di README, PROJECT_STATE e tutti i documenti: nessun target mancante.
|
||||
- `git diff --check`: superato.
|
||||
- `test-no-deployment-coupling.sh`: resta rosso su rilievi preesistenti relativi
|
||||
a contenuti locali PSD e route Omics. Eseguita anche la versione dello script
|
||||
precedente alla bonifica: stesso esito e identico insieme di rilievi, nessuno nuovo.
|
||||
Non è un collaudo del sito e non è stato indebolito per nascondere i risultati.
|
||||
- Nessuna nuova certificazione applicativa, modifica del runtime o chiusura di
|
||||
collaudi reali. I gate elencati nello snapshot restano espliciti.
|
||||
|
||||
## Pubblicazione effettiva completata — 15 settembre 2026
|
||||
|
||||
- Sorgente: `4ff91e8d6e771545bc3d8e7a0ac0b027ef66ba14`, pubblicata su `main`.
|
||||
- [Pipeline 124](https://git.tylconsulting.it/mptyl/ThothII/actions/runs/124):
|
||||
completata con successo, inclusi i nuovi controlli auth/DWH e pubblicazione `pages`.
|
||||
- Release servita: `/srv/thothii-docs/releases/20260915T123738Z-4ff91e8d`.
|
||||
Il symlink `current` punta a questa release; ricreato soltanto `thothii-docs`.
|
||||
- Configurazione nginx copiata identica; container healthy. Confronto degli ID
|
||||
dei container prima/dopo: nessun altro container ricreato o fermato.
|
||||
- Verifica anonima HTTP: home, ricerca e guide manuali IT/EN rispondono 200.
|
||||
SHA-256 di home e indice remoto identici alla build locale; ricerca: 20 pagine,
|
||||
nessuna interna.
|
||||
- Campioni interni `architecture/overview/`, `plans/2026-09-08-memory-management/`
|
||||
e `operations/compose-reference/`: HTTP 404.
|
||||
- Release precedente `releases/20260826T090022Z-e910c7d` conservata per rollback;
|
||||
nessuna vecchia release cancellata. Pubblicazioni future richiedono il passaggio
|
||||
esplicito del runbook, non il solo push di `main`.
|
||||
|
||||
Il precedente blocco sulla copia statica obsoleta è quindi risolto.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Compose reference for maintainers
|
||||
|
||||
This is an internal topology reference, not a second fresh-installation recipe. Operators
|
||||
start with the [Italian](../install/standalone-manual-it.md) or
|
||||
[English](../install/standalone-manual-en.md) manual. It replaces the duplicated four-context
|
||||
Docker guide without changing the runtime.
|
||||
|
||||
The base topology contains frontend, core, catalog-db, qdrant, embedding, embedding-model-init,
|
||||
catalog-migrate and profile-gated workspace-maintenance. Pi runs in core; DWH and generative
|
||||
model endpoints remain installation settings. Reference preprocessing and Memory have distinct
|
||||
lifecycles and collections. See [preprocessing](../contracts/workspace-preprocessing-cli.md).
|
||||
|
||||
## Configuration and migration boundaries
|
||||
|
||||
- Use one physical absolute installation descriptor path, its generated operator environment,
|
||||
Compose project name, base/profile overlays, transport overlays and generated model overlay.
|
||||
Mixing a generic `deploy/env/local.env` invocation with a native `tht` installation creates
|
||||
a different stack; it is not an equivalent lifecycle command.
|
||||
- `THT_INSTALLATION_CONFIG_SOURCE` identifies the protected host descriptor. The read-only
|
||||
backend runtime mount is `/run/thothii-installation/thothii-installation.yaml`, exposed through
|
||||
`THT_INSTALLATION_CONFIG_FILE`; the runtime path is not a host source path.
|
||||
- Catalog runtime/migrator passwords and provider credentials are protected files. A provider's
|
||||
`authentication.apiKeyEnv` names an allowed bundle entry; it is not a raw key. Private CAs
|
||||
are separately mounted PEM files, not bundle values. See the repository's
|
||||
`deploy/secrets/README.md` and the [model catalog guide](../general/pi-configuration.md).
|
||||
- Generate projections after descriptor edits. Do not edit generated model/auth/frontend files.
|
||||
Apply the installation's normal restart process when authored configuration changes.
|
||||
- Explicitly start catalog-db and run catalog-migrate before application rollout on a fresh
|
||||
database or after an approved schema update. That service runs Catalog and Memory migrations;
|
||||
neither normal backend startup nor `tht start` implicitly performs them.
|
||||
- Server deployments retain their reviewed session/auth/network/storage overlays. A writable
|
||||
server Pi-state parent must be initialized with the regular targets expected by the read-only
|
||||
nested mounts; use `scripts/prepare-server-pi-state.sh` with the installation's verified UID/GID.
|
||||
|
||||
## Deployment-specific authority
|
||||
|
||||
For the prepared generic server environment, the base/profile/session override
|
||||
combination is `-f compose.yaml -f deploy/compose.server.yaml
|
||||
-f deploy/compose.session-server.yaml.example`, with `--env-file` supplied before
|
||||
the overrides. Add the reviewed transport/generated overlays for that installation;
|
||||
this fragment alone is not a complete startup command.
|
||||
|
||||
The current [server handoff](server-codex-handoff.md) and
|
||||
[legacy upgrade runbook](server-upgrade-gitea-workspace-v2.md) retain maintenance, backup and
|
||||
rollback gates. Embedded/upstream identity is not standalone OIDC. Local/standalone setup
|
||||
does not authorize replacing a running server stack, resetting volumes, or copying another
|
||||
machine's descriptor. `scripts/run-stack.sh` remains a low-level path for an explicitly
|
||||
prepared generic environment, not the public manual's default startup command.
|
||||
@@ -67,7 +67,7 @@ SSH uses a private key, optional key passphrase, mandatory `known_hosts`, and op
|
||||
TLS CA/server name. REST prefers `POST /rpc/schema_snapshot`; when it is absent, the catalog may
|
||||
use the same strict v1 snapshot through one read-only `POST /rpc/run_query`. An unavailable
|
||||
capability, malformed snapshot, or connector error applies no catalog changes. See the
|
||||
[schema snapshot contract](../contracts/catalog-schema-snapshot.md).
|
||||
[schema snapshot contract](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/catalog-schema-snapshot.md).
|
||||
|
||||
## Synchronize authoritative schema metadata
|
||||
|
||||
@@ -176,6 +176,6 @@ atomic operation. It skips empty generated descriptions, reports aggregate copie
|
||||
counts, and retains the generated text. Because this can replace reviewed descriptions, the
|
||||
interface requires explicit confirmation before applying it.
|
||||
|
||||
The decisions behind this surface are [ADRs 0001–0011](../adr/0001-postgres-metadata-catalog.md)
|
||||
The decisions behind this surface are [ADRs 0001–0011](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/adr/0001-postgres-metadata-catalog.md)
|
||||
and the detailed acceptance record is
|
||||
[AI catalog description generation acceptance](../testing/2026-08-29-ai-catalog-description-generation-acceptance.md).
|
||||
[AI catalog description generation acceptance](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/testing/2026-08-29-ai-catalog-description-generation-acceptance.md).
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# Publishing the public manual
|
||||
|
||||
This is an internal operator runbook. Publishing documentation must not recreate
|
||||
the ThothII application, Gitea, proxy, DWH or other documentation containers.
|
||||
|
||||
## Three separate states
|
||||
|
||||
1. `main` contains reviewed source and the public allowlist in `mkdocs.yml`.
|
||||
2. Gitea Actions builds and validates the generated `pages` branch. A successful
|
||||
Actions run alone does **not** update the live site.
|
||||
3. The live [manual](https://git.tylconsulting.it/thothii-docs/) is served by the
|
||||
dedicated `thothii-docs` nginx container on the host reached through the existing
|
||||
trusted SSH alias `contabo`. Its Compose project/service are `thothii-docs`/`docs`.
|
||||
|
||||
This procedure is manual. No timer, webhook, credential or automatic deployment
|
||||
has been added. Use the operator's existing SSH authorization and known host key;
|
||||
never disable host verification to make a publication work.
|
||||
|
||||
## Build and stage
|
||||
|
||||
From a clean ThothII `main` checkout already pushed to Gitea:
|
||||
|
||||
```sh
|
||||
git status --short
|
||||
git rev-parse HEAD
|
||||
./scripts/build-docs.sh
|
||||
bash scripts/auth-docs-smoke.sh
|
||||
bash scripts/verify-dwh-auth-docs.sh
|
||||
bash scripts/test-auth-docs-smoke.sh
|
||||
bash scripts/test-verify-dwh-auth-docs.sh
|
||||
```
|
||||
|
||||
The strict build also verifies the public boundary: exactly 20 navigation pages,
|
||||
five approved source assets, no internal pages/assets, and matching search entries.
|
||||
The locked Windmill theme requires a separate exact allowlist of 25 static assets;
|
||||
MkDocs applies `exclude_docs` to those files too. Never replace the list with broad
|
||||
directory exceptions. Sources under `docs/` may not shadow theme asset paths.
|
||||
The verifier follows stylesheet/script/image references and CSS font references
|
||||
from generated pages and fails when a local dependency is absent.
|
||||
|
||||
Choose a unique release identifier consisting of UTC timestamp and source SHA.
|
||||
Record the current symlink and container identity before proceeding:
|
||||
|
||||
```sh
|
||||
ssh -oBatchMode=yes -oStrictHostKeyChecking=yes contabo \
|
||||
'readlink /srv/thothii-docs/current; docker inspect --format "{{.Id}} {{.State.Health.Status}}" thothii-docs'
|
||||
```
|
||||
|
||||
On the server, create `/srv/thothii-docs/releases/RELEASE/site` only if RELEASE
|
||||
does not exist. Copy the current `nginx.conf` unchanged into the new release.
|
||||
Transfer the local built `site/` into that new empty directory with rsync over
|
||||
the same verified SSH connection. Do not use `--delete` against `current`, and do
|
||||
not edit routing, TLS, network or authentication configuration.
|
||||
|
||||
## Activate only this site
|
||||
|
||||
Replace RELEASE below with the validated identifier, not a user-supplied path.
|
||||
Keep the previously recorded release for rollback.
|
||||
|
||||
```sh
|
||||
cd /srv/thothii-docs
|
||||
test -f releases/RELEASE/site/index.html
|
||||
test -f releases/RELEASE/nginx.conf
|
||||
docker exec thothii-docs nginx -t
|
||||
ln -s releases/RELEASE current.next
|
||||
mv -Tf current.next current
|
||||
docker compose --project-name thothii-docs -f docker-compose.yml \
|
||||
up -d --no-deps --force-recreate docs
|
||||
```
|
||||
|
||||
Check that `current.next` does not already exist before creating it; stop if it
|
||||
does, because another publication or recovery may be in progress. Changing the
|
||||
symlink alone is insufficient: an existing Docker bind mount still resolves to
|
||||
the old release. The service recreation above remounts the new directory. It may
|
||||
briefly interrupt this manual only.
|
||||
|
||||
## Verify, record, or roll back
|
||||
|
||||
- Wait for `docker inspect` to report this container healthy; verify mounted
|
||||
paths and nginx configuration. Stop after a bounded timeout (for example 60 s).
|
||||
- Without login/cookies, require HTTP 200 for home, search and both
|
||||
`install/standalone-manual-it/` and `install/standalone-manual-en/`.
|
||||
- Compare live home and `search/search_index.json` checksums to the build. Search
|
||||
must contain only the 20 approved pages, never plans, reports or architecture.
|
||||
- Check the actual stylesheet and JavaScript URLs in both installation pages:
|
||||
HTTP 200, CSS served as `text/css`, JavaScript with a valid script content type,
|
||||
and fonts available. In a browser confirm the stylesheets load and the layout is
|
||||
styled. HTML 200 alone is not enough to accept a publication.
|
||||
- Require HTTP 404 for retired/internal paths, including `architecture/overview/`,
|
||||
`plans/2026-09-08-memory-management/`, and `operations/compose-reference/`.
|
||||
- Record source SHA, release ID, previous release and checks in the cleanup/release
|
||||
record. Do not call the publication complete solely because `pages` was pushed.
|
||||
|
||||
If health or public verification fails, point `current` back to the recorded
|
||||
previous release using a fresh temporary symlink and the same atomic rename, then
|
||||
recreate **only** service `docs` with the same Compose command. Verify health and
|
||||
old site availability. Do not delete either release during recovery. Historical
|
||||
releases are retained; pruning them requires a separate retention decision.
|
||||
@@ -118,12 +118,12 @@ other CPU workloads.
|
||||
Run the first evaluation in shadow mode: read the source with its existing read-only role, do not
|
||||
save proposed flags, and report only aggregate counts, rule IDs, coverage, and timings. Never copy
|
||||
matched values into test output. Use a separately approved, labeled Italian corpus to calculate
|
||||
precision and recall; raw PSD values must remain inside the authorized environment.
|
||||
precision and recall; source values must remain inside the authorized environment.
|
||||
|
||||
Inside the configured core runtime, the non-mutating command is:
|
||||
|
||||
```bash
|
||||
npm run sensitivity:shadow -- psd-clinical
|
||||
npm run sensitivity:shadow -- <workspace-id>
|
||||
```
|
||||
|
||||
It reads catalog metadata and source values but emits one aggregate JSON object with no database,
|
||||
@@ -139,12 +139,7 @@ Enabling NER by default requires all of these gates:
|
||||
If a gate fails, leave NER disabled. The deterministic policy remains available and produces the
|
||||
binary draft from its scan coverage; no content is sent to an internal or external LLM.
|
||||
|
||||
The first aggregate PSD shadow comparison is recorded in
|
||||
[`2026-09-02-psd-sensitivity-shadow.md`](../reports/2026-09-02-psd-sensitivity-shadow.md). On the
|
||||
local CPU runner, NER found additional entities but reduced total coverage under the superseded
|
||||
global deadline. The v2 benchmark removed that confounder: CPU NER added 18 sensitive proposals and
|
||||
increased the warm analysis time from 50.1 to 61.3 seconds. It remains opt-in until a labeled Italian
|
||||
evaluation establishes that the additional findings justify their false-positive rate and cost.
|
||||
The deterministic progressive PSD run is recorded in
|
||||
[`2026-09-03-psd-progressive-sensitivity-shadow.md`](../reports/2026-09-03-psd-progressive-sensitivity-shadow.md):
|
||||
both deterministic and CPU-NER profiles assessed all 2,275 columns with zero `unknown` decisions.
|
||||
Benchmarks from a particular installation are not a guarantee for another database or machine.
|
||||
NER remains opt-in until an approved evaluation establishes that additional findings justify
|
||||
their false-positive rate and operational cost. Keep benchmark and release records with the
|
||||
installation's technical evidence, separate from this operator procedure.
|
||||
|
||||
@@ -722,6 +722,6 @@ la nuova installazione è ferma ma ispezionabile.
|
||||
- [OIDC generico](../install/authentication-oidc.md)
|
||||
- [Operazioni workspace](workspaces.md)
|
||||
- [Configurazione dei modelli Pi](../general/pi-configuration.md)
|
||||
- [Contesti Docker](../installazione-docker-4-contesti.md)
|
||||
- [Contesti Docker](compose-reference.md)
|
||||
- [Database Management](database-management.md)
|
||||
- [Analisi locale della sensibilità](sensitivity-analysis.md)
|
||||
|
||||
@@ -54,7 +54,7 @@ Omics. Le preferenze non modificano il descrittore installato.
|
||||
Per una nuova installazione autonoma, selezionare esplicitamente full:
|
||||
|
||||
```bash
|
||||
tht setup --profile local --shell-mode full --shell-default-locale en
|
||||
tht setup --complete --profile local --shell-mode full --shell-default-locale en
|
||||
```
|
||||
|
||||
Il setup senza opzioni shell conserva per compatibilità il default embedded.
|
||||
@@ -184,19 +184,22 @@ Ci sono tre scelte distinte:
|
||||
|
||||
| Scelta | Dove viene conservata | Cosa influenza |
|
||||
| --- | --- | --- |
|
||||
| Lingua UI | preferenza full o stato Omics | label, form, messaggi e controlli |
|
||||
| Lingua di interazione | `interaction_language` nel manifest | nuove domande, spiegazioni e scelte del modello |
|
||||
| Lingua UI | preferenza full o stato Omics | navigazione, amministrazione e messaggi generali |
|
||||
| Lingua di interazione | `interaction_language` nel manifest | domande, spiegazioni, scelte e controlli HITL |
|
||||
| Lingua workspace | configurazione del workspace | documenti, descrizioni e contenuti di dominio |
|
||||
|
||||
La creazione web acquisisce la lingua UI prima delle operazioni asincrone e la
|
||||
invia come `interactionLanguage`. Un cambio successivo non modifica quella
|
||||
richiesta. La ripresa legge il manifest e non usa il locale del browser come
|
||||
invia come `interactionLanguage` di ripiego. Il CLI riconosce localmente la lingua
|
||||
della domanda originale e la fissa nel manifest; usa il ripiego per testo troppo
|
||||
breve, ambiguo o composto soltanto da codice. Un cambio successivo non modifica
|
||||
quella richiesta. Il gate trasmette la lingua nei widget: anche i controlli HITL
|
||||
seguono la sessione, mentre la navigazione conserva la lingua UI.
|
||||
La ripresa legge il manifest e non usa il locale del browser come
|
||||
override. SQL, identificatori, valori e citazioni dei contenuti rimangono invariati.
|
||||
|
||||
Per sessioni precedenti senza `interaction_language`, la prima ripresa fissa la
|
||||
lingua del workspace in modo idempotente. Se il workspace era stato modificato
|
||||
nel frattempo, non esiste una registrazione da cui ricostruire con certezza la
|
||||
vecchia lingua: il criterio di compatibilità è quella disponibile alla ripresa.
|
||||
lingua della domanda in modo idempotente, usando la lingua del workspace come
|
||||
ripiego. Le sessioni che hanno già una lingua fissata la conservano.
|
||||
|
||||
Il cambio lingua di Omics ricarica la pagina. ThothII ricorda soltanto l'identificatore
|
||||
della sessione per utente e pagina, senza salvare una trascrizione nel browser.
|
||||
|
||||
@@ -73,9 +73,9 @@ only that run's safe stage, error code, and finish time; use `docker compose log
|
||||
corresponding service log.
|
||||
|
||||
The contract gives exact validation, exit code, and JSON rules in
|
||||
[Workspace preprocessing CLI](../contracts/workspace-preprocessing-cli.md). For Evidence source
|
||||
[Workspace preprocessing CLI](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/workspace-preprocessing-cli.md). For Evidence source
|
||||
forms and the schema-v4 descriptor contract, see
|
||||
[Workspace Evidence v3](../contracts/workspace-evidence-v3.md).
|
||||
[Workspace Evidence v3](https://git.tylconsulting.it/mptyl/ThothII/src/branch/main/docs/contracts/workspace-evidence-v3.md).
|
||||
|
||||
## Transport and revision rules
|
||||
|
||||
|
||||
@@ -1,695 +0,0 @@
|
||||
# Metadata Catalog di ThothII: ricognizione ThothAI e percorso incrementale
|
||||
|
||||
Data: 2026-08-26; aggiornato 2026-08-27
|
||||
Stato: ricognizione e progettazione completate; navigazione, CRUD Workspace Database, Catalog
|
||||
Table, Catalog Column, Catalog Relationship e sincronizzazione durevole dello schema implementati
|
||||
il 2026-08-27. Generazione AI e integrazione con il workflow core restano negli step successivi.
|
||||
|
||||
## Obiettivo
|
||||
|
||||
ThothII deve introdurre un contesto amministrativo separato, il **Metadata Catalog**, per gestire
|
||||
il database associato a ciascun workspace, la sua struttura fisica introspezionata e i metadati
|
||||
semantici oggi rappresentati da `schema/annotations.yaml`.
|
||||
|
||||
Il programma procede per step indipendenti. Il primo step ha aggiunto l'accesso dalla sidebar; il
|
||||
secondo ha sostituito la superficie vuota con il CRUD di configurazione, il PostgreSQL interno e i
|
||||
test di connessione; gli step successivi hanno aggiunto navigazione gerarchica, colonne, relazioni
|
||||
fisiche e sincronizzazione durevole dell'intero schema. Non introduce ancora generazione AI o
|
||||
integrazione con il workflow core.
|
||||
|
||||
Questa analisi usa come riferimento il working tree legacy osservato in
|
||||
`Thoth/ThothAI`. Non è stato verificato che quel contenuto corrisponda a una release o a un tag
|
||||
canonico; i percorsi e i comportamenti descrivono il sorgente disponibile il 2026-08-26.
|
||||
|
||||
## Decisioni già confermate
|
||||
|
||||
1. Ogni Workspace Database appartiene a un solo workspace tramite un `workspace_id` obbligatorio e
|
||||
univoco; un workspace può avere al massimo un Workspace Database. Poiché i workspace non sono
|
||||
righe del catalogo PostgreSQL, l'associazione è un riferimento logico validato contro
|
||||
`thoth-workspaces.yaml`, non una foreign key SQL.
|
||||
2. Il CRUD non crea né rinomina workspace. Identità e lista ordinata dei workspace restano
|
||||
autorevoli in `thoth-workspaces.yaml`; il catalogo conserva il loro identificatore stabile.
|
||||
3. La struttura fisica viene acquisita interrogando il database esterno tramite i dati di
|
||||
connessione registrati per il Workspace Database.
|
||||
4. I contenuti semantici equivalenti a `annotations.yaml` vengono generati con l'AI e conservati nel
|
||||
PostgreSQL interno.
|
||||
5. Per PSD è prevista l'importazione delle annotations esistenti. Gli altri database partiranno
|
||||
dalla struttura introspezionata e genereranno i metadati semantici da zero.
|
||||
6. `annotations.yaml` sarà sostituito anche come input del core in uno step futuro. Il repository è
|
||||
in fase di test e non è richiesta la conservazione delle sessioni esistenti durante il cutover.
|
||||
7. La gestione catalogo resta una superficie separata dal processo NL→SQL. La futura integrazione
|
||||
deve essere esplicita e non deve modificare fasi, gate o semantica del workflow.
|
||||
8. Il link iniziale è visibile agli utenti con `workspace.manage`, usa stato React locale e non
|
||||
introduce un router.
|
||||
9. La pagina iniziale è vuota, segue il tema, nasconde l'intera colonna core e non interrompe una
|
||||
sessione live. Le azioni di apertura, resume o creazione sessione riportano al core.
|
||||
10. La compatibilità con il modello ThothAI è semantica, non una copia letterale: configurazione e
|
||||
contenuti semantici sono campi relazionali mutabili, mentre identità e appartenenza della
|
||||
struttura fisica derivano dall'introspezione; i segreti restano nel secret store e lo stato dei
|
||||
job non viene mescolato ai dati amministrativi.
|
||||
11. Il CRUD amministra il Metadata Catalog e non esegue DDL sul database esterno, che resta
|
||||
read-only.
|
||||
12. La prima versione supporta PostgreSQL; il confine di introspezione dovrà permettere di
|
||||
aggiungere altri dialetti senza cambiare il modello del catalogo.
|
||||
13. I segreti dei Workspace Database riusano il secret store cifrato di ThothII. Il catalogo
|
||||
conserva riferimenti ai segreti e nessuna API, esportazione o log ne restituisce i valori.
|
||||
14. La UI usa AG Grid Community per la lista master e un pannello React separato per il dettaglio;
|
||||
non dipende dalle funzionalità master-detail di AG Grid Enterprise.
|
||||
15. Un Workspace Database il cui `workspace_id` scompare dal catalogo YAML non viene cancellato
|
||||
automaticamente: diventa orphaned e può soltanto essere recuperato, riassegnato o eliminato
|
||||
esplicitamente da un amministratore.
|
||||
16. La prima vertical slice gestisce configurazione del Workspace Database, riferimenti ai segreti,
|
||||
test di connessione e stato. La seconda gestisce le Catalog Table: la collezione e i nomi sono
|
||||
controllati dall'introspezione, mentre la descrizione curata è modificabile. Le slice successive
|
||||
hanno aggiunto Catalog Column, Catalog Relationship e sincronizzazione durevole dello schema.
|
||||
17. Il modello non conserva il `name` libero di ThothAI: nome e ID visualizzati appartengono al
|
||||
workspace YAML, mentre `database_name` identifica il database PostgreSQL esterno.
|
||||
18. Database management supporta i tre trasporti già riconosciuti da ThothII: `postgres_direct`,
|
||||
`rest_api` e `ssh_tunnel`. PSD rimane un solo Workspace Database: usa la connessione diretta sul
|
||||
server e l'endpoint REST in locale tramite una Database Binding specifica dell'installazione.
|
||||
Questo supporto non abilita automaticamente `ssh_tunnel` nel runtime NL→SQL.
|
||||
19. Una configurazione può essere salvata prima di una connessione riuscita. Il test separato
|
||||
produce uno stato `untested`, `reachable` o `failed`; attivazione e introspezione richiedono uno
|
||||
stato raggiungibile.
|
||||
20. Il CRUD e il test di connessione richiedono `database.manage`; inserimento e sostituzione dei
|
||||
segreti continuano a richiedere `workspace.secrets.manage`.
|
||||
21. Il Workspace Database e il modo di raggiungerlo sono entità distinte. Ogni catalogo di
|
||||
installazione conserva una sola Database Binding attiva per workspace: PSD usa `rest_api` in
|
||||
locale e `postgres_direct` sul server senza duplicare il Workspace Database.
|
||||
22. Nel modello finale il Metadata Catalog è autorevole per engine, `database_name`, schema,
|
||||
capacità e binding. Lo YAML resta autorevole per identità e contenuti del workspace; i campi
|
||||
DWH correnti saranno importati, confrontati e rimossi soltanto durante un cutover esplicito.
|
||||
23. La lista master è l'unione fra workspace YAML e record del catalogo: mostra workspace
|
||||
`unconfigured`, database configurati e record `orphaned`.
|
||||
24. Ogni introspezione registra le capability disponibili. Una capability `unavailable` non viene
|
||||
rappresentata come una collezione osservata ma vuota; REST può completare con successo anche
|
||||
quando indici o enum non sono supportati.
|
||||
25. Il Metadata Catalog non introduce snapshot, draft o pubblicazioni. Configurazione e contenuti
|
||||
semantici, inclusi quelli futuri generati dall'AI, sono normali campi modificabili; la struttura
|
||||
osservata cambia soltanto con una sincronizzazione esplicita.
|
||||
26. Il normale Delete elimina realmente il Workspace Database, la Database Binding e i relativi
|
||||
record catalogo e segreti. Non modifica il DWH esterno né il repository YAML; il workspace torna
|
||||
visibile nella lista master come `unconfigured`.
|
||||
27. La prima versione gestisce un solo schema obbligatorio per Workspace Database, identificato
|
||||
dalla coppia `database_name + schema`; per PSD la coppia è `postgres + datawarehouse`.
|
||||
28. I record mantengono soltanto `created_at`, `updated_at` e un contatore `version` per optimistic
|
||||
concurrency. Non esistono storico delle revisioni, rollback o audit applicativo delle modifiche.
|
||||
29. `workspace_databases` conserva soltanto UUID, `workspace_id` unique, engine, `database_name`,
|
||||
schema, timestamp e version. Il nome visualizzato appartiene al workspace YAML.
|
||||
30. Ogni Workspace Database ha al massimo una riga `database_bindings`. Una singola tabella usa
|
||||
check constraint dipendenti da `transport` per i campi direct, REST e SSH; non esiste un flag
|
||||
`active`, perché ciascuna installazione conserva una sola binding.
|
||||
31. `rest_api` configura il Thoth REST Connector tipizzato: base URL, autenticazione e TLS sono dati
|
||||
della binding, mentre path RPC e shape delle risposte appartengono al contratto applicativo e non
|
||||
sono liberamente configurabili.
|
||||
32. Il test connessione usa soltanto una configurazione già salvata ed è associato alla sua
|
||||
`version`. Ogni modifica della binding o dei segreti invalida il risultato precedente e riporta
|
||||
lo stato a `untested`.
|
||||
33. Password, API key e chiavi sono write-only: l'API espone soltanto `configured`, un campo vuoto
|
||||
conserva il valore esistente e la sostituzione è un'azione esplicita. Delete rimuove anche i
|
||||
segreti associati.
|
||||
34. La pagina usa AG Grid come master e un form React come detail, con sezioni Database, Connection
|
||||
e TLS/SSH condizionali. Non esiste un'azione globale `Add database`: ogni riga `unconfigured`
|
||||
offre `Configure catalog`, apre il form già vincolato a quello specifico workspace YAML e crea il
|
||||
record soltanto al Save; `workspace_id` non è selezionabile né modificabile.
|
||||
35. La grid mostra separatamente revisione/Evidence del workspace, binding runtime NL→SQL e
|
||||
configurazione del Metadata Catalog, oltre a database, schema, endpoint e ultimo aggiornamento.
|
||||
Su schermi piccoli il dettaglio occupa il pannello completo. Il cambio riga con modifiche non
|
||||
salvate e Delete richiedono conferma, senza conferma testuale tipizzata.
|
||||
36. La Database Binding conserva `connection_status`, `tested_version`, `last_tested_at`, un codice
|
||||
errore e un messaggio breve sanificato. Non conserva stack trace, DSN, credenziali o output grezzo
|
||||
del driver.
|
||||
37. Le API vivono sotto `/api/catalog`: list/create di `/databases`, get/patch/delete di
|
||||
`/databases/:id`, sostituzione dei segreti sotto `/databases/:id/secrets`, test connessione sotto
|
||||
`/databases/:id/test` e list/patch/sync delle tabelle sotto `/databases/:id/tables`.
|
||||
38. `GET /api/catalog/databases` restituisce l'intera master list unificata; AG Grid Community applica
|
||||
client-side ricerca, filtri e ordinamento. La prima versione non introduce paginazione server o
|
||||
funzionalità AG Grid Enterprise.
|
||||
39. Il Metadata Catalog vive nello stesso processo Fastify come modulo isolato con repository,
|
||||
service, route, diagnostica e readiness proprie. L'indisponibilità del catalogo non modifica
|
||||
sessioni, SSE o health del core e non giustifica ancora un microservizio separato.
|
||||
40. Il backend mantiene `pg@8.22.0` e aggiunge `kysely@0.29.5` per query e transazioni tipizzate. Le
|
||||
migrazioni Kysely sono timestampate, compilate con il backend ed eseguite da un comando
|
||||
`catalog:migrate` separato; l'applicazione non migra automaticamente il database all'avvio.
|
||||
41. Lo stack aggiunge un servizio interno `catalog-db` con volume persistente, ruolo runtime DML,
|
||||
ruolo migrator DDL e job one-shot `catalog-migrate`. Un catalogo indisponibile produce 503 sulle
|
||||
sole route catalogo.
|
||||
42. La prima vertical slice è amministrativa: scrive il catalogo ma non cambia ancora il runtime di
|
||||
sessioni e workflow, che continua a usare YAML e binding correnti fino al cutover esplicito.
|
||||
43. `Configure` precompila senza salvare engine, database e schema dal descriptor e i dati non
|
||||
sensibili dalla binding effettiva. L'amministratore verifica, inserisce i segreti e salva; non
|
||||
esiste importazione silenziosa.
|
||||
44. Unit e route test usano un repository fake; una suite PostgreSQL Testcontainers separata verifica
|
||||
migrazioni, constraint, transazioni, optimistic concurrency e cascade. SQLite ed emulatori non
|
||||
sono sostituti ammessi per questi test.
|
||||
45. La navigazione delle entità catalogo è gerarchica e senza scorciatoie globali: `Databases →
|
||||
Database → Overview | Tables → Table`. Non esistono una voce globale Tables, un filtro globale
|
||||
Database o una preselezione implicita; Columns continuerà sotto Table e Relationships sotto
|
||||
Database.
|
||||
46. Una Catalog Table conserva nome fisico, `source_comment`, descrizione curata nullable,
|
||||
`generated_description` nullable per lo step AI futuro, version e timestamp. La UI mostra come
|
||||
tre campi indipendenti senza fallback visivo: source comment read-only, generated description
|
||||
modificabile e description modificabile. I valori null restano celle e controlli vuoti.
|
||||
47. Le Catalog Table non possono essere aggiunte o rinominate manualmente. Un amministratore può
|
||||
però ripulire esplicitamente le proiezioni nel Metadata Catalog senza modificare il database
|
||||
esterno; `Sync tables` legge le tabelle PostgreSQL ordinarie e partizionate dello schema scelto,
|
||||
mentre viste e materialized view sono escluse.
|
||||
48. La sincronizzazione è esplicita. La scansione avviene fuori dalla transazione del catalogo; il
|
||||
diff viene applicato atomicamente soltanto se la version del Workspace Database è ancora quella
|
||||
sottoposta a scansione. Una scansione fallita non modifica il catalogo.
|
||||
49. Tabelle nuove vengono create, i commenti sorgente vengono aggiornati e quelle non più osservate
|
||||
vengono eliminate definitivamente. La rimozione di tabelle, colonne o relazioni richiede la
|
||||
conferma dell'esatto piano distruttivo; se il secondo scan produce una fotografia differente,
|
||||
l'applicazione richiede una nuova conferma.
|
||||
50. Un rename fisico è intenzionalmente delete più create e perde i metadati curati. Le colonne e
|
||||
relazioni dipendenti vengono eliminate in cascade insieme alla Catalog Table.
|
||||
51. L'introspezione vive nel modulo catalogo Fastify dietro un adapter. PostgreSQL diretto e tunnel
|
||||
SSH usano il catalogo `pg_catalog`; REST preferisce il contratto tipizzato
|
||||
`POST /rpc/schema_snapshot` e, quando quell'RPC non è esposto, usa come fallback compatibile una
|
||||
singola query read-only tramite `POST /rpc/run_query`. Entrambi i percorsi devono produrre la
|
||||
stessa fotografia v1 stretta descritta in `docs/contracts/catalog-schema-snapshot.md`.
|
||||
52. Test connessione e sincronizzazione sono serializzati per Workspace Database, hanno timeout e
|
||||
richiedono che la binding nella version corrente abbia un test `reachable` prima di qualsiasi
|
||||
Catalog Sync Run. La scansione asincrona ha un timeout separato, di default dieci minuti.
|
||||
53. Il tunnel SSH usa OpenSSH in modalità stdio `-W`, chiave privata e passphrase opzionale dal
|
||||
secret store, `known_hosts` obbligatorio, `StrictHostKeyChecking=yes`, agent e configurazione
|
||||
globale disabilitati. Non è ammesso TOFU. TLS PostgreSQL con CA e server name resta verificato
|
||||
anche attraverso il tunnel.
|
||||
54. In questo slice `ssh_tunnel` è una binding supportata da Database management per Test connection
|
||||
e Schema Sync. Il renderer e il runtime delle sessioni NL→SQL restano fuori scope e continuano a
|
||||
rifiutarla finché non verrà deciso il relativo cutover.
|
||||
55. I menu di azione a livello Workspace Database espongono separatamente `Synchronize tables`,
|
||||
`Synchronize relationships` e `Synchronize all`. Su una selezione di
|
||||
database lo scope scelto viene avviato per ogni database idoneo; non viene sostituito
|
||||
implicitamente con una sincronizzazione completa.
|
||||
56. Lo scope Columns è disponibile dalla grid Tables e limita la riconciliazione alle tabelle
|
||||
selezionate; la pagina Columns non espone azioni di sincronizzazione. La grid Tables espone
|
||||
`Synchronize columns` sulle tabelle selezionate.
|
||||
|
||||
## Correzione del modello mentale corrente
|
||||
|
||||
`schema/annotations.yaml` non contiene l'intero schema del database.
|
||||
|
||||
- `physical.yaml` è un artefatto derivato dall'introspezione. Contiene database, schema, timestamp,
|
||||
tabelle, colonne, tipi, nullability, default, primary key, commenti sorgente, esempi, foreign key
|
||||
fisiche e indici.
|
||||
- `annotations.yaml` contiene metadati curati: descrizioni e concetti delle tabelle; descrizioni,
|
||||
sinonimi, concetti, evidence, note e override `eligible` delle colonne; foreign key logiche.
|
||||
- Il rendering M-Schema fonde questi due input. Le annotations prevalgono sui commenti sorgente e
|
||||
le relazioni logiche vengono unite alle foreign key fisiche.
|
||||
|
||||
La sostituzione del solo file annotations non elimina automaticamente l'introspezione fisica. Il
|
||||
nuovo catalogo dovrà conservare una distinzione esplicita fra fatti osservati nel database e
|
||||
contenuto semantico modificabile.
|
||||
|
||||
## Architettura ThothII rilevante
|
||||
|
||||
### Autorità e revisionamento attuali
|
||||
|
||||
Il repository dei workspace contiene:
|
||||
|
||||
```text
|
||||
thoth-workspaces.yaml
|
||||
<workspace-id>/workspace.yaml
|
||||
<workspace-id>/schema/annotations.yaml
|
||||
<workspace-id>/evidence/**
|
||||
```
|
||||
|
||||
Il backend legge descriptor e annotations allo stesso commit Git. Durante l'attivazione valida il
|
||||
blob, lo copia atomicamente nello snapshot immutabile della revisione e registra commit, blob ID e
|
||||
digest. Le nuove sessioni vengono legate a quella revisione; resume e SQL salvato riaprono lo stesso
|
||||
snapshot.
|
||||
|
||||
Punti principali:
|
||||
|
||||
- `backend/src/workspaces/schema.ts`: descriptor v3 e singolo `dwh.database`/`dwh.schema`;
|
||||
- `backend/src/workspaces/git-repository.ts`: lettura sicura del blob annotations al commit;
|
||||
- `backend/src/workspaces/registry.ts`: validazione e attivazione atomica;
|
||||
- `backend/src/workspaces/annotations-sync.ts`: materializzazione revision-qualified;
|
||||
- `backend/src/workspaces/runtime-config-lease.ts`: binding dello snapshot al runtime;
|
||||
- `harness/tht/mschema/models.py`: contratti `PhysicalSchema` e `Annotations`;
|
||||
- `harness/tht/mschema/render.py`: fusione fisico/semantico;
|
||||
- `harness/tht/cli/vector_cmd.py`: indicizzazione schema in Qdrant.
|
||||
|
||||
### Consumatori da preservare al cutover futuro
|
||||
|
||||
Le annotations incidono oggi su:
|
||||
|
||||
- override `eligible` prima del campionamento LSH;
|
||||
- suggerimento, controllo e accettazione delle foreign key logiche;
|
||||
- descrizioni, concetti e sinonimi dei record schema in Qdrant;
|
||||
- retrieval delle tabelle e colonne candidate;
|
||||
- rendering M-Schema usato dal gate F4 e dalla generazione SQL;
|
||||
- digest della revisione accettata durante il preprocessing.
|
||||
|
||||
Il futuro cutover non potrà limitarsi a rimuovere il file: dovrà fornire al core lo stesso contenuto
|
||||
effettivo, con un'identità coerente e test di equivalenza. Poiché non occorre preservare le sessioni
|
||||
di test esistenti, non serve progettare compatibilità con i vecchi manifest, ma resta necessario
|
||||
evitare letture parziali o semanticamente incoerenti.
|
||||
|
||||
## Inventario ThothAI
|
||||
|
||||
### Modelli legacy
|
||||
|
||||
I modelli sono definiti in `Thoth/ThothAI/backend/thoth_core/models.py`.
|
||||
|
||||
#### `SqlDb`
|
||||
|
||||
Campi di connessione osservati:
|
||||
|
||||
- `name`;
|
||||
- `db_host`, `db_port`;
|
||||
- `db_type`;
|
||||
- `db_name`, `schema`;
|
||||
- `user_name`, `password`;
|
||||
- `db_mode`;
|
||||
- configurazione SSH e Informix opzionale.
|
||||
|
||||
Il modello contiene anche scope, JSON dello scope, ERD, direttive, campi GDPR, collegamento a
|
||||
`VectorDb` e numerosi campi di stato/task/log per lavori AI asincroni.
|
||||
|
||||
I tipi legacy dichiarati sono Informix, MariaDB, MySQL, Oracle, PostgreSQL, SQL Server e SQLite.
|
||||
Questo elenco non costituisce automaticamente un requisito per ThothII: il core corrente supporta
|
||||
PostgreSQL e l'estensione ad altri dialetti dovrà essere decisa separatamente.
|
||||
|
||||
#### `SqlTable`
|
||||
|
||||
- `name`;
|
||||
- `description`;
|
||||
- `generated_comment`;
|
||||
- foreign key obbligatoria a `SqlDb`, con cancellazione cascade.
|
||||
|
||||
#### `SqlColumn`
|
||||
|
||||
- `original_column_name` e alias `column_name`;
|
||||
- `data_format` normalizzato;
|
||||
- `column_description`;
|
||||
- `generated_comment`;
|
||||
- `value_description`;
|
||||
- stringhe denormalizzate `pk_field` e `fk_field`;
|
||||
- foreign key obbligatoria a `SqlTable`, con cancellazione cascade.
|
||||
|
||||
#### `Relationship`
|
||||
|
||||
Contiene quattro foreign key obbligatorie:
|
||||
|
||||
- `source_table` e `source_column`;
|
||||
- `target_table` e `target_column`.
|
||||
|
||||
Il form admin verifica che le tabelle appartengano allo stesso database e che ogni colonna
|
||||
appartenga alla tabella selezionata. Il database non impone però gli stessi check.
|
||||
|
||||
#### `Workspace`
|
||||
|
||||
ThothAI usa `Workspace.sql_db` come foreign key nullable verso `SqlDb`: un workspace seleziona un
|
||||
solo DB, mentre lo stesso DB può essere riusato da più workspace. ThothII adotterà invece una
|
||||
relazione uno-a-uno: `workspace_id` deve essere unico nel catalogo.
|
||||
|
||||
### Lacune dei constraint legacy
|
||||
|
||||
Non risultano constraint database-level per:
|
||||
|
||||
- unicità del nome database nel workspace;
|
||||
- unicità `(database, table name)`;
|
||||
- unicità `(table, column name)`;
|
||||
- unicità degli estremi di una relationship;
|
||||
- appartenenza degli estremi della relationship allo stesso database;
|
||||
- corrispondenza fra colonna e tabella dichiarata.
|
||||
|
||||
ThothII deve applicare queste invarianti sia nel database interno sia nel servizio applicativo. La
|
||||
sola validazione del form non è sufficiente perché API, import e job la possono aggirare.
|
||||
|
||||
### Django Admin e UX da replicare concettualmente
|
||||
|
||||
ThothAI espone il CRUD tramite il Django Admin standard, registrato da
|
||||
`backend/thoth_core/admin.py` e pubblicato su `/admin/`.
|
||||
|
||||
Capacità utili:
|
||||
|
||||
- lista database con ricerca per nome, host, tipo, database e schema;
|
||||
- fieldset separati per identità, connessione, autenticazione, SSH e stato;
|
||||
- lista tabelle filtrabile per database;
|
||||
- lista colonne filtrabile in cascata per database e tabella;
|
||||
- lista relazioni con estremi leggibili e filtri per database e tabelle;
|
||||
- form relazione con dropdown dipendenti database → tabella → colonna;
|
||||
- validazione degli estremi prima del salvataggio;
|
||||
- azioni separate per test connessione, introspezione, import/export e generazione AI;
|
||||
- azioni bulk sulle righe selezionate.
|
||||
|
||||
ThothII deve replicare i contratti di interazione e validazione, non il rendering server-side o i
|
||||
template Django.
|
||||
|
||||
### Introspezione legacy
|
||||
|
||||
`Thoth/ThothAI/backend/thoth_core/dbmanagement.py` usa `thoth-dbmanager` per:
|
||||
|
||||
1. costruire l'adapter del dialetto;
|
||||
2. acquisire tabelle;
|
||||
3. acquisire e normalizzare colonne e tipi;
|
||||
4. acquisire relazioni;
|
||||
5. creare le eventuali colonne mancanti necessarie alle relazioni;
|
||||
6. aggiornare i campi PK/FK denormalizzati.
|
||||
|
||||
Il comportamento è principalmente additivo: usa `get_or_create` o controlli `exists`, aggiorna
|
||||
alcuni commenti, ma non riconcilia in modo completo rename, rimozioni o drift. Non va copiato così
|
||||
com'è. Il processo ThothII implementato distingue scansione, differenze osservate e applicazione
|
||||
della nuova snapshot.
|
||||
|
||||
### Generazione AI legacy
|
||||
|
||||
ThothAI dispone di azioni e workflow per:
|
||||
|
||||
- commenti delle tabelle;
|
||||
- commenti delle colonne;
|
||||
- scope del database;
|
||||
- ERD Mermaid;
|
||||
- documentazione del database;
|
||||
- analisi GDPR.
|
||||
|
||||
Per il requisito attuale sono direttamente rilevanti descrizioni di tabelle e colonne, scope e
|
||||
metadati semantici. ERD, documentazione aggregata e GDPR sono estensioni future, non prerequisiti
|
||||
del CRUD iniziale.
|
||||
|
||||
La separazione `description`/`generated_comment` del legacy non offre versioning o approvazione
|
||||
robusti. Nei passi successivi andrà deciso se l'output AI è una proposta revisionabile o diventa
|
||||
immediatamente il valore editabile corrente.
|
||||
|
||||
### Import ed export legacy
|
||||
|
||||
ThothAI offre:
|
||||
|
||||
- CSV di database, tabelle, colonne e relazioni;
|
||||
- export di struttura per workspace;
|
||||
- import mediante `import_db_structure`;
|
||||
- script SQL dei commenti per più dialetti;
|
||||
- aggiornamento delle descrizioni colonna da CSV.
|
||||
|
||||
Il futuro import PSD dovrà leggere il contratto YAML corrente e convertirlo su chiavi naturali,
|
||||
non riutilizzare gli ID numerici Django. Deve essere idempotente e produrre un report di elementi
|
||||
creati, aggiornati, ignorati o non risolti.
|
||||
|
||||
## Comandi osservati in ThothAI
|
||||
|
||||
### Backend locale
|
||||
|
||||
Eseguiti da `Thoth/ThothAI/backend`:
|
||||
|
||||
```sh
|
||||
uv sync
|
||||
uv run python manage.py migrate
|
||||
uv run python manage.py createsuperuser
|
||||
uv run python manage.py runserver 8200
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
Import catalogo legacy:
|
||||
|
||||
```sh
|
||||
uv run python manage.py import_db_structure --source local
|
||||
uv run python manage.py load_defaults --only-level 4 --source local
|
||||
```
|
||||
|
||||
Test mirati rilevanti:
|
||||
|
||||
```sh
|
||||
uv run pytest tests/test_relational_database_operations.py -v
|
||||
uv run pytest tests/test_ssh_tunnel_configuration.py -v
|
||||
```
|
||||
|
||||
### Stack Docker legacy
|
||||
|
||||
ThothAI dichiara `postgres:16-alpine` nel profilo `internal-db`, con volume persistente e
|
||||
healthcheck `pg_isready`.
|
||||
|
||||
```sh
|
||||
docker compose --profile internal-db up --build
|
||||
```
|
||||
|
||||
Il wrapper legacy abilita lo stesso profilo quando `POSTGRES_INTERNAL=true`:
|
||||
|
||||
```sh
|
||||
POSTGRES_INTERNAL=true ./docker-up.sh
|
||||
```
|
||||
|
||||
Questi comandi documentano il riferimento osservato; non sono comandi di installazione per
|
||||
ThothII.
|
||||
|
||||
## Cosa copiare in ThothII
|
||||
|
||||
### Parità necessaria
|
||||
|
||||
- gerarchia Workspace Database → Table → Column;
|
||||
- relazione strutturale fra colonne sorgente e destinazione;
|
||||
- navigazione e filtri dipendenti workspace/database/tabella;
|
||||
- test di connessione separato dal salvataggio;
|
||||
- introspezione esplicita e ripetibile;
|
||||
- descrizioni generate dall'AI ma modificabili dall'utente;
|
||||
- validazione cross-entity delle relazioni;
|
||||
- azioni di import/export senza segreti;
|
||||
- stato leggibile dei job lunghi;
|
||||
- PostgreSQL interno persistente con migrazioni esplicite;
|
||||
- test di CRUD, cardinalità, cascade/restrict, isolamento per workspace e idempotenza.
|
||||
|
||||
### Parità semantica con `annotations.yaml`
|
||||
|
||||
Il modello futuro deve poter rappresentare almeno:
|
||||
|
||||
- descrizione, concetti e note per tabella;
|
||||
- descrizione, sinonimi, concetti, evidence, note ed `eligible` per colonna;
|
||||
- foreign key logiche;
|
||||
- distinzione fra commento fisico osservato e descrizione curata;
|
||||
- provenienza del contenuto importato o generato.
|
||||
|
||||
L'eventuale esclusione di uno di questi campi deve essere una decisione esplicita perché cambia
|
||||
rendering, retrieval, LSH o SQL generation.
|
||||
|
||||
### Vincoli minimi da progettare
|
||||
|
||||
- `workspace_id` obbligatorio e unico sul Workspace Database, con esistenza validata contro il
|
||||
catalogo YAML dal servizio applicativo;
|
||||
- nome tabella unico nel database e schema appropriato;
|
||||
- nome colonna unico nella tabella;
|
||||
- relationship unica secondo il modello, anche per chiavi composite;
|
||||
- estremi della relationship nello stesso Workspace Database;
|
||||
- appartenenza certa della colonna alla tabella;
|
||||
- mutazioni aggregate transazionali;
|
||||
- gestione esplicita di concorrenza fra CRUD e introspezione.
|
||||
|
||||
## Cosa non copiare
|
||||
|
||||
- Django, Django Admin, Django ORM, DRF, template admin e frontend Next;
|
||||
- modello Workspace legacy e condivisione dello stesso DB fra più workspace;
|
||||
- password o passphrase come normali campi testuali;
|
||||
- password incluse in CSV o export completi;
|
||||
- token SSO inseriti nella query string;
|
||||
- migrazioni generate automaticamente all'avvio;
|
||||
- validazioni presenti soltanto nel form;
|
||||
- `pk_field` e `fk_field` testuali come fonte di verità;
|
||||
- duplicazione di tabella e colonna negli estremi senza constraint coerenti;
|
||||
- introspezione additiva che non segnala rename, delete o drift;
|
||||
- azioni admin che possono mostrare successo dopo output AI non valido;
|
||||
- dipendenza del workflow core dalla disponibilità della UI o del PostgreSQL amministrativo.
|
||||
|
||||
## Aspetti di sicurezza da non ereditare
|
||||
|
||||
L'export legacy della struttura include username e password in chiaro. Il modello conserva inoltre
|
||||
password, passphrase SSH e altri segreti in `CharField`; non è stata trovata cifratura applicativa,
|
||||
nonostante un testo admin affermi il contrario.
|
||||
|
||||
ThothII distingue i metadati di connessione dai riferimenti al secret store cifrato. In ogni caso:
|
||||
|
||||
- nessun endpoint o export deve restituire segreti;
|
||||
- log ed errori devono sanificare DSN e credenziali;
|
||||
- le credenziali di migrazione non devono essere disponibili al runtime CRUD;
|
||||
- il catalogo non deve riusare credenziali del DWH, delle sessioni o di Qdrant;
|
||||
- test connessione e introspezione devono usare timeout e privilegi read-only.
|
||||
|
||||
La binding REST corrente richiede una verifica prima del cutover: il renderer emette
|
||||
`ssl_ca_file`, mentre il modello Python espone `ssl_ca`; il percorso della CA privata potrebbe quindi
|
||||
non essere consumato. PSD richiede TLS con CA privata in locale, perciò questo disallineamento deve
|
||||
essere corretto e coperto da un test end-to-end prima di affidare il profilo REST al catalogo.
|
||||
|
||||
## Percorso incrementale
|
||||
|
||||
### Step 1: accesso alla superficie vuota
|
||||
|
||||
Implementato in questo worktree:
|
||||
|
||||
- pulsante `Database management` nella sidebar destra;
|
||||
- visibilità legata a `workspace.manage`;
|
||||
- superficie centrale React separata e vuota;
|
||||
- nessun router, endpoint, fetch o stato catalogo;
|
||||
- sessione e SSE conservati in background;
|
||||
- ritorno al core tramite creazione, apertura o resume di una sessione;
|
||||
- test frontend dedicati.
|
||||
|
||||
Comandi di verifica:
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
npx vitest run src/shell/AppShell.database-management.test.tsx
|
||||
npx vitest run src/shell/AppShell.new-session.test.tsx \
|
||||
src/shell/AppShell.session-target.test.tsx \
|
||||
src/shell/AppShell.session-mgmt.test.tsx
|
||||
npx tsc -b
|
||||
```
|
||||
|
||||
### Step 2: contratto di dominio e schema relazionale
|
||||
|
||||
Progettazione della vertical slice completata: Workspace Database, Database Binding, singolo schema,
|
||||
riferimenti al secret store, optimistic concurrency e capability per trasporto hanno contratti
|
||||
espliciti. Configurazione e contenuti semantici restano mutabili; la struttura fisica osservata è
|
||||
sincronizzata e non modificabile manualmente.
|
||||
|
||||
### Step 3: PostgreSQL interno e migrazioni
|
||||
|
||||
PostgreSQL interno con volume e ruoli runtime/migrator separati. Il modulo catalogo usa Kysely sopra
|
||||
il driver `pg`; le migrazioni compilate vengono applicate soltanto dal comando `catalog:migrate` e
|
||||
mai allo startup Fastify. Health, readiness e diagnostica restano dedicate; l'indisponibilità del
|
||||
catalogo non cambia `core /health` e non interrompe una sessione.
|
||||
|
||||
### Step 4: API CRUD
|
||||
|
||||
Contratti HTTP, autorizzazione, paginazione, filtri, errori, optimistic concurrency e transazioni.
|
||||
Gli endpoint dovranno vivere sotto un namespace catalogo e non riutilizzare le route sessione.
|
||||
|
||||
### Step 5: UI CRUD
|
||||
|
||||
Workspace Database, Catalog Table, Catalog Column e Catalog Relationship sono implementati con
|
||||
React/Vite e il design system ThothII.
|
||||
La navigazione è gerarchica e locale al database (`Overview | Tables`), senza menu o filtri globali
|
||||
per tipo di entità. La grid delle tabelle non offre Add o cancellazione della singola configurazione;
|
||||
le selezioni espongono invece la pulizia esplicita dei metadati. Il dettaglio full-width mantiene
|
||||
immutabili i fatti fisici e consente di modificare separatamente Description e Generated
|
||||
Description. Colonne e relazioni seguono la stessa gerarchia: Columns appartiene al dettaglio
|
||||
della tabella, Relationships al database. I valori descrittivi null sono mostrati come celle e
|
||||
campi vuoti, senza fallback visivi o placeholder `Not set` che nascondano quale sorgente è
|
||||
effettivamente valorizzata.
|
||||
|
||||
Le griglie che dispongono di azioni massive usano checkbox e una toolbar contestuale con conteggio,
|
||||
menu `Actions` e cancellazione della selezione. La selezione identifica ID espliciti, può essere
|
||||
accumulata attraverso i filtri e viene azzerata dopo successo, nuova sincronizzazione o uscita
|
||||
dalla pagina; un'azione è all-or-nothing se un elemento non è idoneo. I menu a livello database
|
||||
espongono gli scope fisici come azioni distinte: `Synchronize tables`, `Synchronize relationships`
|
||||
e `Synchronize all`. La grid Tables espone invece `Synchronize columns` per le tabelle selezionate;
|
||||
la pagina Columns non espone sincronizzazione. Le selezioni database aggiungono `Delete all tables` e
|
||||
`Delete all relationships`; le selezioni tabelle aggiungono `Delete all columns` e `Delete all
|
||||
relationships`. Queste operazioni sono atomiche, richiedono conferma e non modificano database
|
||||
esterno, binding, configurazione o segreti. Test connection resta un'azione distinta; griglie senza
|
||||
azioni non mostrano controlli di selezione inerti.
|
||||
|
||||
### Step 6: introspezione
|
||||
|
||||
Catalog Table, Catalog Column e Catalog Relationship sono implementate per PostgreSQL diretto,
|
||||
Thoth REST Connector e tunnel SSH. La scansione read-only è separata dalla transazione; una
|
||||
riconciliazione atomica crea, aggiorna i commenti sorgente ed elimina, dopo conferma, i fatti fisici
|
||||
assenti senza rendere modificabile manualmente la struttura osservata. Gli scope autorevoli sono
|
||||
Tables per database e Physical Relationships per database. Per Columns, `tableIds` vuoto include
|
||||
tutte le Catalog Table correnti, mentre una lista di ID limita lo scope al sottoinsieme esplicito;
|
||||
`Synchronize all` osserva tutti e tre gli scope in un unico snapshot e li riconcilia insieme. Tutti
|
||||
gli scope sono eseguiti come Catalog Sync Run durevoli in background, non attraverso implementazioni
|
||||
sincrone e asincrone separate. Un run che prevede cancellazioni conserva il diff, attende una
|
||||
conferma esplicita e verifica nuovamente lo snapshot prima dell'applicazione; se la sorgente è
|
||||
cambiata, invalida la conferma. Ogni applicazione è atomica e fail-closed: errori, timeout o
|
||||
capability non disponibili non producono aggiornamenti parziali.
|
||||
|
||||
PK e FK devono essere visibili sulle Catalog Column senza duplicare le stringhe denormalizzate di
|
||||
ThothAI. La posizione nella primary key è un fatto osservato della colonna; membership e conteggio
|
||||
FK sono proiezioni derivate dalle Catalog Relationship e dalle loro coppie ordinate, aggiornate
|
||||
nella stessa transazione di riconciliazione.
|
||||
|
||||
Ogni scope registra la versione della Database Binding osservata e l'istante dell'ultima
|
||||
sincronizzazione. Una modifica della binding conserva il catalogo precedente ma lo marca stale;
|
||||
solo un `Synchronize all` riuscito rende nuovamente corrente l'intero schema.
|
||||
|
||||
### Step 7: generazione AI dei metadati
|
||||
|
||||
Generated Description è una proposta distinta e modificabile: un revisore può correggerla prima
|
||||
di consolidarla esplicitamente come Description. Lo slice AI dovrà decidere e implementare anche
|
||||
alias semantici, descrizioni dei valori, sinonimi e concetti per tabelle e colonne, oltre alla
|
||||
gestione esplicita di errori e output non validi. La generazione AI e l'azione di consolidamento non
|
||||
appartengono allo slice di introspezione dello schema.
|
||||
|
||||
### Step 8: migrazione PSD
|
||||
|
||||
Import idempotente delle annotations PSD, riconciliazione contro la struttura introspezionata,
|
||||
report degli orfani e confronto semantico con il rendering corrente. Gli altri workspace non
|
||||
ricevono import legacy.
|
||||
|
||||
### Step 9: sostituzione dell'input core
|
||||
|
||||
Rimuovere la dipendenza da `annotations.yaml` soltanto dopo avere un contratto equivalente,
|
||||
test di rendering/search/Qdrant e una policy di disponibilità. Le sessioni di test esistenti
|
||||
possono essere eliminate, ma le nuove sessioni non devono osservare aggiornamenti parziali.
|
||||
Questo cutover è esplicitamente rinviato fino al completamento del database dei metadati. Il primo
|
||||
gate successivo obbligatorio sarà valutare l'integrazione del Catalog Schema Snapshot con il
|
||||
workflow core e lo schema-linking corrente; il rinvio non autorizza a dimenticare o assorbire
|
||||
implicitamente il lavoro in altri slice.
|
||||
|
||||
### Step 10: operazioni e accettazione
|
||||
|
||||
Backup/restore reale, diagnostica, metriche, permessi definitivi, hardening degli export e
|
||||
test di failure isolation fra catalogo e workflow. I Catalog Sync Run hanno un solo job attivo per
|
||||
Workspace Database, sono concorrenti fra database diversi e usano un lock persistente. Un pannello
|
||||
operativo non modale rimane visibile durante la navigazione del database, mostra fasi, contatori,
|
||||
tempo trascorso e log sanitizzato via SSE con polling di fallback, e offre Confirm, Cancel e Retry
|
||||
quando consentiti. Un restart marca `interrupted` i run rimasti attivi; il retry crea un nuovo run.
|
||||
Le modifiche ai metadati restano consentite durante la scansione e sono preservate dall'applicazione.
|
||||
Il worker gira inizialmente nello stesso servizio Fastify ma dietro un'interfaccia estraibile, con
|
||||
coda, lease e heartbeat persistiti nel catalog-db. I riepiloghi dei run non scadono; gli eventi
|
||||
dettagliati sono conservati per 30 giorni, mentre snapshot e diff completi vengono eliminati dopo
|
||||
la conclusione lasciando conteggi, decisioni e una sintesi sanitizzata dell'esito.
|
||||
|
||||
## Verifiche del core da conservare per il cutover
|
||||
|
||||
Comandi attuali rilevanti:
|
||||
|
||||
```sh
|
||||
tht --installation <absolute>/thothii-installation.yaml workspace preprocess dwh \
|
||||
--workspace <id> --json
|
||||
tht --installation <absolute>/thothii-installation.yaml workspace schema suggest-fks \
|
||||
--workspace <id> --json
|
||||
tht --installation <absolute>/thothii-installation.yaml workspace schema check \
|
||||
--workspace <id> --json
|
||||
tht --installation <absolute>/thothii-installation.yaml workspace schema accept \
|
||||
--workspace <id> --run <run-id> --yes --json
|
||||
tht --installation <absolute>/thothii-installation.yaml workspace index-schema \
|
||||
--workspace <id> --json
|
||||
```
|
||||
|
||||
Suite che documentano il comportamento da preservare:
|
||||
|
||||
```sh
|
||||
cd backend
|
||||
npx vitest run test/workspaces-git-annotations.test.ts \
|
||||
test/registry-annotations.test.ts \
|
||||
test/annotations-sync.test.ts \
|
||||
test/workspace-runtime-config-lease.test.ts \
|
||||
test/workspace-preprocessing-service.test.ts
|
||||
npx tsc --noEmit -p .
|
||||
|
||||
cd ../harness
|
||||
.venv/bin/pytest -q \
|
||||
tests/test_annotations_root.py \
|
||||
tests/test_schema_fk_annotations.py \
|
||||
tests/test_mschema_render.py \
|
||||
tests/test_qdrant_cli_commands.py
|
||||
```
|
||||
|
||||
Questi test non implicano che la futura implementazione debba continuare a usare file YAML.
|
||||
Definiscono gli effetti semantici e le guardie da mantenere o sostituire consapevolmente.
|
||||
|
||||
## Decisioni rinviate
|
||||
|
||||
Le seguenti scelte non appartengono allo step 1:
|
||||
|
||||
- lifecycle dei riferimenti ai segreti durante sostituzione e cancellazione;
|
||||
- criteri per aggiungere dialetti successivi a PostgreSQL;
|
||||
- criteri per un'eventuale estensione futura a più schemi per database;
|
||||
- lifecycle e gestione amministrativa delle future Logical Relationship;
|
||||
- alias semantici, descrizioni dei valori, sinonimi e concetti prodotti o assistiti dall'AI;
|
||||
- formato e momento del cutover dal file al database interno;
|
||||
- permission definitiva separata da `workspace.manage`.
|
||||
|
||||
Ognuna sarà affrontata nel relativo step, senza anticipare scelte tecnologiche nel presente
|
||||
documento.
|
||||
@@ -1,251 +0,0 @@
|
||||
# AI-generated descriptions for Catalog Tables and Catalog Columns
|
||||
|
||||
## Problem Statement
|
||||
|
||||
ThothII already stores a Generated Description separately from the curated Description for Catalog
|
||||
Tables and Catalog Columns, but administrators cannot populate it with AI. ThothAI provides the
|
||||
useful core workflow—generate table and column comments from schema context and small real-data
|
||||
samples—but its execution, configuration, and interaction model cannot be copied directly into
|
||||
ThothII.
|
||||
|
||||
Administrators need an asynchronous workflow integrated into Database Management. They must be
|
||||
able to choose an installation-approved model, generate descriptions for selected or missing
|
||||
targets, observe understandable progress, stop or recover a stuck operation, review generated
|
||||
text, and explicitly consolidate it. The solution must retain ThothAI's practical simplicity and
|
||||
must not introduce a general job platform, model gateway, distributed scheduler, or competing
|
||||
user-facing CLI.
|
||||
|
||||
## Solution
|
||||
|
||||
Add Description Generation to Database Management as one installation-wide, sequential background
|
||||
run owned by the Fastify backend. The browser starts a run and remains responsive while the backend
|
||||
processes bounded requests one at a time. Each completion is delegated to a short-lived internal
|
||||
Python helper using LiteLLM. Models, their default, and any API-key secret references are declared in
|
||||
application setup YAML and are independent of both workspaces and Pi configuration.
|
||||
|
||||
Each valid result is written immediately to the target's Generated Description. A minimal run row
|
||||
and ordered text events provide status, counters, history, and a live log. A stopped or crashed run
|
||||
is not resumed automatically; completed results remain in place and Generate Missing supplies the
|
||||
simple recovery path. An Unlock action marks a stale recorded run interrupted only when no helper
|
||||
or backend generation loop is alive.
|
||||
|
||||
Prompts use catalog context and, when available, no more than five real rows and five representative
|
||||
non-null examples. Samples are transient and never logged or persisted. A valid inability to infer
|
||||
a description produces a standard application-localized value such as `Non generabile`; provider,
|
||||
timeout, and response-validation failures remain technical errors.
|
||||
|
||||
Generated text remains separate from Description until an administrator uses the existing
|
||||
checkbox selection and Actions control to consolidate it. Consolidation retains Generated
|
||||
Description and never writes comments to the external Workspace Database.
|
||||
|
||||
## User Stories
|
||||
|
||||
1. As an installation operator, I want to declare the models allowed for metadata generation in setup YAML, so that model availability is controlled centrally.
|
||||
2. As an installation operator, I want to declare one default metadata-generation model, so that administrators begin with a safe operational choice.
|
||||
3. As an installation operator, I want each model to reference its own API-key secret, so that credentials are not stored in workspaces or browser-visible settings.
|
||||
4. As an installation operator, I want metadata-generation models to remain independent of Pi models, so that changing this workflow cannot disrupt the core NL-to-SQL experience.
|
||||
5. As an installation operator, I want invalid model setup to fail validation clearly, so that the application does not start with ambiguous provider behavior.
|
||||
6. As a Catalog Administrator, I want generation controls to explain when no model is configured, so that I know why the action is unavailable.
|
||||
7. As a Catalog Administrator, I want to select an approved model from a selector initialized to the setup default, so that I control which model performs the work.
|
||||
8. As a Catalog Administrator, I want to generate descriptions for selected Catalog Tables, so that I can work on a focused part of the catalog.
|
||||
9. As a Catalog Administrator, I want to generate descriptions for selected Catalog Columns, so that I can work on individual fields without regenerating a whole table.
|
||||
10. As a Catalog Administrator, I want to generate all eligible descriptions for a Workspace Database, so that I can initialize a catalog in one operation.
|
||||
11. As a Catalog Administrator, I want to generate only missing descriptions, so that I can continue interrupted work without replacing completed proposals.
|
||||
12. As a Catalog Administrator, I want a full run to process Catalog Columns before their Catalog Tables, so that table descriptions can benefit from column descriptions.
|
||||
13. As a Catalog Administrator, I want generation to run asynchronously after I start it, so that the browser remains usable and progress is not tied to one HTTP request.
|
||||
14. As a Catalog Administrator, I want only one Description Generation Run active in the installation, so that provider traffic and operational behavior remain predictable.
|
||||
15. As a Catalog Administrator, I want a second start attempt to return a clear conflict, so that I cannot accidentally overlap generation runs.
|
||||
16. As a Catalog Administrator, I want synchronization, cleanup, consolidation, and edits for the target Workspace Database blocked during generation, so that the simple sequential run sees stable catalog state.
|
||||
17. As a Catalog Administrator, I want to see the run's model, scope, status, counters, and timestamps, so that I understand what is happening.
|
||||
18. As a Catalog Administrator, I want a chronological text log, so that I can follow completed targets and diagnose errors.
|
||||
19. As a Catalog Administrator, I want live log updates with a polling fallback, so that temporary SSE problems do not hide run progress.
|
||||
20. As a Catalog Administrator, I want completed and interrupted runs to remain inspectable, so that I can understand prior activity.
|
||||
21. As a Catalog Administrator, I want to stop an active run, so that I can halt an incorrect or unexpectedly costly operation.
|
||||
22. As a Catalog Administrator, I want stopping a run to terminate its current model helper and prevent later targets from starting, so that stop has prompt operational effect.
|
||||
23. As a Catalog Administrator, I want valid results completed before a stop or failure to remain saved, so that useful work is not discarded.
|
||||
24. As a Catalog Administrator, I want a run left active by a backend restart to become interrupted, so that the UI does not claim nonexistent work is still running.
|
||||
25. As a Catalog Administrator, I want to unlock a stale active run when no generation process is alive, so that an erroneous recorded lock cannot block future work.
|
||||
26. As a Catalog Administrator, I want Unlock rejected while a live generation process exists, so that recovery cannot create an overlapping run.
|
||||
27. As a Catalog Administrator, I want Generate Missing to continue after interruption, so that recovery does not require a special resume mechanism.
|
||||
28. As a Catalog Administrator, I want one retry for a transient model failure, so that a brief provider fault does not immediately lose a batch.
|
||||
29. As a Catalog Administrator, I want the run to fail after three consecutive technical failures, so that a broken provider does not generate an unbounded stream of attempts.
|
||||
30. As a Catalog Administrator, I want a successful request to reset the consecutive-failure count, so that isolated errors do not prematurely stop a useful run.
|
||||
31. As a Catalog Administrator, I want a completed-with-errors result when isolated batches fail but the run reaches its end, so that partial problems remain visible.
|
||||
32. As a Catalog Administrator, I want no automatic fallback to a different model, so that the selected model remains truthful and predictable.
|
||||
33. As a Catalog Administrator, I want malformed or ambiguous model output rejected without writing it, so that descriptions cannot be assigned to the wrong target.
|
||||
34. As a Catalog Administrator, I want an inability to infer a description represented by standard localized text, so that every valid outcome is understandable in the workspace language.
|
||||
35. As a Catalog Administrator, I want technical failures kept distinct from non-generatable outcomes, so that provider problems are not mistaken for catalog knowledge.
|
||||
36. As a Catalog Administrator, I want generated prose written in the workspace language, so that it matches the catalog's intended audience.
|
||||
37. As a Catalog Administrator, I want generated text stored separately from curated Description, so that AI output remains a reviewable proposal.
|
||||
38. As a Catalog Administrator, I want to edit a Generated Description manually, so that I can improve a proposal before consolidation.
|
||||
39. As a Catalog Administrator, I want to select one or more tables or columns and run “Move generated description to Description” from the existing Actions control, so that review remains integrated into the current grids.
|
||||
40. As a Catalog Administrator, I want consolidation to retain the Generated Description, so that I can still see the proposal from which the curated text was copied.
|
||||
41. As a Catalog Administrator, I want selected records without a Generated Description skipped and reported, so that the bulk action does not erase curated text.
|
||||
42. As a Catalog Administrator, I want consolidation and generation to modify only the Metadata Catalog, so that no external database comment is changed.
|
||||
43. As a Catalog Administrator, I want prompts to use schema facts and existing catalog text, so that generated descriptions are grounded in available metadata.
|
||||
44. As a Catalog Administrator, I want prompts to use at most five real source rows and five representative values when available, so that the model has useful examples without unbounded disclosure.
|
||||
45. As a Catalog Administrator, I want to be warned that real source samples are sent to the selected provider, so that I can make an informed disclosure decision.
|
||||
46. As a Catalog Administrator, I want sampled rows and values excluded from persistence and logs, so that operational history does not become a secondary data store.
|
||||
47. As a security operator, I want API keys, prompts, samples, and complete provider payloads redacted from logs, so that diagnostics do not leak secrets or source data.
|
||||
48. As a support operator, I want concise per-target and per-batch event messages, so that failures can be diagnosed without provider-specific internals.
|
||||
49. As an authorized administrator, I want all generation, cancellation, unlock, and consolidation actions protected by database-management permission, so that ordinary users cannot mutate catalog metadata.
|
||||
50. As an unauthorized user, I want generation controls hidden or disabled and API calls rejected, so that frontend visibility is not treated as authorization.
|
||||
51. As an operator, I want setup changes to take effect after an application restart, so that configuration lifecycle remains simple and explicit.
|
||||
52. As a product owner, I want the first release to avoid queues, parallel calls, distributed locks, and automatic resume, so that effort remains focused on generating and reviewing useful descriptions.
|
||||
|
||||
## Implementation Decisions
|
||||
|
||||
- The Fastify backend owns one installation-wide Description Generation Run and its sequential
|
||||
processing loop. It does not delegate lifecycle ownership to Pi or Python.
|
||||
- A Description Generation Run has one of `queued`, `running`, `completed`,
|
||||
`completed_with_errors`, `cancelled`, `failed`, or `interrupted`. It stores the Workspace
|
||||
Database, requested scope, selected model identifier, workspace language, progress counters,
|
||||
timestamps, and an optional final error summary.
|
||||
- Ordered Description Generation Events store timestamp, severity, and safe human-readable text.
|
||||
When an event identifies a target, it uses the object type and qualified physical name, such as
|
||||
`Column "patients.birth_date"` or `Table "patients"`; catalog UUIDs remain internal identifiers.
|
||||
No durable per-target jobs, model invocation rows, prompt snapshots, sample snapshots, leases,
|
||||
heartbeats, registry revisions, or provenance chains are introduced.
|
||||
- Starting a run schedules an in-process background loop and returns the run immediately. The API
|
||||
exposes start, run/history lookup, event listing and streaming, cancellation, stale-run unlock,
|
||||
and the safe list of configured model choices. There are no retry-item or resume endpoints.
|
||||
- One in-memory generation manager enforces the installation-wide active-run rule. The existing
|
||||
Catalog Operation Coordinator reserves the target Workspace Database for the duration of the
|
||||
run, without being generalized into a new operation framework.
|
||||
- On backend startup, persisted `queued` or `running` Description Generation Runs become
|
||||
`interrupted`. The application performs no automatic replay or resume.
|
||||
- Unlock succeeds only when no live generation loop or helper child exists. It marks the stale run
|
||||
interrupted and releases the local reservation; it is not a distributed lock recovery protocol.
|
||||
- Each model completion uses a short-lived Python helper backed by LiteLLM. Structured input is
|
||||
supplied over stdin, structured output alone is emitted on stdout, diagnostics use stderr, and
|
||||
the helper can be terminated by cancellation.
|
||||
- A completion request contains no more than ten targets. Requests run one at a time. The helper
|
||||
performs at most one retry for a transient technical failure.
|
||||
- Three consecutive model-request failures fail the run. A successful request resets that count.
|
||||
Isolated exhausted failures may be logged and skipped, producing `completed_with_errors` if the
|
||||
run later reaches its end.
|
||||
- Every valid generated or non-generatable result is applied immediately to Generated Description.
|
||||
Earlier writes are retained after cancellation, interruption, or later failure.
|
||||
- A response must identify requested targets unambiguously and classify each returned result as
|
||||
generated or non-generatable. Duplicate, unknown, missing, or malformed mappings cause a
|
||||
technical request failure and no result from that ambiguous response is applied.
|
||||
- The parser also tolerates one JSON object enclosed by one complete `json` code fence, because
|
||||
some supported models add that formatting despite the prompt. Any prose outside the fence,
|
||||
multiple payloads, or malformed/ambiguous mappings remain invalid.
|
||||
- The application supplies localized standard non-generatable text. Provider wording is not used
|
||||
as the standard value, and technical errors never write that value.
|
||||
- A full-database run generates eligible Catalog Columns before Catalog Tables. Generate Missing
|
||||
excludes targets whose Generated Description is already non-empty; all-generation may replace
|
||||
existing generated proposals only after the initiating action makes that scope explicit.
|
||||
- Model choices are declared under a metadata-generation section in installation setup YAML. Each
|
||||
choice has a stable identifier, display label, LiteLLM provider/model settings, optional endpoint
|
||||
settings, and an optional environment-secret reference for its API key. The reference may be
|
||||
omitted only when an explicit endpoint is configured for unauthenticated access. One identifier
|
||||
is the default.
|
||||
- An explicit endpoint may set `disableThinking: true`; the helper translates it only to the
|
||||
Qwen-compatible chat-template switch needed to keep the response within the strict JSON contract.
|
||||
- Metadata-generation setup is separate from application settings for Pi and from workspace
|
||||
`llm_policy`. Raw keys never enter setup YAML, the catalog database, API responses, process
|
||||
arguments, or event text. Configuration reload is restart-only.
|
||||
- If setup defines no usable model, the safe model-list response is empty and the UI disables
|
||||
generation with an explanation. The backend still rejects direct generation attempts.
|
||||
- Prompt construction treats schema names, comments, descriptions, and values as untrusted data.
|
||||
It requests output in the workspace language and separates instructions from catalog content.
|
||||
- A request may contain up to five real source rows and up to five representative distinct,
|
||||
non-null values for relevant columns. Inputs are bounded before prompt construction and are not
|
||||
persisted or logged.
|
||||
- The UI discloses that real data can be sent to the selected provider. A future Sensitive Data
|
||||
Policy will classify values and exclude or anonymize protected data; that policy is not silently
|
||||
approximated in this slice.
|
||||
- The generation UI reuses Database Management's table and column selections, model selector,
|
||||
Actions control, run drawer conventions, SSE delivery, and polling fallback where practical.
|
||||
Visual parity with Catalog Sync Run logs is not required.
|
||||
- The consolidation action copies each selected, non-empty Generated Description into Description
|
||||
in a catalog transaction, retains Generated Description, skips empty proposals, and reports
|
||||
copied and skipped counts. It never writes to the external Workspace Database.
|
||||
- Generation, cancellation, unlock, and consolidation require the existing database-management
|
||||
permission and are validated by the backend independently of UI state.
|
||||
- No user-facing generation CLI is added. The Python process is an internal completion adapter,
|
||||
not an operator surface or a long-lived service.
|
||||
|
||||
## Testing Decisions
|
||||
|
||||
- Tests assert externally observable behavior rather than private loop structure, process timing,
|
||||
or LiteLLM implementation details.
|
||||
- The primary and highest test seam is the Fastify catalog API with a test PostgreSQL catalog and
|
||||
an injected fake Model Completer. It verifies complete paths through authorization, run
|
||||
persistence, sequential processing, event delivery, Generated Description updates, and final
|
||||
status without contacting a real provider.
|
||||
- API tests cover each generation scope, column-before-table order, the ten-target request bound,
|
||||
model validation, one-active-run conflict, target-database exclusion, cancellation, startup
|
||||
interruption, Unlock safeguards, Generate Missing, partial success, consecutive failure
|
||||
handling, non-generatable localization, malformed responses, redacted events, and permissions.
|
||||
- Catalog repository integration tests verify the migration, run and event ordering, active-run
|
||||
constraint, immediate description writes, history queries, startup interruption, and bulk
|
||||
consolidation behavior against PostgreSQL.
|
||||
- The Python helper has a small black-box contract suite using a simulated LiteLLM adapter. It
|
||||
verifies stdin/stdout framing, pristine stdout, stderr diagnostics, normalized success and
|
||||
failure output, one transient retry, secret redaction, and termination behavior.
|
||||
- Setup-validation tests cover duplicate model identifiers, missing or unknown defaults, malformed
|
||||
provider settings, missing secret references, safe public model projection, and strict separation
|
||||
from Pi and workspace model settings.
|
||||
- Database Management tests use the existing browser-level component seam with MSW. They verify
|
||||
model selection and default, selected/all/missing actions, disabled state without models, running
|
||||
progress and logs, polling recovery, cancellation, Unlock visibility, terminal summaries,
|
||||
generated-text refresh, and selected consolidation with copied/skipped counts.
|
||||
- Existing Catalog Sync Run route, repository, SSE, and drawer tests are prior art for asynchronous
|
||||
status and event behavior. Existing catalog table/column editing and Database Management tests
|
||||
are prior art for optimistic catalog updates, permissions, selection, and action controls.
|
||||
- One required manual acceptance gate, outside deterministic CI, uses the installation's configured
|
||||
default model and a disposable PostgreSQL database containing only invented data. Its application
|
||||
credentials are read-only. It generates Italian text for one Catalog Column and one Catalog
|
||||
Table, verifies their Generated Description, inspects the safe activity log, confirms that no key
|
||||
or sample value is exposed, and consolidates one selected result. If the configured secret is not
|
||||
available, acceptance stops without exposing or requesting the key in conversation.
|
||||
- Delivery includes a strict MkDocs build executed through repository-managed, reproducible
|
||||
documentation dependencies rather than globally installed Python packages. A readable direct
|
||||
dependency file is retained, a complete transitive lock is generated with `uv`, and one canonical
|
||||
repository command performs the strict build from that lock.
|
||||
- Successful real-provider acceptance is recorded in a short sanitized report under
|
||||
`docs/testing/`. It identifies the model and checks performed but contains no credentials,
|
||||
prompts, source samples, complete provider payloads, or generated database values.
|
||||
- No tests are added for worker queues, parallel generation, distributed locking, multi-replica
|
||||
recovery, automatic resume, cost accounting, or model fallback because those behaviors are out
|
||||
of scope.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- Reusing Pi to execute Description Generation or changing Pi's model configuration.
|
||||
- A shared Installation Model Registry, model gateway, long-lived Python sidecar, or provider
|
||||
management platform.
|
||||
- A user-facing generation CLI.
|
||||
- Parallel model calls, worker queues, adaptive rate limiting, distributed locks, leases,
|
||||
heartbeats, automatic resume, or multi-replica execution.
|
||||
- Durable target jobs, invocation history, prompts, samples, token usage, cost accounting,
|
||||
provenance chains, target snapshots, or advanced retention controls.
|
||||
- Automatic retry or resume of individual targets beyond one technical helper retry and a new
|
||||
Generate Missing run.
|
||||
- Automatic fallback to a different model.
|
||||
- Writing generated text into comments of the external Workspace Database.
|
||||
- Generating logical relationships or other catalog metadata beyond Catalog Table and Catalog
|
||||
Column descriptions.
|
||||
- Implementing the Sensitive Data Policy. Its definition and exclusion/anonymization behavior are
|
||||
a required follow-up improvement.
|
||||
- Generalizing the log viewer across unrelated metadata operations. That broader concern remains
|
||||
related to Gitea issue #2.
|
||||
|
||||
## Further Notes
|
||||
|
||||
- The design deliberately follows ThothAI's proven simple workflow while adapting it to ThothII's
|
||||
asynchronous browser interaction, setup ownership, and existing Generated Description model.
|
||||
- The source-sampling disclosure is a release requirement, not merely documentation for operators.
|
||||
- `completed_with_errors` is reserved for a run that reaches the end after isolated technical
|
||||
failures. Three consecutive failures end the run as `failed`.
|
||||
- Successful values are their own recovery record: after interruption, Generate Missing naturally
|
||||
skips them without needing replay state.
|
||||
- The implementation is available without a feature flag once the catalog migration and valid
|
||||
setup are present. With no configured model, the feature remains visibly unavailable rather than
|
||||
partially initialized.
|
||||
- The final manual gate is intentionally narrow: one real-provider run covers one Catalog Column
|
||||
and one Catalog Table, generated Italian text, safe events, and one consolidation. Automated
|
||||
tests remain the evidence for All, Missing, Stop, restart interruption, Unlock, and failure paths.
|
||||
@@ -1,173 +0,0 @@
|
||||
# AI catalog description generation
|
||||
|
||||
Status: simplified design, API, persistence, test seams, and delivery tickets accepted.
|
||||
|
||||
## Objective
|
||||
|
||||
Bring ThothAI's useful AI comment-generation workflow into the ThothII Metadata Catalog without
|
||||
turning it into a general job platform. Administrators can generate editable descriptions for
|
||||
catalog tables and columns, inspect progress, stop a run, recover a stale run, and explicitly copy
|
||||
approved generated text into the curated Description field.
|
||||
|
||||
The implementation is UI/API only. There is no user-facing generation command.
|
||||
|
||||
## ThothAI behavior retained
|
||||
|
||||
- Generate descriptions for selected tables, selected columns, missing descriptions, or all
|
||||
eligible targets.
|
||||
- Generate columns before their containing table when running the full workflow, so table prompts
|
||||
can benefit from the resulting column descriptions.
|
||||
- Process bounded batches of at most ten targets, one model request at a time.
|
||||
- Include schema context, existing catalog text, up to five real source rows, and up to five
|
||||
representative non-null values when available.
|
||||
- Keep generated text separate from the curated Description until an administrator consolidates
|
||||
it.
|
||||
- Use the existing table and column checkboxes plus the Actions selector to copy Generated
|
||||
Description into Description for one or more selected records. The generated value is retained.
|
||||
- Store a localized standard value such as `Non generabile` when a valid model response says that
|
||||
a description cannot be inferred.
|
||||
|
||||
Unlike ThothAI, every generation action is asynchronous from the browser's perspective and exposes
|
||||
a persistent, readable activity log.
|
||||
|
||||
## Minimal architecture
|
||||
|
||||
The Fastify backend owns the run lifecycle and sequential loop. It starts one short-lived Python
|
||||
helper for each model completion. The helper uses LiteLLM, accepts structured input on stdin,
|
||||
returns structured output on stdout, and writes diagnostics only to stderr.
|
||||
|
||||
This is preferred over reusing Pi. Pi remains the interactive NL-to-SQL orchestration surface,
|
||||
whereas description generation is a bounded batch transformation with no conversational state or
|
||||
human gate. A LiteLLM helper avoids inventing a Pi session protocol for a task that needs one
|
||||
request and one structured response.
|
||||
|
||||
There is no Python daemon, model gateway, queue service, worker pool, or generation CLI. Python is
|
||||
already a core implementation language in ThothII's harness and core image; this helper does not
|
||||
introduce a new runtime family.
|
||||
|
||||
## Run lifecycle and exclusion
|
||||
|
||||
- At most one Description Generation Run may be queued or running in the installation.
|
||||
- Start returns immediately after creating the run and scheduling the in-process backend loop.
|
||||
- Requests are sequential; there is no parallel provider traffic.
|
||||
- The target Workspace Database is reserved through the existing in-memory catalog-operation
|
||||
coordinator. Synchronization, cleanup, consolidation, and direct catalog edits for that database
|
||||
are rejected while generation is active.
|
||||
- A second generation start is rejected with a conflict response.
|
||||
- Stop terminates the current helper process, stops further targets, and marks the run cancelled.
|
||||
- Backend startup marks any queued or running generation row interrupted. It does not resume work.
|
||||
- Generate Missing is the normal manual continuation mechanism because successful values were
|
||||
already saved.
|
||||
- Unlock is available only when the backend has no live generation process; it marks a stale
|
||||
recorded run interrupted and clears the local reservation.
|
||||
|
||||
This is intentionally a single-process policy. Multi-replica coordination is out of scope.
|
||||
|
||||
## Persistence
|
||||
|
||||
Persist only:
|
||||
|
||||
- a Description Generation Run with database, scope, selected model, language, status, counters,
|
||||
timestamps, and an optional final error summary;
|
||||
- ordered Description Generation Events containing timestamp, level, and human-readable text;
|
||||
- each successful or non-generatable result directly in the target's Generated Description.
|
||||
|
||||
Do not add per-target job rows, invocation history, prompt or sample snapshots, provider cost
|
||||
accounting, leases, heartbeats, registry revisions, or generated-description provenance. The event
|
||||
log is operational evidence, not a replay mechanism.
|
||||
|
||||
## Model setup
|
||||
|
||||
Selectable models and their default belong to application setup YAML, not to a workspace. Each
|
||||
entry supplies a stable display identifier, LiteLLM provider/model information, optional endpoint
|
||||
settings, and—unless that explicit endpoint is unauthenticated—a reference to an installation
|
||||
secret containing the API key. Keyless entries without an explicit endpoint are invalid. Raw keys must not be
|
||||
stored in the YAML, database, frontend, events, or process arguments.
|
||||
An explicit endpoint may opt into `disableThinking: true` when its Qwen-compatible chat template
|
||||
would otherwise place reasoning text around the required JSON result.
|
||||
|
||||
This metadata-generation configuration is independent of the existing Pi provider/model settings
|
||||
and workspace `llm_policy`. A setup change takes effect after application restart. If no model is
|
||||
configured, generation controls are disabled with an explanatory message.
|
||||
|
||||
The browser receives only the selectable identifiers and labels. The selected value defaults to
|
||||
the setup default and is validated again by the backend when a run starts.
|
||||
|
||||
## Prompt inputs and outputs
|
||||
|
||||
Targets are grouped in model requests of at most ten. Prompts distinguish instructions from
|
||||
untrusted schema names, comments, descriptions, and sampled values. A response must map every
|
||||
returned result to a requested target and classify it as generated or non-generatable. Missing,
|
||||
duplicate, unknown, or malformed target results make that request a technical failure rather than
|
||||
silently writing ambiguous text.
|
||||
One complete `json` code fence around the object is tolerated for model compatibility; prose
|
||||
outside it, multiple payloads, and ambiguous mappings are still rejected.
|
||||
|
||||
For a complete database run, eligible columns are processed before tables. A table request can use
|
||||
the current Generated Description or Description of its columns. The output language is the
|
||||
workspace language; the standard non-generatable text is localized by the application rather than
|
||||
trusted to arbitrary model wording.
|
||||
|
||||
Up to five source rows and five representative examples may be sent to the provider and are never
|
||||
persisted. Delivery must call out this disclosure. A follow-up Sensitive Data Policy will define
|
||||
which values are excluded or anonymized.
|
||||
|
||||
## Errors, retry, and logs
|
||||
|
||||
The helper performs at most one retry for a transient technical provider failure. A final failed
|
||||
request produces an error event and increments the consecutive-error count. The run stops as
|
||||
failed after three consecutive technical failures; any successful request resets the count. There
|
||||
is no automatic fallback to another model.
|
||||
|
||||
Valid non-generatable outcomes are results, not technical errors. Successful results from earlier
|
||||
requests remain stored when a later request fails or the run is stopped.
|
||||
|
||||
The UI shows status, counters, selected model, start/end times, and a chronological text log. Live
|
||||
delivery may reuse the existing SSE infrastructure with polling as fallback; exact visual parity
|
||||
with synchronization logs is not required. Logs must not contain API keys, prompts, source sample
|
||||
values, or full provider payloads.
|
||||
|
||||
## Explicitly deferred complexity
|
||||
|
||||
- shared model registry or cutover of Pi configuration;
|
||||
- long-lived Python sidecar or internal HTTP model gateway;
|
||||
- generic catalog-operation kernel;
|
||||
- durable target items, invocation records, target snapshots, or provenance chains;
|
||||
- distributed locks, leases, heartbeats, worker queues, automatic resume, or multi-replica support;
|
||||
- parallel calls, adaptive rate limiting, cost estimation, advanced metrics, or model fallback;
|
||||
- user-facing generation CLI;
|
||||
- automatic writeback to comments in the external database;
|
||||
- Sensitive Data Policy implementation, which remains a required improvement after this slice.
|
||||
|
||||
## Delivery tracking
|
||||
|
||||
The accepted specification is Gitea issue #4 and the implementation is split into issues #5–#11.
|
||||
Each ticket is a bounded vertical slice with explicit Gitea dependencies. Implementation proceeds
|
||||
from the unblocked frontier, using a fresh subagent context for each ticket; integration and final
|
||||
verification remain centralized so later slices cannot silently reopen the deferred platform
|
||||
features above.
|
||||
|
||||
Issue #4 remains open until delivery completes four final gates: the stale Compose service-set
|
||||
contract is corrected in its own commit; documentation dependencies are repository-managed and a
|
||||
strict MkDocs build passes; one narrow real-provider acceptance run succeeds against non-sensitive
|
||||
test data; and a separate, non-blocking Sensitive Data Policy design ticket is linked as required
|
||||
follow-up work.
|
||||
|
||||
The documentation toolchain retains a readable direct-dependency input, adds a complete lock
|
||||
generated with `uv`, and exposes one canonical strict-build command. Real-provider acceptance uses
|
||||
the installation's configured default model and a disposable PostgreSQL database seeded only with
|
||||
invented values and accessed read-only by the application. A missing protected model secret stops
|
||||
the gate without disclosing it. The successful gate is captured in a sanitized report under
|
||||
`docs/testing/` without prompts, samples, full generated values, payloads, or credentials.
|
||||
|
||||
Delivery is organized as four reviewable commits: the stale Compose contract correction, the
|
||||
reproducible documentation toolchain, the AI-description feature, and—only after acceptance—the
|
||||
sanitized acceptance report. A failed real-provider gate does not invalidate already verified
|
||||
commits, but issue #4 remains open and no acceptance report claims success. Application defects are
|
||||
fixed and reverified; missing configuration or provider unavailability is recorded and retried.
|
||||
|
||||
After every gate passes, the existing `codex/db-management` branch is pushed to its configured
|
||||
origin without introducing a new pull-request workflow, then issue #4 is closed with links to the
|
||||
delivery evidence. The separate Sensitive Data Policy issue is created as non-blocking follow-up,
|
||||
linked to #4, and labeled `enhancement` plus `ready-for-human` because its design requires a future
|
||||
`grill-with-docs` before agent implementation.
|
||||
@@ -1,248 +0,0 @@
|
||||
# Installation Model Catalog
|
||||
|
||||
Status: implemented on 2026-09-02.
|
||||
|
||||
## Outcome
|
||||
|
||||
`thothii-installation.yaml` is the only operator-authored source for models used by interactive
|
||||
sessions, metadata generation, and embedding. Runtime-specific files are deterministic projections,
|
||||
not additional configuration sources. Workspace descriptors contain database and Evidence concerns
|
||||
and no model, provider, allowlist, default, embedding, or vector-store configuration.
|
||||
|
||||
This design does not merge execution lifecycles. Pi continues to run interactive sessions, the
|
||||
short-lived LiteLLM helper continues to perform metadata generation, and the internal Ollama service
|
||||
continues to provide embeddings. They share model declaration, not execution machinery.
|
||||
|
||||
## Canonical installation shape
|
||||
|
||||
The following example covers all currently required cases: a Pi built-in model, an authenticated
|
||||
custom endpoint, a keyless internal endpoint, metadata generation, and the single embedding model.
|
||||
|
||||
```yaml
|
||||
schemaVersion: 2
|
||||
profile: server
|
||||
projectDirectory: /srv/thothii
|
||||
envFile: /srv/thothii/operator.env
|
||||
|
||||
workspaceRepository:
|
||||
remote: git@git.example.com:organization/workspaces.git
|
||||
branch: main
|
||||
access: ssh
|
||||
|
||||
modelCatalog:
|
||||
defaults:
|
||||
session: zai/glm-5.3
|
||||
metadataGeneration: local-qwen/qwen3.6-35b-a3b
|
||||
|
||||
embedding:
|
||||
id: ollama/qwen3-embedding:0.6b
|
||||
dimensions: 1024
|
||||
|
||||
providers:
|
||||
deepseek:
|
||||
authentication:
|
||||
mode: pi_auth
|
||||
session:
|
||||
mode: pi_builtin
|
||||
models:
|
||||
deepseek-v4-pro:
|
||||
session: {}
|
||||
deepseek-v4-flash:
|
||||
session: {}
|
||||
|
||||
zai:
|
||||
endpoint:
|
||||
baseUrl: https://api.z.ai/api/coding/paas/v4
|
||||
authentication:
|
||||
mode: secret_env
|
||||
apiKeyEnv: ZAI_API_KEY
|
||||
session:
|
||||
mode: openai_compatible
|
||||
metadataGeneration:
|
||||
litellmProvider: openai
|
||||
models:
|
||||
glm-5.3:
|
||||
label: GLM-5.3
|
||||
session:
|
||||
reasoning: true
|
||||
contextWindow: 200000
|
||||
maxTokens: 131072
|
||||
metadataGeneration: {}
|
||||
|
||||
local-qwen:
|
||||
endpoint:
|
||||
baseUrl: https://ml-aritmolab.policlinicosandonato.it/v1
|
||||
authentication:
|
||||
mode: none
|
||||
session:
|
||||
mode: openai_compatible
|
||||
metadataGeneration:
|
||||
litellmProvider: openai
|
||||
models:
|
||||
qwen3.6-35b-a3b:
|
||||
label: Qwen3.6 35B A3B
|
||||
session:
|
||||
reasoning: false
|
||||
contextWindow: 131072
|
||||
maxTokens: 16384
|
||||
compatibility:
|
||||
supportsDeveloperRole: false
|
||||
supportsReasoningEffort: false
|
||||
supportsStore: false
|
||||
maxTokensField: max_tokens
|
||||
metadataGeneration:
|
||||
disableThinking: true
|
||||
|
||||
authentication:
|
||||
configDirectory: /srv/thothii/auth-canonical
|
||||
runtimeProjection:
|
||||
directory: /srv/thothii/auth-runtime
|
||||
uid: 10001
|
||||
gid: 10001
|
||||
```
|
||||
|
||||
The catalog uses maps instead of repeated IDs. The canonical identity of a model is always derived
|
||||
as `<provider-key>/<model-key>`. `upstreamModel` may be added to a model only when the endpoint uses
|
||||
a different identifier. `label` is optional and falls back to the canonical identity.
|
||||
|
||||
Model eligibility is not repeated in an `usages` array. A `session` block makes the model eligible
|
||||
for sessions; a `metadataGeneration` block makes it eligible for metadata generation. The embedding
|
||||
is a single required installation value rather than a list plus default.
|
||||
|
||||
## Provider and authentication rules
|
||||
|
||||
A provider owns one endpoint, one authentication mode, and zero or one adapter for each runtime.
|
||||
Model entries cannot override provider endpoint or credentials. If the same upstream service needs
|
||||
different endpoints or credentials, the installation declares two provider identities.
|
||||
|
||||
Supported session modes are intentionally closed:
|
||||
|
||||
- `pi_builtin`: Pi already owns the model's technical descriptor; the model's `session` block is
|
||||
empty and ThothII does not copy context-window or compatibility facts.
|
||||
- `openai_compatible`: ThothII generates a Pi custom-provider descriptor; each session model supplies
|
||||
the technical values required by Pi.
|
||||
|
||||
Metadata generation uses the provider-level `litellmProvider`. A model-level
|
||||
`metadataGeneration.disableThinking: true` is permitted only for an explicit compatible endpoint.
|
||||
There is no generic adapter or plugin abstraction in schema version 2.
|
||||
|
||||
Exactly one provider authentication mode is allowed:
|
||||
|
||||
- `secret_env` requires an approved API-key environment reference present in the protected secret
|
||||
bundle. Secret values never enter YAML, generated files, logs, arguments, or API responses.
|
||||
- `pi_auth` is valid only for session-only `pi_builtin` providers and resolves through Pi's protected
|
||||
authentication projection.
|
||||
- `none` is valid only for an explicit endpoint. Runtime projections may supply a fixed non-secret
|
||||
compatibility placeholder when a client library requires a non-empty key.
|
||||
|
||||
## Defaults and selections
|
||||
|
||||
`defaults.session` and `embedding` are required. `defaults.metadataGeneration` is required exactly
|
||||
when at least one model has a `metadataGeneration` block; metadata generation may otherwise be
|
||||
absent and its UI controls are disabled.
|
||||
|
||||
`modelCatalog.defaults.session` is the only configured session-model default. `PI_PROVIDER`,
|
||||
`PI_MODEL`, and provider/model fields in installation-default settings are removed. A user choice is
|
||||
a Model Selection containing only the canonical model identity and runtime controls such as thinking
|
||||
level. A session manifest pins the selected canonical identity.
|
||||
|
||||
Removing the currently selected model causes new-session selection to fall back to the catalog
|
||||
default with an explicit administrative warning. An existing session is never silently moved to a
|
||||
different model; resume fails with `model_unavailable` when its pinned identity can no longer be
|
||||
resolved.
|
||||
|
||||
## Generated runtime projections
|
||||
|
||||
Before Compose starts, `tht` strictly validates schema version 2 and generates installation-local
|
||||
artifacts below `deploy/<installation-id>/generated/`:
|
||||
|
||||
- a normalized catalog JSON consumed defensively by the backend;
|
||||
- Pi `models.json` for custom providers;
|
||||
- Pi `settings.json`, combining fixed product settings with the session-eligible canonical IDs;
|
||||
- a Compose override that mounts the projections and supplies embedding identity and dimensions to
|
||||
core, preprocessing, and `embedding-model-init`.
|
||||
|
||||
Generation is deterministic and published only after every candidate artifact validates. A failed
|
||||
generation aborts start before Compose is invoked. `tht doctor` recomputes expected bytes and reports
|
||||
differences; no digest manifest or separate apply command exists. When projection bytes change,
|
||||
`tht start` recreates the affected services so they cannot continue with an older bind mount.
|
||||
Pi-only restart, update, and rollback operations reject projection drift and direct the operator to
|
||||
`tht start`, because applying only the core-facing files could leave embedding services stale.
|
||||
|
||||
Generated projections are not backed up. Restore validates the canonical installation descriptor,
|
||||
regenerates every projection, and only then starts services. Base Compose files and `operator.env`
|
||||
must contain no model identities, defaults, endpoints, or dimensions.
|
||||
|
||||
## Workspace schema v4
|
||||
|
||||
Workspace schema v4 removes both top-level `llm_policy` and `semantic_index`. The entire latter
|
||||
block is redundant today: its engine and distance are product constants, its collection duplicates
|
||||
the workspace ID, and its model and dimensions are installation facts.
|
||||
|
||||
The runtime derives:
|
||||
|
||||
- Qdrant collection identity from the workspace ID;
|
||||
- engine and distance from the supported product contract;
|
||||
- embedding identity and dimensions from the Installation Model Catalog.
|
||||
|
||||
The published index generation records the canonical embedding identity and dimensions that created
|
||||
it. A mismatch makes the index explicitly incompatible and requires operator-triggered
|
||||
preprocessing. No existing index is deleted or rebuilt automatically.
|
||||
|
||||
The v3-to-v4 workspace migration is deterministic: set `workspace.schema_version` to `4`, remove
|
||||
`llm_policy`, and remove `semantic_index`. It does not alter database, Evidence, diagnostics, or
|
||||
binding data.
|
||||
|
||||
## Installation migration
|
||||
|
||||
Legacy installation migration must inspect all three former sources:
|
||||
|
||||
1. `metadataGeneration` in `thothii-installation.yaml`;
|
||||
2. `deploy/pi/models.json`;
|
||||
3. `deploy/pi/settings.json`.
|
||||
|
||||
The migrator emits a version-2 candidate only when it can reconcile identities, endpoints,
|
||||
credentials, and runtime-specific facts without guessing. Ambiguous aliases such as `glm-53`,
|
||||
`zai/glm-5.3`, and `openai/glm-5.3` are not silently equated. A conflict produces a field-level
|
||||
report and leaves every input unchanged for operator resolution.
|
||||
|
||||
After migration, the strict loader rejects `metadataGeneration`, workspace `llm_policy`, workspace
|
||||
`semantic_index`, legacy Pi source files, unknown fields, duplicate YAML keys, invalid defaults, and
|
||||
incompatible authentication/adapter combinations with an actionable `migration_required` or
|
||||
validation error.
|
||||
|
||||
## Final simplicity audit
|
||||
|
||||
The accepted design removes every configuration duplication that can be removed without inference:
|
||||
|
||||
- one authored installation file instead of an installation block plus two Pi files;
|
||||
- one canonical `provider/model` identity instead of display IDs and runtime IDs;
|
||||
- per-use blocks instead of a duplicated usages list;
|
||||
- one embedding entry instead of a selectable embedding catalog;
|
||||
- one catalog session default instead of environment and settings defaults;
|
||||
- no model or vector-store fields in workspace descriptors;
|
||||
- provider-level credentials instead of per-model credentials;
|
||||
- no generic runtime-plugin abstraction;
|
||||
- no persisted digest, apply command, or backup of generated projections.
|
||||
|
||||
The remaining generated files are necessary boundary adapters, not configuration concepts. Making
|
||||
the backend parse the authoring YAML independently would remove one file but restore two semantic
|
||||
validators. Hard-coding embedding values in Compose would remove one projection but restore a model
|
||||
source outside the catalog. Inferring authentication from missing fields would save one YAML key but
|
||||
turn a safe explicit choice into ambiguity. These apparent simplifications are therefore rejected.
|
||||
|
||||
No further reduction was found that preserves one authority, strict validation, explicit security,
|
||||
session determinism, and model-free workspaces.
|
||||
|
||||
## Implementation surface
|
||||
|
||||
Implementation must update the host `tht` installation loader, setup and lifecycle projection,
|
||||
doctor, backup/restore, Compose mounts and embedding inputs, backend catalog/settings/session model
|
||||
resolution, workspace schema and migration, runtime rendering and diagnostics, frontend workspace
|
||||
drafts and model filtering, examples, fixtures, and documentation. Existing session manifests remain
|
||||
readable and keep their pinned provider/model identity; only resume resolution changes to the new
|
||||
catalog.
|
||||
|
||||
Implementation completed after explicit approval. The installation schema, deterministic runtime
|
||||
projections, migration path, model-free workspace schema v4, backend consumers, operator UI,
|
||||
fixtures, and documentation now enforce this contract.
|
||||
@@ -5,9 +5,9 @@ manuale con commit/push dell'operatore accettati per la release 0;
|
||||
restanti semplificazioni confermate, con chiarimenti su impatto core e controllo Git;
|
||||
E1, E2, E3 e il collegamento ai gate X1 implementati il 2026-09-09.
|
||||
Il contratto X1 è in [Session corrections](../contracts/archive-repair.md). Risultati e limiti in
|
||||
[E1 — validazione](2026-09-09-evidence-e1-validation.md) e
|
||||
[E2 — validazione](2026-09-09-evidence-e2-validation.md) e
|
||||
[E3 — validazione](2026-09-09-evidence-e3-validation.md).
|
||||
[E1 — validazione](../reports/knowledge-archives-release.md) e
|
||||
[E2 — validazione](../reports/knowledge-archives-release.md) e
|
||||
[E3 — validazione](../reports/knowledge-archives-release.md).
|
||||
|
||||
La [revisione di semplicità](2026-09-08-memory-evidence-simplification-review.md)
|
||||
registra il riesame di Q1–Q15. Il flusso principale è draft scritta dallo specialista
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Data del piano: 2026-09-08. Aggiornamento 2026-09-09: M1–M3, E1–E3 e X1
|
||||
implementati. Risultati e limiti della verifica finale sono raccolti nel
|
||||
[rapporto X1](2026-09-09-archive-repair-x1-validation.md).
|
||||
[rapporto X1](../reports/knowledge-archives-release.md).
|
||||
|
||||
La [revisione di semplicità](2026-09-08-memory-evidence-simplification-review.md)
|
||||
riesamina tutte le decisioni Q1–Q15 alla luce degli ultimi chiarimenti del
|
||||
|
||||
@@ -6,7 +6,7 @@ confini di test confermati dal proprietario il 2026-09-08.
|
||||
Primo incremento del progetto Memory management. Attua le decisioni già approvate
|
||||
nel piano del 2026-09-08 e nell'ADR 0018. Le scelte tecniche di dettaglio qui
|
||||
proposte derivano dalla ricognizione del runtime. Gli esiti dell'implementazione
|
||||
sono riportati nel [rapporto di verifica](2026-09-08-memory-m1-validation.md).
|
||||
sono riportati nel [rapporto di verifica](../reports/knowledge-archives-release.md).
|
||||
|
||||
## Problem Statement
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# M1 — Implementazione e verifica
|
||||
|
||||
Data: 2026-09-08. Implementazione locale della
|
||||
[specifica approvata](2026-09-08-memory-m1-spec.md), associata all'
|
||||
[issue 27](https://git.tylconsulting.it/mptyl/ThothII/issues/27).
|
||||
|
||||
## Risultato
|
||||
|
||||
La pagina **Memory management** è disponibile nell'Administration dopo Database
|
||||
management. Gestisce le quattro famiglie di card, elenco completo, ricerca e filtri,
|
||||
ordinamento, dettaglio, creazione, modifica, cancellazione, collegamenti e dipendenze.
|
||||
Richiede un amministratore autenticato e una selezione esplicita del workspace;
|
||||
non richiede una sessione o un database DWH configurato.
|
||||
|
||||
Il harness possiede l'archivio PostgreSQL `thoth_memory`. Card, collegamenti,
|
||||
dipendenze e lavoro di propagazione sono salvati nella stessa transazione.
|
||||
La pagina distingue salvataggio fallito e contenuto salvato con indice incompleto,
|
||||
offrendo retry anche per le cancellazioni. Recall Memory ed exemplar verificano
|
||||
esistenza, workspace e proiezione corrente nell'archivio prima di restituire contenuto.
|
||||
|
||||
Promozione, salvataggio singolo e finalizzazione corrente passano dal servizio
|
||||
autorevole. Le ricevute della sorgente impediscono duplicati e ricreazione di card
|
||||
cancellate. Reindicizzazione e preprocessing non importano vecchi payload o sessioni.
|
||||
L'errore Memory non annulla una sessione già finalizzata; il gate segnala anche
|
||||
una promozione salvata con indicizzazione incompleta.
|
||||
|
||||
Le migrazioni sono versionate, controllate tramite checksum e incluse nel wheel
|
||||
e nell'immagine core. Il servizio di preparazione `catalog-migrate` le esegue dopo
|
||||
quelle del Catalog. Il runtime assume il ruolo limitato `thoth_memory_runtime`,
|
||||
con isolamento del workspace tramite RLS e senza privilegi DDL.
|
||||
|
||||
## Verifiche eseguite
|
||||
|
||||
| Confine | Esito |
|
||||
| --- | --- |
|
||||
| Harness, test senza L0/L2 | 1.134 passati; i 9 test dei percorsi portabili sono stati eseguiti separatamente e sono passati. |
|
||||
| Servizio Memory, PostgreSQL e Qdrant reali | 17 passati, inclusi CLI, migrazioni, ruolo runtime, isolamento, transazioni, outage, retry, cancellazioni, cambio famiglia e rebuild. |
|
||||
| Gate Pi | 190 passati, inclusi identità UUID e avviso dopo salvataggio con indice incompleto. |
|
||||
| Backend | 1.345 passati nella suite completa, 40 esclusi dalle condizioni previste dai test; un test di autenticazione ha superato il timeout sotto carico. Il relativo file è stato rieseguito isolato: tutti i 17 test passati. |
|
||||
| Frontend | 632 passati, inclusi ingresso dall'AppShell, form, filtri, collegamenti, dipendenze e retry delle cancellazioni. |
|
||||
| Browser integrato | Passato: autenticazione amministratore, creazione, modifica, riavvio del backend, rilettura, cancellazione e assenza nel recall. |
|
||||
| Build e tipi | Build backend e frontend, typecheck TypeScript e build documentale strict superati. |
|
||||
| Lint e diff | Ruff sui file Python modificati e `git diff --check` superati. Il lint globale segnala tre rilievi in file non modificati, elencati sotto. |
|
||||
|
||||
Il browser utilizza autenticamente frontend, login locale, Fastify, ThtRunner,
|
||||
CLI Python, PostgreSQL e Qdrant. Gli embedding sono deterministici e le attività
|
||||
Pi/sessione estranee al percorso Memory usano le fixture esistenti. Non sono state
|
||||
intercettate le API Memory. Sono stati usati container temporanei PostgreSQL 16 e
|
||||
Qdrant 1.18.2, senza accesso a un DWH remoto o a un modello generativo.
|
||||
|
||||
Il test browser ha consentito di correggere etichette accessibili instabili nei
|
||||
campi compilati e la sovrapposizione del pannello di recupero ai comandi del dettaglio.
|
||||
La selezione del workspace e l'uscita dalla pagina sono bloccate durante le operazioni.
|
||||
|
||||
Il lint globale preesistente riguarda soltanto:
|
||||
|
||||
- ordinamento import in `harness/tests/test_effective_relationships.py`;
|
||||
- ordinamento import in `harness/tests/test_p3_dwh_binding.py`;
|
||||
- uso di `datetime.UTC` in `harness/tht/mschema/catalog_snapshot.py`.
|
||||
|
||||
## Riproduzione
|
||||
|
||||
Usare Node 24 e le dipendenze installate dei tre layer. Per eseguire il harness
|
||||
in un ambiente con home non scrivibile si può impostare `THT_HOME` su una directory
|
||||
di prova. I test dei percorsi portabili devono essere eseguiti senza questo override,
|
||||
perché verificano deliberatamente la risoluzione dell'home e di `THT_DATA_ROOT`.
|
||||
|
||||
```sh
|
||||
cd harness
|
||||
THT_HOME=/private/tmp/thothii-m1-test-home .venv/bin/pytest -m 'not l0 and not l2' --ignore=tests/test_portable_paths.py -q
|
||||
.venv/bin/pytest tests/test_portable_paths.py -q
|
||||
.venv/bin/pytest tests/memory/test_administration.py -q
|
||||
npm test
|
||||
```
|
||||
|
||||
```sh
|
||||
cd backend
|
||||
npx vitest run
|
||||
npx tsc --noEmit -p .
|
||||
npm run build
|
||||
```
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
npx vitest run
|
||||
npx tsc -b
|
||||
npm run build
|
||||
THT_MEMORY_BROWSER_E2E=1 npx playwright test e2e/memory-real.spec.ts
|
||||
```
|
||||
|
||||
Il percorso browser richiede Docker, Python del harness, Go per il bridge di
|
||||
autenticazione e Chromium di Playwright. Avvia risorse isolate e le rimuove alla
|
||||
fine. Su macOS il browser deve poter avviare i processi Chromium fuori dalle
|
||||
restrizioni della sandbox. La build documentale si esegue dalla radice con
|
||||
`./scripts/build-docs.sh`.
|
||||
|
||||
## Stato della consegna
|
||||
|
||||
Le modifiche sono nel worktree locale. Nessuno stack già attivo è stato aggiornato
|
||||
e nessun dato esistente è stato migrato o eliminato. Prima di usare M1 su
|
||||
un'installazione occorrono il nuovo core e la preparazione `catalog-migrate`.
|
||||
M2 (retrieval ibrido ed espansione dei collegamenti), M3 (integrazione estesa nel
|
||||
workflow) ed Evidence management restano incrementi successivi.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Data del piano: 2026-09-08. Aggiornamento 2026-09-09: M1–M3 implementati,
|
||||
con integrazione X1 per le correzioni persistenti dei conflitti. Risultati e limiti
|
||||
sono raccolti nel [rapporto X1](2026-09-09-archive-repair-x1-validation.md).
|
||||
sono raccolti nel [rapporto X1](../reports/knowledge-archives-release.md).
|
||||
|
||||
La [revisione di semplicità](2026-09-08-memory-evidence-simplification-review.md)
|
||||
mantiene il perimetro Memory e precisa un salvataggio sequenziale e una pulizia
|
||||
|
||||
@@ -1,9 +1,31 @@
|
||||
# PRD — Security hardening per Docker personale e server multiutente
|
||||
|
||||
## Ripresa del lavoro e limiti di autorizzazione
|
||||
|
||||
Questo PRD resta una bozza, non una specifica di implementazione approvata. Il precedente
|
||||
prompt di ripresa è stato consolidato qui il 15 settembre 2026. Riconfermare i rilievi
|
||||
SEC-01–SEC-12 contro codice e dipendenze correnti, separando fatti, ipotesi, rischi del
|
||||
profilo locale/server e problemi già risolti. Le vecchie survey non provano lo stato del server.
|
||||
Usare inizialmente controlli in sola lettura e dati sintetici; accesso a server, IdP, DWH
|
||||
o provider e relative mutazioni richiedono target e operazioni concordati.
|
||||
|
||||
Prima di implementare, il proprietario deve confermare profili di fiducia, isolamento
|
||||
del runtime Pi, trattamento dei valori sensibili, revoca, retention, limiti di risorse,
|
||||
priorità e criteri misurabili. I modelli visibili sul server sono un problema separato.
|
||||
Registrare le decisioni in questo PRD; pubblicare spec e ticket Gitea soltanto dopo la
|
||||
conferma del perimetro e della granularità. La bonifica documentale non autorizza il
|
||||
codice di sicurezza, né il rollout di tutti i punti SEC.
|
||||
|
||||
L'implementazione futura richiede un worktree dedicato, test positivi/negativi ai confini
|
||||
concordati, typecheck e revisione contro standard e specifica. Conservare gate manuali,
|
||||
evidenze e rollback; un ticket completato non chiude automaticamente il PRD. Non copiare
|
||||
segreti o dati operativi nei worktree. Usare le skill effettivamente disponibili per
|
||||
chiarimento, diagnosi e revisione, senza assumere che i vecchi nomi dei comandi esistano.
|
||||
|
||||
**Stato:** bozza da validare con `grill-with-docs`; implementazione rinviata.
|
||||
**Data:** 8 settembre 2026.
|
||||
**Owner delle decisioni:** il maintainer di ThothII.
|
||||
**Ripresa:** [prompt per la prossima sessione](2026-09-08-security-hardening-resume-prompt.md).
|
||||
**Ripresa:** seguire la sezione «Ripresa del lavoro e limiti di autorizzazione» sopra.
|
||||
|
||||
Questo documento conserva la survey di sicurezza discussa con il maintainer e propone requisiti,
|
||||
priorità e criteri di accettazione. Non è una spec approvata, un penetration test, una certificazione
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
# Riprendere il PRD di sicurezza con le skill di Pocock
|
||||
|
||||
**Stato:** prompt conservato per uso futuro; nessuna esecuzione programmata.
|
||||
**PRD:** [Security hardening per Docker personale e server multiutente](2026-09-08-security-hardening-prd.md).
|
||||
|
||||
Apri una sessione nella codebase ThothII e incolla il blocco seguente. Il nome corretto della
|
||||
skill è `grill-with-docs`, che combina `grilling` e `domain-modeling`. Il prompt apre la fase di
|
||||
chiarimento; il passaggio a issue, worktree e implementazione resta soggetto alle conferme indicate.
|
||||
|
||||
```text
|
||||
Riprendiamo il lavoro di sicurezza rinviato l'8 settembre 2026.
|
||||
|
||||
Leggi docs/plans/2026-09-08-security-hardening-prd.md. È una bozza di PRD ricavata da una
|
||||
survey storica, non una spec approvata né una prova della configurazione del server remoto.
|
||||
Voglio preparare interventi proporzionati per Docker su Mac/PC personale e per un server
|
||||
multiutente con autenticazione built-in oppure OIDC. Il problema separato dei modelli
|
||||
visibili sul server è fuori perimetro.
|
||||
|
||||
Usa realmente le skill di Matt Pocock: leggi le istruzioni installate, dichiarando quali
|
||||
applichi. Parti da ask-matt per verificare il percorso e da grill-with-docs per il lavoro
|
||||
di design; quest'ultima richiede grilling e domain-modeling. Se una skill non è disponibile,
|
||||
segnalalo e concorda il fallback, senza installarla o fingere di averla eseguita.
|
||||
|
||||
FASE 1 — Riconferma delle evidenze, senza modificare il runtime
|
||||
|
||||
1. Leggi AGENTS.md, PROJECT_STATE.md, CONTEXT.md, le istruzioni docs/agents/ su dominio,
|
||||
issue tracker e label, gli ADR pertinenti e il PRD. Controlla HEAD, stato del worktree
|
||||
e differenze dalla baseline della survey. Preserva tutte le modifiche preesistenti.
|
||||
2. Riconferma i rilievi SEC-01…SEC-12 nel codice corrente. Separa fatti verificati,
|
||||
ipotesi, rischi condizionati al profilo e problemi già risolti. Non trattare i vecchi
|
||||
conteggi delle dipendenze come una scansione aggiornata.
|
||||
3. Usa controlli locali read-only e dati sintetici. Per un difetto da riprodurre, usa
|
||||
diagnosing-bugs con un segnale ripetibile sul comportamento effettivo; una diagnosi
|
||||
non autorizza ancora il fix. Confronta fatti di librerie e advisory con fonti primarie
|
||||
correnti quando necessario, senza inviare codice privato o segreti ai servizi di ricerca.
|
||||
4. Non accedere o intervenire su server, IdP, DWH o provider reali senza aver concordato
|
||||
target e operazioni. Non mostrare API key, cookie, password o campioni di dati reali.
|
||||
|
||||
Esito della fase: una matrice aggiornata che conserva gli ID dei rilievi, con evidenza,
|
||||
profilo interessato e stato. Un fatto ancora non verificabile resta esplicitamente aperto.
|
||||
|
||||
FASE 2 — grill-with-docs, con me presente
|
||||
|
||||
5. Costruisci l'albero delle decisioni. Parti da profili di deploy, fiducia fra utenti e
|
||||
condivisione dei dati; poi affronta isolamento di Pi, policy dei valori sensibili,
|
||||
revoca, retention e limiti seguendo le dipendenze effettive.
|
||||
6. A ogni round presenta soltanto le domande attualmente sbloccate, numerate, con la tua
|
||||
raccomandazione e i trade-off. Attendi le mie risposte prima di assumere le decisioni
|
||||
successive. Cerca autonomamente i fatti ricavabili dal repository; usa agenti di
|
||||
ricerca mirati quando previsto dalla skill, senza delegare a loro le mie decisioni.
|
||||
7. Aggiorna il PRD distinguendo proposte e decisioni confermate. Aggiorna CONTEXT.md solo
|
||||
per termini realmente risolti. Proponi ADR soltanto per scelte difficili da invertire,
|
||||
sorprendenti senza contesto e fondate su alternative reali: basta il formato minimo.
|
||||
8. Concorda requisiti, priorità, rischi accettati e criteri misurabili, inclusi i tempi
|
||||
di revoca e i limiti di risorse. Conferma con me i confini pubblici dei test prima
|
||||
di scriverli. Mantieni espliciti i gate manuali già presenti in PROJECT_STATE.md.
|
||||
|
||||
Esito della fase: nessuna decisione bloccante lasciata implicitamente all'agente;
|
||||
riepilogo e mia conferma della comprensione condivisa. Fino a quella conferma rimani
|
||||
su analisi e documentazione: nessun cambiamento applicativo o di deployment.
|
||||
|
||||
FASE 3 — Spec e ticket, soltanto dopo mia conferma
|
||||
|
||||
9. Usa to-spec per sintetizzare le decisioni già prese, senza riaprire arbitrariamente
|
||||
l'intervista. Chiedimi conferma della pubblicazione prima di creare la spec nel
|
||||
tracker canonico Gitea indicato in docs/agents/issue-tracker.md, non nel mirror GitHub.
|
||||
Collega la spec canonica dal PRD e rendi chiaro quale documento è la fonte aggiornata.
|
||||
10. Usa to-tickets per proporre fette verticali verificabili autonomamente, dimensionate
|
||||
per un contesto fresco. Collega ogni ticket ai requisiti e ai rilievi pertinenti,
|
||||
indica i veri blocker e includi criteri positivi e negativi. Fai approvare granularità
|
||||
e dipendenze prima di pubblicare. Solo i ticket approvati e completi ricevono
|
||||
ready-for-agent; non rimetterli in triage e non chiudere automaticamente la spec padre.
|
||||
11. Se una decisione richiede una prova eseguibile, proponi un prototype limitato a quella
|
||||
domanda prima di fissare la spec. Usa wayfinder solo se il lavoro risulta realmente
|
||||
troppo ampio e incerto per essere chiarito con grill-with-docs.
|
||||
|
||||
Esito della fase: spec approvata e ticket autosufficienti con dipendenze risolte o esplicite.
|
||||
Chiedimi se autorizzo il primo ticket: l'approvazione del design non avvia da sola il codice.
|
||||
|
||||
FASE 4 — Implementazione futura autorizzata
|
||||
|
||||
12. Prima di modificare codice, concorda e crea un worktree dedicato, verificando percorso,
|
||||
branch e commit base. Non riusare una directory occupata, non alterare il worktree
|
||||
originario e non copiare automaticamente segreti o dati operativi. Assicurati che
|
||||
PRD e prompt siano disponibili nel worktree attraverso un passaggio esplicito.
|
||||
13. Esegui implement su un ticket sbloccato per volta, in un contesto fresco. Segui tdd
|
||||
ai confini concordati: un test rosso sul comportamento, implementazione minima,
|
||||
test verde. Esegui typecheck e test mirati durante il lavoro e le suite pertinenti
|
||||
al termine; usa fixture locali per IdP, DWH e provider.
|
||||
14. Esegui code-review sui due assi Standards e Spec, usando i due agenti previsti dalla
|
||||
skill e una base Git fissata. Assicurati che il diff esaminato includa tutto il lavoro
|
||||
del ticket, anche se ancora non committato; un diff vuoto non è una review superata.
|
||||
Risolvi i rilievi e verifica di nuovo. Commit soltanto del lavoro pertinente nel
|
||||
worktree autorizzato; push, merge e deploy richiedono un'autorizzazione distinta.
|
||||
15. Consegna evidenze dei test, istruzioni di adozione e rollback, gate manuali pendenti
|
||||
e rischi residui. Non dichiarare chiuso il PRD intero se è concluso soltanto un ticket
|
||||
o se resta un'accettazione dell'owner.
|
||||
|
||||
Inizia dalla Fase 1, poi proponimi il primo round di grill-with-docs.
|
||||
```
|
||||
@@ -1,112 +0,0 @@
|
||||
# X1 — validation of session archive corrections
|
||||
|
||||
Date: 2026-09-09. The joint Memory/Evidence repair increment is implemented.
|
||||
The authoritative contract is [Session archive corrections](../contracts/archive-repair.md).
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
The session gate shows complete before/after content for specific alternatives targeting
|
||||
Memory or Evidence. The reviewer chooses one correction or rejects all proposals as
|
||||
inadequate and requests reformulation. The resulting receipt survives interruption;
|
||||
saved content and index activation are reported separately. Pending activation offers
|
||||
retry of the same chosen operation. A subsequent curator change blocks replay.
|
||||
|
||||
Application requires an administrator in the harness and the responding browser
|
||||
principal's archive-management permission. Cross-principal runtime responses cannot
|
||||
misattribute the correction. A non-administrator can decline or continue the current
|
||||
question without modifying shared archives. The gate does not advance a workflow phase.
|
||||
|
||||
Memory and Evidence remain separate domains. The integration coordinator reuses their
|
||||
canonical persistence and activation operations. A session Evidence correction requires
|
||||
a consolidated archive, preserves source lineage, and cannot publish unrelated external
|
||||
edits. Existing administration, source import, dependency cleanup and final Memory review
|
||||
remain available. No automatic Git commit or push was added.
|
||||
|
||||
## Verification
|
||||
|
||||
- Harness regression: **1,264 passed**, one skipped, five deselected. All **nine**
|
||||
portable-path checks passed separately without `THT_HOME`. Python lint passed on changed modules.
|
||||
- Backend: **1,366 passed**, 40 skipped. Tests include actual session-response routes
|
||||
for both target archives, unauthorized response, malformed choice and runtime ownership.
|
||||
- Frontend: complete suite **645 passed**; the final display adjustment passed all four
|
||||
focused widget tests. Backend and frontend TypeScript checks passed.
|
||||
- Pi extension: **199 passed**, including closed human choices, rejection, failure/retry,
|
||||
forged selections and the updated public tool schema. The modular skill projection is
|
||||
byte-identical to its updated approved template.
|
||||
- PostgreSQL/Qdrant integration traverses the actual Python CLI for preparation,
|
||||
application and recovery inspection. Corrected Memory and Evidence are retrieved from
|
||||
real indexes, and Evidence activation preserves the Memory card. Session loading is a
|
||||
controlled fixture and embeddings are deterministic; this is not an LLM quality test.
|
||||
- Failure tests cover both targets, index outage, replay, later edits, workspace/session
|
||||
isolation, changed session context, rejection, non-admin writes, and interruption after
|
||||
the Evidence file write but before its saved receipt.
|
||||
- Playwright desktop/mobile: **one passed**. The real widget renders both alternatives,
|
||||
accepts an Evidence choice, displays pending activation and allows retry to active.
|
||||
No page errors or mobile horizontal overflow. Screenshots are
|
||||
`/private/tmp/thothii-x1-repair-desktop.png` and `/private/tmp/thothii-x1-repair-mobile.png`.
|
||||
This browser fixture controls operation outcomes; persistent behavior is tested above.
|
||||
- Strict MkDocs build and `git diff --check` passed.
|
||||
|
||||
## Local installation and reviewer acceptance
|
||||
|
||||
Core and frontend images were rebuilt from this worktree using the existing local
|
||||
preview launcher. Migration `004_archive_repairs.sql` was applied to the existing
|
||||
installation catalog. The new gate is available to session workflows; it is not an
|
||||
always-visible administration panel. Existing PSD archive content was not changed by
|
||||
the synthetic validation cases.
|
||||
All five local services are healthy at `http://127.0.0.1:8080/`.
|
||||
|
||||
The technical increments and their planned checks are complete. The end-user acceptance
|
||||
check remains a real session containing a meaningful domain conflict, with the reviewer
|
||||
evaluating the proposed correction. Automated browser validation uses temporary accounts
|
||||
and data, not the user's authenticated PSD session. Source import retains its E3
|
||||
validation boundaries; no broader model-quality benchmark was added.
|
||||
|
||||
## Follow-up acceptance: configured model
|
||||
|
||||
The opt-in `test_real_model_proposes_a_reviewable_persistent_archive_correction`
|
||||
passed with the installation's **zai/glm-5.3** model. Synthetic Memory asserted an
|
||||
order-ID-only join; synthetic Evidence required the financial year too. The model
|
||||
returned two schema-valid, specific alternatives with complete content and the exact
|
||||
target revisions. The test reviewer selected Memory, persisted the correction through
|
||||
the real coordinator and PostgreSQL, and retrieved the updated rule. Evidence stayed
|
||||
unchanged. This test uses deterministic vectors and the configured completion helper;
|
||||
it does not claim a full autonomous Pi session or human acceptance of PSD semantics.
|
||||
|
||||
The run log is `/private/tmp/x1-acceptance-model.log`. Reproduce with
|
||||
`THT_MEMORY_L2_INSTALLATION=<installation.yaml>` and `THT_MEMORY_L2_CORE=<core-container>`
|
||||
using `pytest -q -s -m l2 tests/memory/test_administration.py -k real_model_proposes`.
|
||||
Credentials are resolved inside core and are not returned to the test runner.
|
||||
|
||||
## Follow-up acceptance: both administration pages
|
||||
|
||||
The opt-in `frontend/e2e/memory-real.spec.ts` passed through real authentication,
|
||||
Fastify, ThtRunner, Python, isolated PostgreSQL and Qdrant. It verifies:
|
||||
|
||||
- Database management, Memory management and Evidence management appear as peers in
|
||||
that order, with no active core session or DWH binding required.
|
||||
- Memory creation, editing, persistence across backend restart, deletion and absence
|
||||
from subsequent recall.
|
||||
- Canonical Evidence remains intact after the Memory deletion. Its full rule is read
|
||||
through the real Evidence administration worker; content filtering finds it and an
|
||||
unmatched filter produces the empty state.
|
||||
- Requests for an unregistered workspace return 404 for both archives.
|
||||
- Desktop and mobile Evidence views render without horizontal document overflow.
|
||||
On phones, both archive pages have at least 380px of usable width at a 390px viewport.
|
||||
Navigation opens in the shared accessible dialog, closes with Escape or archive selection,
|
||||
and returns focus to the trigger after Escape.
|
||||
|
||||
The temporary PostgreSQL readiness probe now waits for TCP, avoiding the image's
|
||||
socket-only initialization server. The browser waits for Memory refresh to finish
|
||||
before leaving its page, matching the existing navigation guard. Visual inspection
|
||||
also exposed a real mobile layout issue: the fixed sidebar left only 134px for the
|
||||
Evidence page. `ArchiveNavigation` now moves that sidebar into the shared dialog below
|
||||
768px on Memory/Evidence pages. Desktop behavior is unchanged. The frontend image
|
||||
was rebuilt for the local preview.
|
||||
|
||||
Run log: `/private/tmp/x1-acceptance-browser7.log` (**one passed**).
|
||||
Screenshots: `/private/tmp/thothii-acceptance-evidence-desktop.png` and
|
||||
`/private/tmp/thothii-acceptance-evidence-mobile.png`. Reproduce with
|
||||
`THT_MEMORY_BROWSER_E2E=1 npx playwright test e2e/memory-real.spec.ts` from `frontend/`.
|
||||
The fixture removes its temporary containers, accounts and checkout on completion.
|
||||
The TypeScript check, Python lint, strict documentation build and diff check also pass.
|
||||
@@ -1,67 +0,0 @@
|
||||
# Evidence E1 — validation
|
||||
|
||||
Date: 2026-09-09. Scope: editable Curated Evidence v4 and the persistent local archive.
|
||||
|
||||
## Implemented behavior
|
||||
|
||||
- Parser, renderer, authoring output and normalization share the existing typed payloads.
|
||||
Visible Markdown edits determine content for all eight kinds. Legacy v1–v3 conversion
|
||||
is explicit and lossless, with errors for content that cannot be represented exactly.
|
||||
- Manual declarations record the curator. A correction preserves the original document
|
||||
as lineage, separately from the current declaration. No source hash is needed to
|
||||
create a manual file.
|
||||
- The local archive records baselines, immutable candidates, active revisions and
|
||||
deletion/source suppression metadata. Unresolved review items and invalid edits block
|
||||
consolidation. Missing archive directories are availability failures, not deletions.
|
||||
- Activation failures preserve the previous active revision. Interrupted normalization
|
||||
replays only unchanged input bytes; later operator edits survive recovery.
|
||||
- Revision-checked correction methods reject stale workflow updates. Legacy preparation
|
||||
and resolution cannot overwrite an initialized local archive; explicit import/refresh
|
||||
integration is deferred to E3.
|
||||
|
||||
## Verification
|
||||
|
||||
The final harness suite excluding opt-in L0/L2 and portable-layout cases passed with
|
||||
**1,180 tests** (58 deselected). All **9 portable-layout tests** passed separately with
|
||||
`THT_HOME` unset. The dedicated real-Qdrant integration test passed, including the
|
||||
optional 35-unit PSD probe. Ruff passed on the changed Evidence implementation and
|
||||
tests, and the strict documentation build succeeded. No frontend or backend TypeScript
|
||||
changes are part of E1.
|
||||
|
||||
The integration test uses an isolated Qdrant 1.18.2 container, the actual corpus
|
||||
pipeline, semantic chunking, vector adapter and active Evidence searcher. Deterministic
|
||||
three-dimensional embeddings isolate file/content correctness from model behavior.
|
||||
It verifies that raw edits do not change recall, consolidation updates recalled content
|
||||
and curator identity, a blocked candidate preserves prior recall, and deletions remove
|
||||
recall. Existing schema and Memory records survive each operation.
|
||||
|
||||
All **35 PSD units** were copied from the owner's workspace into
|
||||
`/private/tmp/thothii-e1-psd.bsW4cp`. Deterministic conversion preserved every ID, payload,
|
||||
scope, provenance and review item. There were no unresolved review items. The optional
|
||||
integration probe then indexed all 35 converted units and compared their complete ID
|
||||
set to the original. It uses PSD's actual `max_chunk_chars: 5000`; a preliminary probe
|
||||
at 4000 correctly blocked an oversized atomic unit.
|
||||
|
||||
Reproduce the isolated real-corpus probe after creating a converted workspace copy:
|
||||
|
||||
```sh
|
||||
cd harness
|
||||
THT_E1_PSD_COPY=/absolute/path/to/converted-copy \
|
||||
.venv/bin/pytest -q -s tests/test_evidence_editable_integration.py
|
||||
```
|
||||
|
||||
The environment variable is optional. Ordinary CI uses only synthetic Evidence. No
|
||||
source refresh, external document download, DWH call or model request is involved.
|
||||
|
||||
## Delivery boundary
|
||||
|
||||
E1 is a core/library increment. E2 must add the installed manual consolidation command,
|
||||
connect runtime source selection to the active local snapshot, and build administrative
|
||||
list/filter/detail with real persistent host paths and manual Git instructions. E3
|
||||
adds source acquisition and explicit refresh/conflict handling. X1 later wires deliberate
|
||||
joint Memory/Evidence corrections into review gates.
|
||||
|
||||
The actual PSD Evidence checkout was not converted. The live Docker preview at
|
||||
`http://127.0.0.1:8080` remains the previously deployed M3 stack, with no new Evidence
|
||||
administration page. The corpus conversion and reindexing described here used copies
|
||||
and disposable test resources.
|
||||
@@ -1,86 +0,0 @@
|
||||
# Evidence E2 — validation
|
||||
|
||||
Date: 2026-09-09. E2 is implemented locally and installed on the existing Docker preview.
|
||||
E3 source imports/refresh and X1 deliberate Memory/Evidence workflow corrections remain open.
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
- Independent **Administration → Evidence management**, after Memory, protected by
|
||||
`evidence.manage`: complete typed content, provenance and original excerpts, review items,
|
||||
pagination, search, kind/purpose/status and scope/source filters, sort, and refresh.
|
||||
- Working-file states distinguish active, modified, new, removed, invalid, legacy and review
|
||||
required. Detail shows the actual configured host path with copy controls. Instructions
|
||||
cover external editing, all eight Markdown templates, consolidation and manual Git.
|
||||
- Installed `tht workspace evidence consolidate --workspace <id> [--json]` uses a closed
|
||||
maintenance envelope. First use converts legacy units. Validation, immutable candidates,
|
||||
activation and retry run through the existing corpus pipeline without a DWH scan or Git.
|
||||
- Runtime and ordinary preprocessing consume the active local snapshot. Unconsolidated
|
||||
edits remain excluded. Catalog/Schema readiness is not advanced by this operation.
|
||||
Clear preserves curated files, archive metadata and Memory; full preprocessing must
|
||||
recreate the missing Reference/Schema derivations afterward.
|
||||
- Immutable runtime lease filenames now identify rendered bytes as well as logical input
|
||||
identity. This fixes upgrades colliding with old runtime files without changing Catalog
|
||||
fingerprints or removing the checks against tampered files.
|
||||
|
||||
## Automated checks
|
||||
|
||||
The complete backend suite passed: **1,355 tests**, 40 skipped. The complete frontend
|
||||
suite passed: **639 tests**. Both TypeScript checks passed. Native Go workspace operation
|
||||
and CLI tests passed, including rejection of arbitrary consolidation flags. Ruff passed
|
||||
for changed Python implementation and test files.
|
||||
|
||||
The harness run passed **1,248 tests**, with one skipped and five deselected. Its three
|
||||
portable-path tests failed because that run deliberately set `THT_HOME` to the test
|
||||
runtime; rerunning the portable tests with `THT_HOME` unset passed. The final focused
|
||||
administration/path suite passed all 18 tests, including actionable migration errors and invalid
|
||||
consolidation combinations rejected before cleanup or indexing.
|
||||
|
||||
The real-Qdrant integration test exercised the actual harness consolidation CLI with
|
||||
deterministic embeddings: all 35 PSD units converted and indexed with stable identities;
|
||||
active-only source selection; separate Schema and Memory canaries; Clear and rebuild
|
||||
from the retained snapshot. Unit tests cover validation, saved-but-unindexed failure,
|
||||
retry, browsing/filtering, no automatic Git, and no Catalog mutation from consolidation.
|
||||
|
||||
A temporary Git repository and bare local remote exercise the documented manual sequence:
|
||||
edit, add and remove files, consolidate, inspect, stage the complete Evidence tree,
|
||||
commit, push and clone. The clone retains changed content, additions, deletions, managed
|
||||
metadata and an accessible active snapshot. No remote user repository was pushed.
|
||||
|
||||
## Installed preview
|
||||
|
||||
The existing Compose project is `thothii-18998cca7b0a`, at `http://127.0.0.1:8080`.
|
||||
The persistent editable checkout is:
|
||||
|
||||
```text
|
||||
/Users/mp/projects/ThothII/deploy/psd/evidence-registry/repo/psd-clinical/evidence
|
||||
```
|
||||
|
||||
The original registry checkout was copied from its retained Docker volume. The original
|
||||
author repository was not changed. Core and maintenance share a nested host bind for
|
||||
`repo`; registry state/snapshots and all other existing data volumes were retained.
|
||||
The installation descriptor includes the existing workspace bindings and the new
|
||||
`evidence-host.yaml` override. The previous descriptor and native binary are backed up
|
||||
at `/private/tmp/thothii-installation-before-e2.yaml` and `/private/tmp/tht-before-e2`.
|
||||
|
||||
The real installed command succeeded with **35 documents, 35 chunks, 35 changed, zero
|
||||
removed**, using the configured embedding service and Qdrant. A second run succeeded
|
||||
with **35 unchanged, zero changed**. Reading the actual archive from core returned
|
||||
35 active units and no file errors. All five long-running services are healthy.
|
||||
Only the Evidence stage ran. The strict documentation build and `git diff --check`
|
||||
also passed. The stack launcher is `bash /private/tmp/thothii-memory-preview.sh`; keep its
|
||||
worktree image-build override until this branch is integrated into the main checkout.
|
||||
|
||||
Browser verification reached the local login page. The saved administrator password
|
||||
does not match the current account hash, so the authenticated visual check remains
|
||||
manual. No account or password was modified. React interaction tests cover navigation,
|
||||
detail, host paths, templates, filtering, pending activation and invalid files.
|
||||
|
||||
## Boundaries
|
||||
|
||||
There is no web content editor, watcher, automatic commit/push, or implicit source refresh.
|
||||
The API exposes administration reads and consolidation; the archive's revision-checked
|
||||
save/remove operations remain available for the later explicit workflow corrections.
|
||||
These gates are not claimed as implemented by E2. Initialized local archives retain
|
||||
structural/review checks but bypass the legacy fixed retrieval-evaluation fixture so
|
||||
its old expected IDs cannot veto deliberate deletions. A general retrieval benchmark
|
||||
is outside the agreed scope.
|
||||
@@ -1,100 +0,0 @@
|
||||
# Evidence E3 — validation
|
||||
|
||||
Date: 2026-09-09. Explicit source import/refresh and decisions are implemented. X1,
|
||||
the integration of deliberate Memory/Evidence corrections into workflow gates, remains next.
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
The independent Evidence page now offers **Sources and imports**. An operator copies
|
||||
a specialist's draft into `evidence/incoming/`, then explicitly imports/refreshes.
|
||||
Original local Markdown and configured HTTP/S3 sources use existing read-only adapters.
|
||||
Acquisition retains raw bytes, source identity and versioned normalized documents.
|
||||
The existing Pi authoring refiner prepares typed, editable v4 proposals.
|
||||
|
||||
Unchanged hashes skip refinement. All source acquisitions/refinements must succeed
|
||||
before saving a new set of comparisons. Missing sources are recorded as unavailable,
|
||||
never interpreted as permission to delete. No runtime lookup, ordinary consolidation
|
||||
or preprocessing triggers remote refresh once the local archive is initialized.
|
||||
|
||||
The administrator sees current and proposed units, scope, content, excerpts, review
|
||||
items and explicit retirement IDs. **Keep local Evidence** records the retained wording
|
||||
as a manual declaration with original lineage. **Use proposed Evidence** adopts the
|
||||
proposal and its source version. Both save and activate through the existing archive
|
||||
and corpus pipeline; review items block adoption. Comparisons use optimistic checks
|
||||
on affected file bytes. Interrupted decisions have a durable replay journal and retry
|
||||
without reacquisition, while intervening external edits are preserved and reported.
|
||||
|
||||
Deleted IDs remain reserved. New model-generated identities from sources with curated
|
||||
deletions are also conservatively suppressed; surviving IDs can still receive reviewed
|
||||
updates. Deliberate new knowledge can be authored as a manual file. This mechanical
|
||||
protection does not depend on the model detecting semantic duplication or contradictions.
|
||||
|
||||
Installed commands are `workspace evidence refresh` and `workspace evidence decide`,
|
||||
alongside E2 consolidation. Decision envelopes carry a source identity, comparison
|
||||
revision and keep/replace choice. Extra URLs, arbitrary paths, forged actors and unknown
|
||||
fields are rejected at the public API/CLI boundary. HTTP requests bind the authenticated
|
||||
curator. Source operations do not mutate Catalog readiness or run DWH/schema stages.
|
||||
The Python source worker is internal; the workflow CLI's visible surface is preserved.
|
||||
|
||||
## Checks
|
||||
|
||||
- Complete backend suite: **1,359 passed**, 40 skipped. Complete frontend suite:
|
||||
**641 passed**. Both TypeScript checks passed; native Go CLI/workspace tests passed.
|
||||
- Harness regression run: **1,256 passed**, one skipped and five deselected, with
|
||||
portable-path tests run separately without `THT_HOME`. All **24 focused import,
|
||||
CLI-surface and portable-path checks** passed. These
|
||||
cover import, unchanged refresh, access failure, missing source, manual correction,
|
||||
keep/replace, deletion suppression, stale comparisons, failure/retry and interrupted
|
||||
journal writes. Ruff passed on the changed Python implementation and tests.
|
||||
- The real-Qdrant test traverses the actual harness source CLI with deterministic
|
||||
refinement/embedding boundaries: import is absent from recall before a decision,
|
||||
accepted content becomes searchable, refreshed proposals preserve active manual
|
||||
corrections, replacement removes the former text, deletion remains absent after
|
||||
another refresh, and unrelated Schema/Memory canaries survive.
|
||||
- Source contract fixtures cover controlled HTTP and S3 identities, exact acquired
|
||||
bytes, and acquisition call counts. Existing adapter tests retain transport/egress
|
||||
coverage. The test does not claim to exercise a live S3 account.
|
||||
- React interaction tests verify explicit refresh, comparison content, exact decisions,
|
||||
saved-decision retry and failure feedback. Route tests cover admin authorization,
|
||||
workspace isolation, strict inputs and principal attribution. Service tests verify
|
||||
the trusted config file descriptor and absence of Catalog mutation.
|
||||
|
||||
## Local preview
|
||||
|
||||
Core/frontend were rebuilt for the existing `thothii-18998cca7b0a` stack. Its persistent
|
||||
archive and data volumes are retained. The native `/usr/local/bin/tht` was updated;
|
||||
the previous executable is at `/private/tmp/tht-before-e3`.
|
||||
|
||||
The installed refresh command ran against `psd-clinical` successfully: **35 unchanged
|
||||
sources, zero changed, zero pending comparisons**. All 35 source hashes matched their
|
||||
existing units, so this probe required no refinement and changed no active Evidence.
|
||||
Source registry metadata was saved locally; no Git commit or push was performed.
|
||||
|
||||
A separate synthetic draft was passed to the configured Pi/model inside core. It
|
||||
produced one domain proposal with one review item, which was not activated. The probe
|
||||
exposed a deployment issue: Python wheel modules and Pi skills live in different
|
||||
directories. The refiner now resolves resources through `THT_HARNESS_DIR`, with the
|
||||
source-tree location as its development fallback; a regression test covers this layout.
|
||||
|
||||
The corrected installed worker was then exercised end to end in a temporary workspace
|
||||
inside core, using the real configured Pi/model and a synthetic `incoming/orders.md`.
|
||||
It returned success, one changed source, one comparison and one proposal with a review
|
||||
item. The active snapshot remained absent. The temporary directory was removed on exit;
|
||||
the probe did not open the DWH or activate an index. Strict docs build and
|
||||
`git diff --check` also passed.
|
||||
|
||||
The in-app browser still showed the login page with the prior credential error.
|
||||
Authenticated visual verification remains manual; no credentials were reset or retried.
|
||||
|
||||
## Operational instructions and boundaries
|
||||
|
||||
See [Import drafts and refresh sources](../contracts/curated-evidence-v4.md#import-drafts-and-refresh-sources)
|
||||
for commands, local paths, review, retry and backup/Git requirements. Preserve the
|
||||
complete Evidence tree, including source comparisons, journals and acquired versions.
|
||||
Local activation and transfer to the remote Git repository remain separate operator steps.
|
||||
|
||||
No web content editor, automatic Git, background watcher, new job queue, general
|
||||
retrieval benchmark or automatic source merge was introduced. Review/refinement is
|
||||
sequential and bounded by per-source limits plus 200 documents/100 MiB per refresh.
|
||||
New changed-source decisions and failure scenarios use isolated test data; live PSD
|
||||
curated content was kept unchanged. X1 is not included in this increment.
|
||||
@@ -1,96 +0,0 @@
|
||||
# M2 — Ricerca ibrida e collegamenti
|
||||
|
||||
Data: 2026-09-09. Implementazione locale dell'incremento M2 del
|
||||
[piano Memory approvato](2026-09-08-memory-management.md#piano-esecutivo).
|
||||
|
||||
## Risultato
|
||||
|
||||
La ricerca Memory ed exemplar usa embedding dense e BM25 in Qdrant. I filtri sono
|
||||
applicati in entrambi i rami prima della selezione dei candidati. Il core espande
|
||||
i collegamenti uscenti, deduplica, limita cicli e visite, riordina insieme i risultati
|
||||
e restituisce il contenuto corrente verificato in PostgreSQL. Non usa un database
|
||||
a grafo né una chiamata LLM per il riordinamento.
|
||||
|
||||
Il contesto fisico distingue database, schema, tabella e colonna e richiede che
|
||||
corrispondano alla stessa dipendenza strutturata. Le card senza dipendenze valgono
|
||||
per il workspace; un riferimento a un antenato fisico si applica ai suoi discendenti.
|
||||
Ambito descrittivo e concetti possono restringere ulteriormente la ricerca tramite
|
||||
`--filters`. La CLI impedisce di sostituire database/schema del runtime. Il dettaglio
|
||||
dei limiti e della formula di ranking è nel [contratto operativo](../gestione-memory.md#hybrid-recall-and-links).
|
||||
|
||||
L'incremento conserva i confini dei gate correnti: F2 riceve chiarimenti di dominio,
|
||||
gli exemplar restano consultativi. Un collegamento non autorizza a consumare una
|
||||
famiglia diversa o una card fuori ambito. Il riepilogo finale, i nuovi gate e la
|
||||
pulizia delle dipendenze dopo sincronizzazione fisica appartengono a M3.
|
||||
|
||||
## Transizione e recupero
|
||||
|
||||
La migrazione versionata `002_hybrid_projection.sql` aggiunge il formato delle
|
||||
proiezioni. Le card M1 restano autorevoli e consultabili; le loro proiezioni dense
|
||||
risultano pendenti e non possono alimentare il recall. Un retry esplicito o
|
||||
`tht memory index -c <runtime.yaml>` costruisce dense e BM25 dal contenuto corrente.
|
||||
Il formato della proiezione e la revisione della card sono verificati prima dell'uso.
|
||||
|
||||
Il salvataggio può aggiungere il vettore sparse mancante nella sola collezione
|
||||
Memory. Non sostituisce configurazioni incompatibili e non modifica Reference.
|
||||
Il rebuild esplicito ricrea anche una collezione Memory assente; il test elimina
|
||||
la collezione, ricostruisce da PostgreSQL e verifica il ritorno della sola card conservata.
|
||||
Fallimenti lasciano il lavoro di propagazione persistito e recuperabile. Nessuna
|
||||
importazione da JSONL, sessioni storiche o vecchi payload Qdrant.
|
||||
|
||||
## Verifiche
|
||||
|
||||
| Controllo | Esito |
|
||||
| --- | --- |
|
||||
| Suite harness senza L0/L2, escluso il file dei percorsi portabili | 1.152 test passati nell'esecuzione finale. |
|
||||
| Suite mirata Memory, adapter e CLI, con embedding reale | 78 test passati. |
|
||||
| Verifica aggiuntiva del rebuild con collezione assente e adapter | 54 passati; il solo test del modello reale era escluso in questa riesecuzione. |
|
||||
| API Fastify Memory | 13 test passati, compresa propagazione della lingua del workspace. |
|
||||
| Browser amministrativo integrato | Passato: creazione, modifica, riavvio, rilettura, cancellazione e verifica del recall. |
|
||||
| Wheel e casi CLI | 10 test passati; il wheel include entrambe le migrazioni Memory. |
|
||||
| Build e controlli statici | Build/typecheck backend, Ruff sui file Python interessati e build documentale strict passati. |
|
||||
|
||||
- Test deterministici: collegamenti necessari, contenuto corrente, duplicati,
|
||||
cicli, profondità e limiti, card mancanti o pendenti, rifiuti già registrati,
|
||||
famiglie e ambiti esclusi, dipendenze omonime e filtri CLI vincolati al runtime.
|
||||
- Adapter: stesso filtro nei prefetch dense/BM25 per Memory ed exemplar; restano
|
||||
coperti i contratti Evidence esistenti.
|
||||
- PostgreSQL/Qdrant: salvataggio, modifica, cambio famiglia, cancellazione,
|
||||
ricostruzione, riferimento separato, isolamento, RLS, errori, retry e transizione
|
||||
delle proiezioni M1 al formato ibrido.
|
||||
- Recupero effettivo: client Ollama di produzione con il modello configurato
|
||||
`qwen3-embedding:0.6b`, dimensione 1024, e Qdrant dell'immagine fissata in Compose.
|
||||
La domanda sulla chiave commessa fra esercizi recupera la regola attesa e la
|
||||
granularità collegata, escludendo un altro database, un altro ambito e dipendenze
|
||||
che corrispondono soltanto combinando riferimenti distinti. Verifica separatamente
|
||||
dense, BM25 e fusione, poi recall, cancellazione e rebuild.
|
||||
|
||||
Il test effettivo avvia un processo Ollama separato, montando il volume del modello
|
||||
installato in sola lettura. PostgreSQL e Qdrant sono container temporanei dedicati,
|
||||
eliminati a fine test. Non usa ID di risultati predisposti. Il browser amministrativo
|
||||
usa invece embedding deterministici: verifica il collegamento fra UI, autenticazione,
|
||||
Fastify, ThtRunner e persistenza, senza essere una misura di qualità del recupero.
|
||||
|
||||
Non è una valutazione generale della qualità semantica su un corpus di produzione;
|
||||
verifica i casi di recupero richiesti da M2, con il percorso reale configurato.
|
||||
|
||||
## Riproduzione
|
||||
|
||||
Dalla directory `harness`, con Docker disponibile:
|
||||
|
||||
```sh
|
||||
THT_HOME=/private/tmp/thothii-m2-test-home \
|
||||
THT_MEMORY_TEST_OLLAMA_VOLUME=<volume-modelli-installazione> \
|
||||
THT_MEMORY_TEST_MODEL=qwen3-embedding:0.6b \
|
||||
THT_MEMORY_TEST_DIMENSIONS=1024 \
|
||||
.venv/bin/pytest -q tests/memory/test_administration.py \
|
||||
tests/memory/test_retrieval.py tests/memory/test_recall.py \
|
||||
tests/test_qdrant_vector_store.py tests/test_solved_search_cli.py
|
||||
```
|
||||
|
||||
Senza il volume esplicito, il solo test con modello reale viene escluso; gli altri
|
||||
test restano eseguibili. Il volume deve contenere il modello indicato. Le immagini
|
||||
Qdrant e Ollama del test sono lette da `compose.yaml`.
|
||||
|
||||
Consegna locale: non sono stati eseguiti deploy, migrazioni delle installazioni
|
||||
attive o aggiornamenti remoti dell'issue tracker.
|
||||
@@ -1,78 +0,0 @@
|
||||
# Memory M3 — validation
|
||||
|
||||
Implemented on 2026-09-09 in the rapid-harbor worktree.
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
- F8 presents an editable summary of proposed additions, explicit updates and links.
|
||||
Only selected content is saved, including the optional solved-question exemplar.
|
||||
- Proposals reference effective approved decisions. Exact existing content is reused.
|
||||
Concurrent edits invalidate an update; manual identities and origins are preserved.
|
||||
- Selected cards and links commit atomically. Durable receipts recover repeat delivery
|
||||
and the gap before the session review marker. Finalization does not add Memory.
|
||||
- F4/F6/F7 retrieve SQL rules and explained errors for the existing approval gates.
|
||||
Retrieval is consultative and does not write an approval decision.
|
||||
- Successful Catalog physical sync deletes cards with matching removed dependencies.
|
||||
The same Catalog transaction marks pending Memory cleanup. Retry keeps the original
|
||||
removals and does not rescan; deletion receipts and projection tombstones survive restarts.
|
||||
- Migration 003 adds minimal review and physical-cleanup receipts.
|
||||
|
||||
## Executed checks
|
||||
|
||||
| Check | Result |
|
||||
| --- | --- |
|
||||
| Harness deterministic suite, excluding portable-path environment cases | 1,152 passed |
|
||||
| Portable-path suite without the temporary THT_HOME override | 9 passed |
|
||||
| Memory service/retrieval with isolated PostgreSQL and Qdrant | 41 passed, 1 optional real-embedding case skipped, 1 L2 case excluded |
|
||||
| Pi gate suite | 195 passed |
|
||||
| Backend full suite | 1,346 passed; one auth timing test exceeded 5 seconds under concurrent load |
|
||||
| Isolated auth and Catalog route rerun | All 40 passed, including the timed-out case |
|
||||
| Catalog PostgreSQL integration after adding atomic cleanup-marker coverage | All 5 passed |
|
||||
| Frontend full suite | 635 passed |
|
||||
| Chromium summary review, desktop and 390px mobile | Passed; no page errors or horizontal overflow |
|
||||
| Configured real GLM 5.3 generation | Passed on synthetic PostgreSQL data |
|
||||
| Backend/frontend production builds, modified Python lint, strict docs build | Passed |
|
||||
|
||||
The existing local Docker preview was rebuilt from this worktree, migration 003
|
||||
was applied, and core/frontend were recreated with the existing persistent volumes.
|
||||
The preview remains at `http://127.0.0.1:8080`.
|
||||
|
||||
The browser check uses the production widget in an isolated Vite fixture. It edits
|
||||
the rule, declines the exemplar, submits only the selected card and checks responsive
|
||||
layout. Gate tests separately verify request ordering through the production Pi
|
||||
composition root; service and Catalog tests use real PostgreSQL. This is not a claim
|
||||
of an automated complete live Pi conversation.
|
||||
|
||||
The L2 case retrieves an approved SQL rule, excludes a card bound to another database,
|
||||
and asks the configured GLM 5.3 model to generate a query. Order IDs repeat between
|
||||
financial years; the correct composite join returns 120 on the synthetic fixture.
|
||||
The generated SQL is validated and executed in a read-only PostgreSQL transaction.
|
||||
No real DWH rows are sent. Embeddings in this case are deterministic; the real
|
||||
embedding/hybrid retrieval evidence remains documented in M2.
|
||||
|
||||
## Reproduction
|
||||
|
||||
From the harness:
|
||||
|
||||
```sh
|
||||
THT_HOME=/private/tmp/thothii-m1-harness-home .venv/bin/pytest -q -m 'not l0 and not l2' --ignore=tests/test_portable_paths.py
|
||||
.venv/bin/pytest -q tests/test_portable_paths.py
|
||||
THT_HOME=/private/tmp/thothii-m1-harness-home .venv/bin/pytest -q tests/memory/test_administration.py tests/memory/test_retrieval.py -m 'not l2'
|
||||
npm test
|
||||
```
|
||||
|
||||
The optional generation case requires an installation YAML path and its running
|
||||
core container. It resolves the model credential inside core without printing it:
|
||||
|
||||
```sh
|
||||
THT_MEMORY_L2_INSTALLATION=<installation.yaml> THT_MEMORY_L2_CORE=<core-container> \
|
||||
.venv/bin/pytest -q -s -m l2 tests/memory/test_administration.py -k real_model
|
||||
```
|
||||
|
||||
From frontend: `npx playwright test e2e/memory-review.spec.ts`.
|
||||
Screenshots are written to `/private/tmp/thothii-m3-summary-desktop.png` and
|
||||
`/private/tmp/thothii-m3-summary-mobile.png`.
|
||||
|
||||
Evidence authoring and the joint X1 persistent Memory/Evidence conflict repair remain
|
||||
outside M3. This increment does not infer knowledge from unexplained failures or
|
||||
promise general improvements in SQL-generation accuracy.
|
||||
@@ -0,0 +1,175 @@
|
||||
# Tre esempi locali per l'installazione guidata
|
||||
|
||||
Stato: nota esplorativa conservata; requisiti definiti nel PRD e implementazione
|
||||
rinviata su richiesta dell'utente.
|
||||
Requisiti correnti e decisioni aperte sono ora raccolti nel
|
||||
[PRD dei database di esempio](2026-09-27-example-databases-prd.md), che prevale
|
||||
su questa nota esplorativa in caso di divergenza.
|
||||
Branch: `codex/benchmark-examples`, derivato da `codex/guided-standalone-install`
|
||||
al commit `67ee5262`. Collegamento al progetto installazione:
|
||||
`docs/plans/2026-09-27-guided-installation-resumption.md` sul branch di origine.
|
||||
|
||||
## Requisiti dell'utente
|
||||
|
||||
- Tre database pubblicamente scaricabili da BIRD o altro benchmark, con evidence.
|
||||
- Tre livelli di complessità crescente; preferenza per dati in CSV.
|
||||
- Esempi da implementare in locale.
|
||||
- Caricamento opzionale tramite CLI dal repository dei workspace: selezione di
|
||||
uno, due o tutti e tre i database, dopo il setup; integrazione nel setup da valutare.
|
||||
- Dati, schema PostgreSQL commentato ed Evidence disponibili per ogni esempio.
|
||||
- Domande in un documento di accompagnamento per esercitarsi, senza SQL target.
|
||||
- Collaudo in tre tappe: Windows, Linux Omarchy, macOS.
|
||||
|
||||
### Criterio chiarito dall'utente
|
||||
|
||||
ThothII viene usato con human in the loop: questo progetto non serve a misurarlo
|
||||
contro un benchmark. I benchmark sono soltanto fonti di database e documentazione.
|
||||
Numero di domande, gold SQL, percentuali di correttezza e copertura delle annotazioni
|
||||
per domanda non sono criteri di selezione o di accettazione.
|
||||
Le domande sono invece utili come materiale didattico: il prodotto le include in
|
||||
un documento separato dalle Evidence, senza soluzioni SQL o valutazione automatica.
|
||||
|
||||
Si cercano complessità relazionale e semantica e documentazione sostanziale da
|
||||
curare come Source Evidence: significati, regole aziendali, formule, codifiche,
|
||||
granularità e relazioni. Documenti non collegati ai quesiti del benchmark contano
|
||||
quanto quelli collegati. DDL, righe di esempio e numero di file da soli non
|
||||
dimostrano una buona documentazione di dominio. Dopo il confronto delle alternative,
|
||||
il trio per cui l'utente richiede ora la procedura è Financial, European Football e F1.
|
||||
|
||||
## Dataset proposti
|
||||
|
||||
California Schools è escluso per richiesta dell'utente. European Football è richiesto;
|
||||
l'utente ha inoltre chiesto di valutare Spider 2.0 e la disponibilità di evidence.
|
||||
La proposta corrente comprende Financial e European Football da BIRD e F1 da
|
||||
Spider 2.0-Lite. Shopify, QuickBooks e Workday restano alternative documentate.
|
||||
I livelli sono una progressione didattica proposta per ThothII.
|
||||
|
||||
| Livello | Database | Motivo | Fonti per le Evidence |
|
||||
| --- | --- | --- | --- |
|
||||
| Primo percorso | BIRD `financial` | Conti, clienti, prestiti e movimenti | Codifiche di dominio e regole nelle annotazioni BIRD |
|
||||
| Intermedio | BIRD `european_football_2` | Campionati, squadre, giocatori e partite | Stagioni, significato degli indicatori e aggregazioni nelle annotazioni BIRD |
|
||||
| Avanzato | Spider 2.0-Lite `f1` | Stagioni, gare, piloti, giri, pit stop e cambi di posizione; 29 tabelle dichiarate | Documenti di dominio sui sorpassi e sui tipi di giro, da curare e integrare dove insufficienti |
|
||||
|
||||
Revisione Hugging Face BIRD osservata:
|
||||
`f65faf4ae3b638c1fa6df1d3370c8d92c8366301`.
|
||||
|
||||
Le evidence BIRD comprendono spiegazioni di codici, significati di colonne e regole di
|
||||
calcolo. Sono annotazioni legate alle domande; richiedono adattamento e revisione
|
||||
per diventare Source Evidence di ThothII. Non sono già un archivio ThothII pronto.
|
||||
|
||||
Le definizioni dbt sono fonti da curare, non Evidence Unit già importate in ThothII.
|
||||
Non contare ogni descrizione di colonna come un'evidence distinta. I file tecnici
|
||||
delle librerie dbt non rientrano nel materiale semantico del database.
|
||||
Revisione Spider2 osservata: `cafb867313aab4e674652054198f383cf4018943`.
|
||||
|
||||
Le ricerche motivate e le alternative sono in
|
||||
`docs/research/2026-09-27-spider2-lite-evidence-candidates.md` e
|
||||
`docs/research/2026-09-27-spider2-dbt-evidence-candidates.md`.
|
||||
|
||||
## Fonti e formati
|
||||
|
||||
- [Dataset ufficiale e licenza dichiarata CC BY-SA 4.0](https://huggingface.co/datasets/birdsql/bird_mini_dev).
|
||||
- [Domande PostgreSQL, evidence e SQL di riferimento](https://huggingface.co/datasets/birdsql/bird_mini_dev/blob/f65faf4ae3b638c1fa6df1d3370c8d92c8366301/data/mini_dev_pg-00000-of-00001.json).
|
||||
- [Istruzioni ufficiali e pacchetto database](https://github.com/bird-bench/mini_dev).
|
||||
- [Pacchetto completo indicato dalla dataset card](https://drive.google.com/file/d/13VLWIwpw5E3d5DUkMvzw7hvHE67a4XkG/view?usp=sharing).
|
||||
- [Archivio ZIP collegato dal repository ufficiale](https://bird-bench.oss-cn-beijing.aliyuncs.com/minidev.zip):
|
||||
risposta HEAD 200, 800943648 byte al controllo; contenuto non ancora scaricato né
|
||||
confrontato con il pacchetto aggiornato della dataset card.
|
||||
|
||||
I CSV `database_description` descrivono schema e valori, non contengono le righe
|
||||
delle tabelle. I dati sono forniti come database SQLite e materiale per PostgreSQL/
|
||||
MySQL. Proposta: mantenere PostgreSQL come destinazione locale e, se utile, produrre
|
||||
CSV riproducibili insieme a DDL, tipi e vincoli. Non usare CSV senza schema come
|
||||
unica rappresentazione del database. Conservare provenienza, versione, attribuzione
|
||||
e licenza con gli artefatti derivati.
|
||||
|
||||
Fonti Spider 2.0-Lite per F1:
|
||||
|
||||
- [Istruzioni per scaricare i database SQLite locali](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/README.md).
|
||||
- [Schema e metadati F1](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite/resource/databases/sqlite/f1).
|
||||
- [Classificazione dei sorpassi](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/f1_overtake.md).
|
||||
- [Tipi di giro](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/lap_type.md).
|
||||
|
||||
I tre database sorgente sono SQLite. Esportazione CSV e caricamento PostgreSQL
|
||||
dovranno preservare tipi, relazioni, granularità e contenuto dei dati selezionati.
|
||||
I file sono stati individuati negli archivi; i dati completi non sono stati scaricati
|
||||
né convertiti durante la progettazione.
|
||||
|
||||
## Proposta di download e caricamento PostgreSQL
|
||||
|
||||
Questa sezione risponde alla richiesta di fattibilità e non autorizza né attesta
|
||||
un'implementazione già eseguita.
|
||||
|
||||
### Destinazione
|
||||
|
||||
Il Compose include `catalog-db`, PostgreSQL 17.6, con volume `catalog-data` e database
|
||||
`thothii_catalog`. Quest'ultimo ospita le informazioni applicative del Catalog e
|
||||
la persistenza Memory. Proposta per le installazioni dimostrative: riutilizzare lo
|
||||
stesso servizio PostgreSQL, creando tre database separati, con nomi da finalizzare:
|
||||
`example_financial`, `example_football`, `example_f1`. Ogni database avrà un solo
|
||||
schema applicativo, un workspace associato e un ruolo di interrogazione in sola
|
||||
lettura. L'importazione userà un ruolo distinto con permessi di scrittura.
|
||||
|
||||
La creazione degli esempi deve essere una manutenzione esplicita rieseguibile, non
|
||||
un'aggiunta affidata unicamente agli script di inizializzazione del volume PostgreSQL.
|
||||
Le migrazioni Catalog e i suoi ruoli runtime rimangono separati dal caricatore.
|
||||
La condivisione del servizio implica condivisione di risorse, volume e gestione
|
||||
backup; non equivale a isolamento fra istanze PostgreSQL indipendenti.
|
||||
|
||||
### Sequenza prevista
|
||||
|
||||
1. Selezione esplicita di uno, due o tre esempi, anche dopo il primo setup.
|
||||
2. Manifest versionato per ciascun esempio: URL ufficiali, revisione/checksum,
|
||||
file nell'archivio, fonti documentali, licenze e versione della conversione.
|
||||
Cache dei pacchetti comuni per evitare download duplicati.
|
||||
3. Download ed estrazione dei SQLite e della documentazione. BIRD: descrizioni CSV
|
||||
e annotazioni evidence, conservando il contesto necessario a interpretarle.
|
||||
F1: metadati dello schema e documenti di dominio. Nessuna generazione automatica
|
||||
di nuove regole presentate come se fossero evidence originali.
|
||||
4. Ispezione dello schema e dei dati effettivi; conversione SQLite verso DDL
|
||||
PostgreSQL e CSV, con mapping espliciti per tipi, date, booleani, valori null,
|
||||
identificatori e colonne prive di tipo. Rilevare PK/FK presenti e distinguere
|
||||
relazioni documentate o proposte da quelle effettivamente vincolate nella sorgente.
|
||||
5. Caricamento in database di preparazione dedicati; creazione degli indici e
|
||||
vincoli verificati, confronto delle righe e dei valori e controlli relazionali.
|
||||
Un fallimento lascia l'esempio non pronto senza sostituire una versione funzionante.
|
||||
6. Pubblicazione dei database validati e registrazione dei binding nel Catalog;
|
||||
creazione dei workspace e sincronizzazione degli schemi via servizi esistenti.
|
||||
7. Importazione separata: descrizioni nel Catalog; documenti e regole nelle Source
|
||||
Evidence del workspace, con provenienza. Le Evidence restano artefatti del
|
||||
modulo Evidence; la proiezione ricercabile appartiene a Qdrant.
|
||||
8. Revisione umana/consolidamento delle Evidence e delle relazioni proposte,
|
||||
preprocessing e controlli di utilizzabilità. La disponibilità dei file scaricati
|
||||
non equivale a un workspace pronto.
|
||||
|
||||
Il processo conserva stato e versioni per riprendere dopo errori, evita duplicazioni
|
||||
e non sovrascrive Evidence curate o dati esistenti durante una normale riesecuzione.
|
||||
Download ed elaborazione devono usare componenti containerizzati, mantenendo il
|
||||
percorso Windows/WSL2 senza richiedere Python o Node aggiuntivi sull'host.
|
||||
|
||||
## Decisione architetturale aperta
|
||||
|
||||
Gli ADR 0001 e 0003 e il glossario corrente prevedono un database per workspace.
|
||||
La richiesta di un workspace con tre database richiede quindi una scelta esplicita.
|
||||
Proposta: un pacchetto/repository di esempi con tre workspace indipendenti, ognuno
|
||||
associato al proprio database. Nessuna modifica multi-database è approvata finora.
|
||||
|
||||
## Lavoro previsto dopo la definizione
|
||||
|
||||
1. Fissare versione e checksum dei dati, ispezionare schema, tipi, chiavi e
|
||||
documentazione di dominio; definire percorsi dimostrativi di complessità crescente.
|
||||
2. Preparare il caricamento locale selettivo dei tre dataset, con dati e ruoli
|
||||
distinti dal Catalog applicativo, ripresa e riesecuzione senza duplicazioni.
|
||||
3. Preparare descriptor e Source Evidence con provenienza per ogni esempio;
|
||||
esplicitare ciò che è documentato e ciò che richiede una decisione del curatore.
|
||||
4. Registrare binding nel Catalog, sincronizzare schema e predisporre il percorso
|
||||
di revisione/consolidamento e preprocessing dei workspace selezionati.
|
||||
5. Integrare nel setup la scelta opzionale dei dataset e mostrare per ciascuno
|
||||
caricamento, configurazione, Evidence e stato di utilizzabilità.
|
||||
6. Verificare tutte le sette selezioni non vuote dei tre esempi, la riesecuzione e
|
||||
gli errori di download/importazione. Collaudare una domanda reale per ciascun
|
||||
esempio installato, poi arresto e riavvio, prima su Windows.
|
||||
|
||||
La selezione opzionale comprende anche la possibilità di installare ThothII senza
|
||||
esempi. Nessun download massivo, caricamento database o implementazione del setup
|
||||
è stato eseguito durante questa proposta.
|
||||
@@ -0,0 +1,402 @@
|
||||
# PRD — Database di esempio per ThothII
|
||||
|
||||
Data: 2026-09-27. Stato: requisiti D1–D8 approvati tramite `grill-with-docs`;
|
||||
implementazione rinviata su richiesta dell'utente; non iniziata.
|
||||
Branch di progettazione: `codex/benchmark-examples`.
|
||||
|
||||
Il branch conserva la progettazione per una ripresa successiva. La definizione
|
||||
della procedura di installazione prosegue separatamente su
|
||||
`codex/guided-standalone-install`; non deve presumere che la CLI o i database di
|
||||
esempio descritti qui siano già disponibili.
|
||||
|
||||
Questo PRD raccoglie i requisiti correnti e sostituisce, in caso di divergenza,
|
||||
le proposte nella [nota esplorativa](2026-09-27-benchmark-examples.md).
|
||||
Gli aspetti tecnici da verificare prima del rilascio sono distinti dalle decisioni
|
||||
di prodotto approvate e non attestano funzionalità già implementate.
|
||||
|
||||
## Problema e risultato desiderato
|
||||
|
||||
Chi installa ThothII deve poter scegliere e caricare uno, due o tre database di
|
||||
esempio, ottenendo dati reali, schema commentato, Evidence disponibili e un documento
|
||||
di domande per esercitarsi. Il percorso deve funzionare anche dopo l'installazione,
|
||||
senza obbligare a reinstallare ThothII o a conoscere la sua architettura interna.
|
||||
|
||||
La distribuzione avviene dal repository dei workspace: oltre alle definizioni dei
|
||||
workspace, il repository ospita una cartella `examples/` con la CLI e quanto serve
|
||||
a scaricare e predisporre gli esempi su richiesta. Il normale aggiornamento del
|
||||
repository non deve eseguire importazioni.
|
||||
|
||||
Il repository pubblico ThothII su `git.tylconsulting.it` deve rimandare al repository
|
||||
pubblico dedicato agli esempi, ospitato su Gitea e gestito da TYL Consulting.
|
||||
L'URL esatto di destinazione resta da definire; non si presume che debba coincidere
|
||||
con l'istanza Gitea del repository ThothII. README e documentazione di installazione
|
||||
devono rendere reperibili CLI, workspace e istruzioni dal repository principale.
|
||||
|
||||
ThothII ha un processo human in the loop. Le domande sono spunti didattici, senza
|
||||
risposte SQL da riprodurre, punteggi, classifiche o confronto automatico col benchmark.
|
||||
|
||||
## Requisiti confermati
|
||||
|
||||
| ID | Requisito |
|
||||
| --- | --- |
|
||||
| R1 | Tre esempi: BIRD Financial, BIRD European Football, Spider 2.0-Lite F1. |
|
||||
| R2 | Selezione di uno, due o tutti e tre; gli esempi sono facoltativi. |
|
||||
| R3 | Caricare dati e schema PostgreSQL, inclusi commenti di tabelle e colonne. |
|
||||
| R4 | Accompagnare ogni esempio con le Evidence disponibili e la loro provenienza, curate prima del rilascio e indicizzate durante il caricamento. |
|
||||
| R5 | Fornire le domande disponibili in un documento leggibile per esercitarsi. |
|
||||
| R6 | Escludere gli SQL target dei benchmark dal prodotto distribuito agli utenti. |
|
||||
| R7 | Verificare esplicitamente la conversione dei tipi e dei valori verso PostgreSQL. |
|
||||
| R8 | Distribuire una CLI attraverso il repository dei workspace, nella cartella degli esempi. |
|
||||
| R9 | Consentire il caricamento tramite CLI autonoma dopo l'installazione e richiamare la stessa procedura come ultimo passo facoltativo del setup. |
|
||||
| R10 | Collaudare Windows, poi Omarchy, infine macOS, in tre passaggi separati. |
|
||||
| R11 | Distribuire pacchetti PostgreSQL già convertiti e verificati, con ricetta di conversione riproducibile. Valutare conversione locale solo per fonti non redistribuibili. |
|
||||
| R12 | Concludere con workspace subito utilizzabili: dati, commenti, Evidence curate, metadati sincronizzati e indicizzazione completata. |
|
||||
| R13 | La procedura deve prevedere una copia indipendente del repository degli esempi, senza memoria Git dell'originale, oppure uno scaricamento con accesso al repository pubblico in sola lettura. Workspace ed Evidence locali restano modificabili; nessuna credenziale o operazione di scrittura verso l'originale. |
|
||||
|
||||
DDL, comandi di importazione e controlli tecnici SQL fanno parte del caricatore;
|
||||
R6 riguarda le soluzioni alle domande dei benchmark.
|
||||
|
||||
## Perimetro dei tre esempi
|
||||
|
||||
| Esempio | Percorso didattico | Materiale semantico disponibile |
|
||||
| --- | --- | --- |
|
||||
| Financial | Iniziale | Descrizioni BIRD, codifiche, annotazioni Evidence associate ai quesiti. |
|
||||
| European Football | Intermedio | Descrizioni BIRD, significato degli indicatori e annotazioni Evidence. |
|
||||
| F1 | Avanzato | Metadati Spider 2.0-Lite e documenti di dominio, fra cui sorpassi e tipi di giro. |
|
||||
|
||||
Questa progressione è didattica, non una misura delle prestazioni di ThothII.
|
||||
La maggiore complessità di F1 non implica una copertura semantica completa:
|
||||
le lacune vanno dichiarate nel materiale di accompagnamento.
|
||||
|
||||
Le fonti sono SQLite e documentazione separata. I CSV BIRD delle descrizioni non
|
||||
sono i dati delle tabelle. La dimensione PostgreSQL, inclusi indici e spazio
|
||||
temporaneo di caricamento, deve essere misurata durante la preparazione; non si
|
||||
deduce dalla sola dimensione SQLite. Le misure sorgente sono nella
|
||||
[ricerca sulle dimensioni](../research/2026-09-27-example-database-sizes.md).
|
||||
|
||||
## Architettura di riferimento
|
||||
|
||||
ThothII include già il servizio PostgreSQL `catalog-db`; il database applicativo
|
||||
è `thothii_catalog`. Il progetto propone di usare la stessa istanza per tre database
|
||||
di esempio distinti, senza mescolare le loro tabelle con quelle applicative.
|
||||
|
||||
Il contratto corrente associa un database a un workspace: il pacchetto contiene
|
||||
quindi tre workspace, ciascuno con il proprio database e un singolo schema
|
||||
applicativo. Non è previsto un cambiamento verso workspace multi-database.
|
||||
|
||||
La CLI di importazione usa credenziali di caricamento separate dalle credenziali
|
||||
in sola lettura con cui ThothII interroga gli esempi. Non riutilizza il ruolo runtime
|
||||
del Metadata Catalog per creare o caricare database. I segreti restano locali,
|
||||
fuori dal repository, dai manifest pubblici e dai log.
|
||||
|
||||
Il PostgreSQL interno non richiede l'esposizione di una porta sull'host: il
|
||||
caricatore deve poter operare nella rete dello stack. Una connessione a un server
|
||||
PostgreSQL alternativo è un'eventuale estensione, non un requisito iniziale.
|
||||
|
||||
## Distribuzione e contenuti
|
||||
|
||||
Struttura illustrativa, da adattare alle convenzioni del repository prescelto:
|
||||
|
||||
```text
|
||||
thoth-workspaces.yaml
|
||||
examples/
|
||||
README.md
|
||||
cli/
|
||||
manifests/
|
||||
financial.yaml
|
||||
european-football.yaml
|
||||
f1.yaml
|
||||
docs/
|
||||
financial-practice.md
|
||||
european-football-practice.md
|
||||
f1-practice.md
|
||||
example-financial/
|
||||
workspace.yaml
|
||||
evidence/
|
||||
source/
|
||||
curated/
|
||||
example-football/...
|
||||
example-f1/...
|
||||
```
|
||||
|
||||
La Source Evidence rimane nel percorso canonico `<workspace-id>/evidence`;
|
||||
il documento di esercitazione è esterno al corpus delle Evidence. Il solo fatto
|
||||
di trovarsi nel repository non deve rendere le domande regole di dominio ricercabili.
|
||||
|
||||
**Adeguamento necessario in ThothII:** il lettore attuale considera workspace tutte
|
||||
le directory alla radice, eccetto `workspace-docs`, e ne verifica la corrispondenza
|
||||
con il catalogo. Una nuova `examples/` non è quindi accettata automaticamente.
|
||||
Il sottoprogetto deve estendere esplicitamente questo contratto per riconoscerla
|
||||
come directory ausiliaria, preservando la validazione dei veri workspace;
|
||||
non deve registrarla come workspace fittizio. Riferimenti:
|
||||
`backend/src/workspaces/git-repository.ts:212` e
|
||||
`backend/src/workspaces/registry.ts:515`.
|
||||
|
||||
Nel repository Git risiedono CLI, manifest, documentazione e definizioni dei
|
||||
workspace. Gli archivi voluminosi dei dati sono scaricati su richiesta da URL
|
||||
versionati, con checksum, cache e attribuzioni. Il luogo di pubblicazione dei
|
||||
pacchetti derivati dipende dalla decisione sulla modalità di conversione e dai
|
||||
diritti di redistribuzione delle singole fonti: la licenza del codice di un
|
||||
benchmark non prova da sola la licenza di tutti i dati inclusi.
|
||||
|
||||
Ogni manifest identifica almeno: esempio e workspace, versione del pacchetto,
|
||||
revisioni e URL delle fonti, file da estrarre, checksum, licenze/attribuzioni,
|
||||
versione della conversione, compatibilità PostgreSQL/ThothII, inventario degli
|
||||
artefatti e risultati attesi dei controlli. Versioni e nomi non sono ricavati
|
||||
silenziosamente da un riferimento mobile come `main`.
|
||||
|
||||
La verifica delle fonti del 2026-09-27 ha rilevato CC BY-SA 4.0 nella dataset card
|
||||
BIRD e MIT per software/documentazione nel repository Spider2. Questo non chiarisce
|
||||
da solo la redistribuibilità di ciascun database fornito negli archivi esterni:
|
||||
per i tre dump PostgreSQL lo stato è ancora da verificare, non un divieto accertato.
|
||||
Registrare licenza dichiarata, fonte e stato della verifica separatamente per dati,
|
||||
descrizioni, Evidence, domande e codice. La verifica sulla versione esatta è una
|
||||
condizione di pubblicazione dei pacchetti; la conversione locale rimane l'eccezione
|
||||
prevista da D2. Fonti: [card BIRD](https://huggingface.co/datasets/birdsql/bird_mini_dev),
|
||||
[repository BIRD](https://github.com/bird-bench/mini_dev),
|
||||
[licenza Spider2](https://github.com/xlang-ai/Spider2/blob/main/LICENSE) e
|
||||
[download Spider2-Lite](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/README.md).
|
||||
|
||||
## Schema commentato e conversione
|
||||
|
||||
Per ogni database si prepara un contratto di conversione per tabella e colonna,
|
||||
fondato sull'ispezione sia dello schema sia dei valori effettivi. Non basta
|
||||
tradurre il tipo dichiarato da SQLite, che può contenere valori eterogenei.
|
||||
|
||||
| Area | Regola di accettazione |
|
||||
| --- | --- |
|
||||
| Interi e identificatori | Range compatibili, nessun overflow; i codici con zeri iniziali restano codici. |
|
||||
| Decimali e floating point | Precisione e scala dichiarate; nessun arrotondamento silenzioso. |
|
||||
| Date e orari | Formato, granularità e timezone documentati; non inventare una timezone. |
|
||||
| Durate | Non confonderle con orari del giorno; rappresentazione e unità esplicite. |
|
||||
| Booleani e categorie | Conversione solo con codifiche verificate; distinguere sconosciuto e falso. |
|
||||
| Null e testo | Distinguere NULL, stringa vuota e sentinelle; preservare Unicode, virgole e newline. |
|
||||
| Colonne senza tipo o miste | Profilazione completa e decisione esplicita; errore comprensibile se non conformi. |
|
||||
| Identificatori SQL | Mapping stabile e quoting coerente per maiuscole, parole riservate e caratteri speciali. |
|
||||
| PK, FK e indici | Separare vincoli presenti, relazioni documentate e relazioni inferite; verificare prima di imporre. |
|
||||
| Contenuti strutturati | Conservare il significato di XML/JSON/testi complessi senza trasformazioni non documentate. |
|
||||
|
||||
Ogni cambiamento rispetto alla sorgente compare in un rapporto di conversione.
|
||||
Per casi anomali non sono ammessi scarto di righe o sostituzione con NULL senza
|
||||
una regola esplicita e verificata. I controlli confrontano conteggi e valori
|
||||
normalizzati per tabella; un solo confronto dei conteggi non basta.
|
||||
|
||||
Le descrizioni disponibili diventano veri `COMMENT ON TABLE` e
|
||||
`COMMENT ON COLUMN` nel database PostgreSQL, mantenendo provenienza e segnalando
|
||||
le descrizioni mancanti. Eventuali integrazioni redazionali sono distinte dalle
|
||||
descrizioni originali. Questi commenti devono essere visibili anche nel Metadata
|
||||
Catalog usato da ThothII; la sola presenza dei commenti in PostgreSQL non soddisfa
|
||||
il requisito se la sincronizzazione del Catalog li ignora.
|
||||
|
||||
Il percorso esiste già: `backend/src/catalog/schema-introspector.ts:84` e `:106`
|
||||
leggono `pg_description`; `metadata-snapshot.ts:52` applica la precedenza
|
||||
descrizione curata, descrizione generata, commento sorgente. Il collaudo deve
|
||||
considerare questa precedenza: non cancellare una descrizione curata per far
|
||||
apparire un commento importato.
|
||||
|
||||
## Evidence e documento di esercitazione
|
||||
|
||||
Le fonti documentali e le annotazioni Evidence sono raccolte senza introdurre
|
||||
regole inventate. Un'annotazione specifica di una domanda conserva il contesto
|
||||
necessario: non diventa automaticamente una regola valida per tutto il database.
|
||||
Duplicati e conflitti vengono riconciliati conservando i riferimenti originali.
|
||||
|
||||
L'archivio distingue Source Evidence e Curated Evidence nel formato supportato
|
||||
da ThothII. La curation avviene prima del rilascio: il pacchetto contiene le fonti
|
||||
e le unità curate, con riferimenti verificabili e lacune dichiarate. I file originali
|
||||
non vengono presentati come Evidence già revisionate. Qdrant contiene la proiezione
|
||||
ricercabile, non sostituisce l'archivio delle Evidence. L'utente finale può modificare
|
||||
e arricchire la curation, ma non deve completarla per iniziare a usare l'esempio.
|
||||
|
||||
Il documento di esercitazione contiene domande disponibili, fonte e identificativo,
|
||||
raggruppamento tematico, eventuali note sui limiti dei dati e riferimenti utili.
|
||||
Non contiene soluzioni SQL né risposte attese per il confronto automatico.
|
||||
Se necessario, si adattano i riferimenti ai nomi PostgreSQL, rendendo riconoscibile
|
||||
la modifica. Guide, domande e contenuti semantici curati sono disponibili in italiano
|
||||
e inglese, conservando gli originali e rendendo riconoscibili le traduzioni;
|
||||
gli identificatori SQL restano invariati. Le rappresentazioni linguistiche di una
|
||||
stessa Evidence non devono duplicarne il risultato nella ricerca.
|
||||
|
||||
Gli archivi originali possono includere SQL target. L'estrazione per il prodotto
|
||||
ammette solo i campi necessari a schema, documentazione, Evidence e domande;
|
||||
gli SQL target non entrano nei workspace, negli indici o nei documenti didattici.
|
||||
|
||||
## Comportamento della CLI
|
||||
|
||||
L'interfaccia esatta sarà definita dopo le decisioni di questo PRD. Le capacità
|
||||
richieste sono: elencare gli esempi e i prerequisiti, scegliere un sottoinsieme,
|
||||
scaricare/verificare, caricare, collegare i workspace e mostrare lo stato per esempio.
|
||||
|
||||
1. Individuare l'installazione e verificare compatibilità, servizi e spazio.
|
||||
2. Risolvere i manifest e mostrare cosa verrà caricato per gli esempi scelti.
|
||||
3. Scaricare solo i pacchetti necessari; riutilizzare gli archivi condivisi in cache.
|
||||
4. Verificare ed estrarre il pacchetto PostgreSQL già convertito; l'eventuale
|
||||
conversione locale eccezionale deve essere dichiarata dal manifest.
|
||||
5. Caricare in un database di preparazione e verificarne dati, tipi, vincoli e commenti.
|
||||
6. Rendere disponibile il database verificato e registrare il binding nel Catalog.
|
||||
7. Sincronizzare metadati, importare le Evidence già curate ed eseguire
|
||||
consolidamento/preprocessing per rendere il workspace subito utilizzabile.
|
||||
8. Fornire un riepilogo per esempio, il documento con le domande e il prossimo passo.
|
||||
|
||||
Lo stato deve distinguere almeno dati caricati, metadati sincronizzati, Evidence
|
||||
disponibili, indicizzazione completata e workspace pronto. Un download concluso
|
||||
non equivale a un esempio utilizzabile. Se gli esempi hanno esiti diversi, il
|
||||
riepilogo deve mostrare successi e fallimenti separatamente.
|
||||
|
||||
La riesecuzione della stessa versione non duplica dati e non sovrascrive le
|
||||
Evidence modificate dall'utente. Un errore non sostituisce un database funzionante;
|
||||
lo stato permette di riprendere dalle fasi completate. Il preprocessing corrente
|
||||
non è internamente resumable: in caso di errore quella fase viene rieseguita.
|
||||
Aggiornamento di versione, ripristino e rimozione distruttiva richiedono operazioni
|
||||
esplicite distinte dalla normale installazione e sono esclusi dalla prima versione
|
||||
della CLI, che comprende elenco/selezione, installazione, verifica e ripresa dopo errore.
|
||||
|
||||
L'integrazione deve usare le API esistenti per creazione del database nel Catalog,
|
||||
binding e secret store (`backend/src/routes/catalog-databases.ts`), con
|
||||
autenticazione e permessi appropriati. La sincronizzazione dello schema è un
|
||||
run distinto, con conferma esplicita (`backend/src/routes/catalog-schema.ts:189`
|
||||
e `:223`): il progetto deve definire come presentare o gestire quella conferma
|
||||
senza aggirarne il contratto. `workspace preprocess run` ed Evidence consolidate
|
||||
sono già disponibili come CLI, ma non creano binding o credenziali per conto del
|
||||
caricatore. Si veda [il contratto preprocessing](../contracts/workspace-preprocessing-cli.md).
|
||||
|
||||
## Collaudo e condizioni di completamento
|
||||
|
||||
- Ogni esempio ha un inventario verificato di schema, dati, commenti, Evidence e domande.
|
||||
- Il repository con `examples/` supera la validazione e mantiene i controlli
|
||||
sulle directory dei workspace; nessun file della CLI viene eseguito dal pull.
|
||||
- Tutte le sette selezioni non vuote producono esclusivamente gli esempi scelti.
|
||||
- La selezione di nessun esempio non ostacola l'installazione di ThothII.
|
||||
- Si verificano conversione dei valori, vincoli, commenti e propagazione al Catalog.
|
||||
- Il ruolo di interrogazione può leggere i dati e non può modificarli.
|
||||
- Interruzione del download, checksum errato, errore d'importazione e spazio
|
||||
insufficiente producono uno stato recuperabile e non danneggiano esempi esistenti.
|
||||
- Ripetere un'installazione completata non altera dati né curation locale.
|
||||
- La copia indipendente non contiene storia Git o relazione di fork dell'originale,
|
||||
né remote verso di esso; mantiene versione, checksum, licenze e attribuzioni.
|
||||
- Il percorso di download non richiede credenziali di scrittura verso il repository
|
||||
pubblico e non esegue push. In entrambe le modalità l'utente può modificare
|
||||
workspace ed Evidence locali e continuare a usarli dopo il riavvio.
|
||||
- Una sessione reale può interrogare ciascun esempio, con Evidence reperibili;
|
||||
non è richiesto riprodurre l'SQL di un benchmark.
|
||||
- Ogni workspace risulta subito utilizzabile anche dopo riavvio; le Evidence
|
||||
curate sono effettivamente reperibili e non solo presenti sul filesystem.
|
||||
- Primo rilascio verificato su Windows/WSL2 e Docker Desktop; secondo su Omarchy;
|
||||
terzo su macOS. Nessuna dichiarazione di supporto a una tappa non ancora verificata.
|
||||
|
||||
La proposta è eseguire conversione/caricamento in container, senza introdurre
|
||||
Python o Node obbligatori sull'host dell'utente. Il metodo di avvio/download della
|
||||
CLI resta da precisare in base alla scelta dei pacchetti.
|
||||
|
||||
## Decisioni approvate con grill-with-docs
|
||||
|
||||
Approvazione dell'utente del 2026-09-27: «ok a tutto», riferita a D1, D2 e D3.
|
||||
Nel round successivo l'utente approva D4 con precisazione della distribuzione Gitea,
|
||||
D5 e D7. Dopo il chiarimento approva anche D6, ribadendo che chi installa deve
|
||||
trovare tutto pronto, e aggiunge D8 sulla copia autonoma o sul download in sola lettura.
|
||||
|
||||
| ID | Decisione | Esito approvato |
|
||||
| --- | --- | --- |
|
||||
| D1 | Quando proporre il caricamento? | CLI autonoma dopo il setup, richiamabile anche come ultimo passo facoltativo dello stesso setup. |
|
||||
| D2 | Dove convertire le sorgenti verso PostgreSQL? | Preparare e verificare pacchetti PostgreSQL versionati nella fase di rilascio; la CLI dell'utente scarica e carica. Conservare la ricetta di conversione riproducibile. Se una fonte non è redistribuibile, valutarne la conversione locale. |
|
||||
| D3 | Quanto deve essere pronto l'esempio dopo il caricamento? | Dati, commenti e Evidence curate in anticipo, già sincronizzate e indicizzate, per consentire subito una sessione; curation successiva resta disponibile all'utente. |
|
||||
| D4 | Repository di distribuzione | Il repository pubblico ThothII su git.tylconsulting.it rimanda a un repository pubblico dedicato agli esempi su Gitea gestito da TYL Consulting. Per installazioni con un repository proprio, il curatore integra i contenuti degli esempi in quel repository. Nessun nuovo supporto multi-repository in questo sottoprogetto. |
|
||||
| D5 | Lingua dei contenuti | Guide, domande e contenuti semantici curati in italiano e inglese; originali conservati, traduzioni riconoscibili e identificatori SQL invariati. Nessuna duplicazione della stessa Evidence nella ricerca. |
|
||||
| D6 | Preparazione e verifica delle Evidence | Il progetto prepara e controlla i contenuti; all'utente vengono sottoposte solo ambiguità o conflitti non risolvibili dalle fonti, con una proposta concreta. Chi installa riceve tutto pronto e non deve revisionare le Evidence per iniziare. |
|
||||
| D7 | Prima versione della CLI | Elenco/selezione, installazione, verifica e ripresa dopo errore. Aggiornamento di versione, reset e disinstallazione rimandati; nessuna sostituzione automatica di esempi modificati. |
|
||||
| D8 | Copia autonoma e sola lettura | Copia indipendente senza storia/remote/relazione di fork dell'originale, oppure scaricamento dal repository pubblico in sola lettura. Il limite riguarda la scrittura sul repository originale: workspace ed Evidence locali rimangono modificabili. Versioni, licenze e attribuzioni sono conservate. |
|
||||
|
||||
La risposta «1» dell'utente conferma per D8 la sola lettura remota e la modificabilità locale.
|
||||
Nome e URL del repository destinazione saranno definiti prima della pubblicazione.
|
||||
Interfaccia CLI, autenticazione e custodia dei segreti saranno definite nella
|
||||
specifica tecnica coerentemente con i contratti esistenti. Le verifiche tecniche
|
||||
e dei diritti sulle fonti sono lavoro del progetto e non domande demandate all'utente.
|
||||
|
||||
## Contesto del secondo round e chiarimento D6
|
||||
|
||||
La verifica locale ha individuato il repository PSD privato, mentre i template
|
||||
generici riportano un URL esemplificativo. Non è stato individuato un repository
|
||||
concreto già destinato agli esempi. L'installazione supporta una sola sorgente Git:
|
||||
la scelta di un repository per gli esempi non deve sostituire implicitamente il
|
||||
repository già configurato in un'installazione esistente.
|
||||
|
||||
D6 riguarda la verifica del significato delle Evidence adattate dalle fonti:
|
||||
per esempio, un'annotazione riferita a una singola domanda non può diventare una
|
||||
regola generale senza supporto documentale. Non riguarda la scrittura da zero delle
|
||||
Evidence da parte dell'utente o una revisione a ogni installazione.
|
||||
|
||||
Chiarimento approvato per D6: il progetto prepara i contenuti, ne
|
||||
controlla provenienza, coerenza e adattamento a PostgreSQL; all'utente vengono
|
||||
sottoposte solo ambiguità o conflitti non risolvibili dalle fonti, con una proposta
|
||||
concreta. I punti irrisolti restano segnalati ed esclusi dalle regole pubblicate
|
||||
come verificate. L'utilizzatore finale riceve il materiale già curato.
|
||||
|
||||
## D8 — Copia del repository e permessi
|
||||
|
||||
Richiesta dell'utente: «fork del repository senza memoria dell'originale, o lo
|
||||
scarico in locale ma senza diritti di scrittura». Il risultato deve restare pronto
|
||||
all'uso e non richiedere un lavoro di curation a chi installa.
|
||||
|
||||
La proposta tecnica per la copia indipendente è estrarre un rilascio verificato
|
||||
senza la directory `.git` originaria; se il runtime richiede Git, inizializzare
|
||||
una nuova storia locale, senza remote verso l'originale né associazione di fork
|
||||
sulla piattaforma. Un fork ordinario che conserva storia e relazione col repository
|
||||
originario non soddisfa questo significato di indipendenza. L'eventuale pubblicazione
|
||||
in un repository personale è un'operazione separata, non implicita nell'installazione.
|
||||
|
||||
Versione del pacchetto, checksum, licenze e attribuzioni rimangono nel manifest e
|
||||
nella documentazione: l'assenza di memoria Git non elimina la provenienza dei dati
|
||||
e delle Evidence. Nessun aggiornamento automatico deve sovrascrivere una copia
|
||||
personalizzata.
|
||||
|
||||
Per il percorso di download, la scelta approvata è accesso anonimo in sola
|
||||
lettura al repository pubblico, senza credenziali di scrittura e senza operazioni
|
||||
di push. File e archivio locale delle Evidence restano modificabili dall'utente.
|
||||
Il filesystem locale non è reso globalmente in sola lettura.
|
||||
|
||||
**Adeguamento necessario nel runtime:** la copia senza `.git` non è oggi una sorgente
|
||||
completa per ThothII. Il lettore richiede `HEAD` e file committati
|
||||
(`backend/src/workspaces/git-repository.ts:198`); il refresh esegue fetch del branch
|
||||
da `origin` e rifiuta checkout sporchi o divergenze (`:467–485`). Il solo `git init`
|
||||
senza remote non completa quindi il percorso corrente.
|
||||
|
||||
La specifica deve prevedere una sorgente locale autonoma, oppure una nuova copia
|
||||
Git locale usata come sorgente del checkout gestito: eventuali riferimenti Git
|
||||
interni all'installazione non devono puntare al repository pubblico originale.
|
||||
Il backend già accetta percorsi Git locali assoluti/file URL (`:60–64`), ma setup,
|
||||
configurazione e aggiornamento devono supportare coerentemente il percorso scelto.
|
||||
Le due modalità devono funzionare senza chiedere all'utente di configurare Git.
|
||||
|
||||
Il download HTTPS anonimo è compatibile con il consumo remoto del backend; va
|
||||
verificato anche nel bootstrap dell'installazione. Il checkout gestito non è la
|
||||
cartella da sporcare con modifiche manuali: la procedura deve rendere esplicita una
|
||||
copia locale modificabile dei workspace e gestirne l'attivazione senza push verso
|
||||
l'originale. L'archivio locale delle Evidence è già separato e modificabile.
|
||||
Riferimenti: `docs/contracts/workspace-evidence-v3.md:218` e il contratto delle
|
||||
Evidence curate. I controlli di integrità del checkout non vanno disabilitati per
|
||||
ottenere la modificabilità richiesta.
|
||||
|
||||
## Passaggio alla specifica tecnica
|
||||
|
||||
La definizione dei requisiti è conclusa con D1–D8. La specifica dovrà tradurli in
|
||||
questi blocchi verificabili, prima dell'implementazione:
|
||||
|
||||
1. Contratto del repository: cartella `examples/`, distribuzione pubblica e copia
|
||||
autonoma o accesso remoto in sola lettura, con personalizzazioni locali persistenti.
|
||||
2. Preparazione dei tre pacchetti: fonti e diritti verificati, conversione di
|
||||
schema/dati/tipi, commenti, Evidence curate e materiale didattico bilingue.
|
||||
3. CLI: download, verifica, importazione isolata, binding, sincronizzazione e
|
||||
indicizzazione, stato e ripresa dopo errore, senza push verso l'originale.
|
||||
4. Integrazione facoltativa nel setup, collegamenti fra repository e documentazione.
|
||||
5. Collaudo Windows, successivamente Omarchy, infine macOS.
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [BIRD mini-dev: dati e documentazione](https://github.com/bird-bench/mini_dev).
|
||||
- [Dataset card BIRD](https://huggingface.co/datasets/birdsql/bird_mini_dev).
|
||||
- [Spider 2.0-Lite: download e formati](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite).
|
||||
- [Ricerca sui candidati e sulle Evidence](../research/2026-09-27-spider2-lite-evidence-candidates.md).
|
||||
- [Contratto workspace/Evidence](../contracts/workspace-evidence-v3.md),
|
||||
[modulo Evidence](../evidence.md), [glossario](../../CONTEXT.md),
|
||||
[ADR 0001 — Metadata Catalog](../adr/0001-postgres-metadata-catalog.md),
|
||||
[ADR 0003 — binding locali](../adr/0003-installation-local-database-bindings.md).
|
||||
@@ -0,0 +1,43 @@
|
||||
# What ThothII does
|
||||
|
||||
ThothII helps turn a natural-language question into reviewed SQL. It is intended for
|
||||
people who know the meaning of their data and need to make the assumptions behind a
|
||||
query explicit. The model proposes; a human reviewer approves, corrects or rejects.
|
||||
|
||||
## From a question to a reusable result
|
||||
|
||||
The [eight-phase workflow](skills.md) clarifies the question, consults reusable knowledge,
|
||||
selects relevant Evidence and database objects, prepares a query plan, and produces SQL
|
||||
for review. Approved knowledge can be saved for later questions.
|
||||
|
||||
- **Workspace:** the domain context and its Evidence configuration.
|
||||
- **Database catalog:** tables, columns, relationships and reviewed descriptions.
|
||||
- **Evidence:** domain sources and rules with provenance that a reviewer can inspect.
|
||||
- **Memory:** reusable clarifications, SQL rules, solved questions and explained errors.
|
||||
- **Session:** the saved artifacts and decisions for one question, not a permanent chat transcript.
|
||||
|
||||
Resuming a session uses its saved state. Model output is a proposal, not a guarantee of
|
||||
correctness: review the scope, assumptions, sources and SQL before relying on the result.
|
||||
|
||||
## What an installation includes
|
||||
|
||||
The Docker stack includes the web application, its runtime, a PostgreSQL metadata/Memory
|
||||
catalog, Qdrant and the embedding service. A browser is the normal user interface; the
|
||||
host `tht` command is used to configure and operate the installation.
|
||||
|
||||
The data warehouse and generative model endpoints are configured separately. Docker
|
||||
does not supply their credentials, network access or domain data. A standalone installation
|
||||
is therefore self-hosted, but is not automatically offline or independent of those services.
|
||||
Review data-access permissions and the model-provider configuration before using real data.
|
||||
|
||||
## Choose your next step
|
||||
|
||||
- Install on Mac, Windows through WSL2, or Linux: [Italian](install/standalone-manual-it.md)
|
||||
or [English](install/standalone-manual-en.md) manual procedure.
|
||||
- Configure [display mode and language](install/shell-and-language.md),
|
||||
[authentication](install/authentication-local.md) and [models](general/pi-configuration.md).
|
||||
- Prepare [workspaces](operations/workspaces.md) and [databases](operations/database-management.md).
|
||||
- Start a reviewed question using the [user guide](guida-utente.md).
|
||||
|
||||
The installation guides state the platform tests still to complete. Availability of a
|
||||
procedure is not a certification that every target machine has been tested.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Knowledge archives: consolidated implementation evidence
|
||||
|
||||
Consolidated on 15 September 2026 from the M1–M3, E1–E3 and X1 records of 8–9 September.
|
||||
This is historical verification evidence, not a claim that these test counts describe today's
|
||||
tree or that every installation has passed acceptance. Original commands, detailed outcomes and
|
||||
local deployment details remain under `docs/plans/` in Git commit
|
||||
`5f3a7f5975b96fae1e1cdd0da08b4d60d41064cc`.
|
||||
|
||||
| Increment | Delivered boundary | Recorded verification |
|
||||
| --- | --- | --- |
|
||||
| M1 | PostgreSQL Memory authority, administration, durable indexing retry | 1,134 harness + 9 portable cases; 17 real PostgreSQL/Qdrant cases; 190 Pi gates; 632 frontend. One backend auth timeout passed its isolated rerun. |
|
||||
| M2 | Dense/BM25 recall, scoped links and explicit projection rebuild | 1,152 harness; 78 targeted cases with real embedding; 13 Fastify API cases; 10 wheel/CLI cases. |
|
||||
| M3 | Human Memory promotion, receipts and physical-schema dependency cleanup | 1,152 harness + 9 portable; 41 Memory integration, 1 optional embedding skipped, 1 L2 excluded; 195 Pi gates; 635 frontend; 5 Catalog integration. Backend timing case passed isolated rerun. |
|
||||
| E1 | Editable file authority and explicit consolidation | 1,180 harness + 9 portable; real Qdrant including optional 35-unit PSD probe. No actual PSD authoring checkout conversion in E1. |
|
||||
| E2 | Evidence administration, host CLI and pending activation recovery | 1,355 backend, 639 frontend, 1,248 harness; portable-path rerun passed with THT_HOME unset. Initial authenticated visual acceptance remained manual. |
|
||||
| E3 | Draft import, explicit source refresh and protected manual corrections | 1,359 backend, 641 frontend, 1,256 harness; 24 focused checks. Synthetic filesystem/HTTP/S3 behavior, not a live S3-account certification. |
|
||||
| X1 | Human-reviewed Memory/Evidence conflict correction and durable recovery | 1,264 harness + 9 portable; 1,366 backend, 645 frontend, 199 Pi gates; desktop/mobile widget probe and later real authenticated administration probe. |
|
||||
|
||||
X1's configured `zai/glm-5.3` probe used synthetic conflicting knowledge. It was not a full
|
||||
autonomous Pi-session certification or acceptance of PSD semantics. Later administration
|
||||
checks exercised real authentication and a disposable synthetic workspace, including persistence
|
||||
across backend restart. Existing PSD archive content was not rewritten by those probes.
|
||||
|
||||
## Current authorities and repeatable checks
|
||||
|
||||
- [Memory implementation and storage](../gestione-memory.md), ADR 0018.
|
||||
- [Editable Evidence](../contracts/curated-evidence-v4.md), ADR 0019.
|
||||
- [Session corrections](../contracts/archive-repair.md).
|
||||
- [Evidence lifecycle acceptance](../testing/evidence-lifecycle-test-plan.md).
|
||||
- Harness tests under `tests/memory/`, Evidence integration tests, backend route/service tests,
|
||||
Pi gate tests and frontend tests are the executable regression boundaries. Run portable-path
|
||||
tests without a THT_HOME override; optional L2/provider tests require separate authorization.
|
||||
|
||||
Do not equate passing synthetic tests with real-provider quality, live S3 coverage, PSD-domain
|
||||
acceptance or permission to migrate another installation. Those remain explicit operator gates.
|
||||
|
||||
## Catalog/model design records consolidated at the same time
|
||||
|
||||
The old metadata-catalog exploration and description-generation plan/spec are no longer
|
||||
current-state authorities. PostgreSQL/Fastify ownership, installation bindings, description
|
||||
generation and source-sampling constraints now live in ADRs 0001–0016,
|
||||
[architecture](../architecture/overview.md), [Database Management](../operations/database-management.md)
|
||||
and the [description acceptance checklist](../testing/2026-08-29-ai-catalog-description-generation-acceptance.md).
|
||||
The installation-model plan is replaced by ADR 0013 and the
|
||||
[current model catalog guide](../general/pi-configuration.md).
|
||||
|
||||
Preserve these outstanding questions rather than infer acceptance from implementation:
|
||||
real provider/DWH acceptance recorded by the owner, licensing review of shipped optional models,
|
||||
future dialect/multi-schema support, and any desired semantic aliases/value descriptions.
|
||||
The former proposed catalog-to-core cutover and separate database permissions are already
|
||||
represented by current ADR 0016 and `database.manage`; do not reopen them as unfinished steps.
|
||||
The original description-generation plan referred to issue #4 for final delivery gates;
|
||||
this consolidation neither changes nor closes its tracker state.
|
||||
@@ -1,420 +0,0 @@
|
||||
# Inventario delle funzionalità legacy di gestione metadati di ThothAI
|
||||
|
||||
Data dell'inventario: 2026-08-23
|
||||
|
||||
Ultima verifica rispetto a ThothII: 2026-08-31
|
||||
|
||||
Stato: **inventario storico verificato; non è una specifica dello stato corrente**.
|
||||
|
||||
Issue originaria: [mptyl/ThothII#6](https://git.tylconsulting.it/mptyl/ThothII/issues/6)
|
||||
|
||||
Fonte primaria: repository legacy annidato `Thoth/ThothAI`, commit
|
||||
`55855de0f18e5cb4bc72f0a2ab0a7317995186dd`.
|
||||
|
||||
Le citazioni che iniziano con `/Thoth/ThothAI/` sono relative alla radice di quella copia legacy
|
||||
fissata al commit indicato. Alla verifica del 2026-08-31 tutti i 68 riferimenti univoci puntavano a
|
||||
file esistenti e a intervalli di righe validi.
|
||||
|
||||
> Questo documento conserva l'inventario e le evidenze degli anti-pattern di ThothAI. Le frasi di
|
||||
> requisito nelle sezioni successive descrivono la baseline proposta il 2026-08-23; non prevalgono
|
||||
> su ADR, contratti, codice o `PROJECT_STATE.md` correnti.
|
||||
|
||||
## Stato rispetto al codice corrente
|
||||
|
||||
### Fonti autorevoli correnti
|
||||
|
||||
Per capire cosa esiste oggi, usare nell'ordine:
|
||||
|
||||
- `PROJECT_STATE.md`, per lo snapshot operativo aggiornato;
|
||||
- `CONTEXT.md`, per il modello di dominio corrente;
|
||||
- il [piano accettato del Metadata Catalog](../plans/2026-08-26-metadata-catalog-from-thothai.md)
|
||||
e il [contratto dello schema snapshot](../contracts/catalog-schema-snapshot.md);
|
||||
- gli ADR del catalogo, in particolare
|
||||
[0001](../adr/0001-postgres-metadata-catalog.md),
|
||||
[0004](../adr/0004-fastify-kysely-metadata-catalog.md),
|
||||
[0006](../adr/0006-separate-physical-and-logical-relationships.md),
|
||||
[0007](../adr/0007-durable-authoritative-schema-synchronization.md),
|
||||
[0008](../adr/0008-allow-manual-catalog-metadata-cleanup.md),
|
||||
[0009](../adr/0009-use-one-sequential-description-generation-run.md),
|
||||
[0010](../adr/0010-allow-bounded-real-source-samples-for-description-generation.md) e
|
||||
[0011](../adr/0011-gate-source-samples-with-a-sensitive-data-flag.md);
|
||||
- l'implementazione, soprattutto `backend/src/catalog/types.ts`,
|
||||
`backend/src/routes/catalog-databases.ts`, `backend/src/routes/catalog-schema.ts`,
|
||||
`backend/src/routes/catalog-description-generation.ts`,
|
||||
`backend/src/routes/catalog-description-consolidation.ts` e
|
||||
`frontend/src/shell/DatabaseManagementPage.tsx`.
|
||||
|
||||
### Disposizione della baseline storica
|
||||
|
||||
| Capacità inventariata | Disposizione al 2026-08-31 | Evidenza corrente o nota |
|
||||
|---|---|---|
|
||||
| Configurazione per workspace, secret separati e test connessione | **Adottata e implementata** | PostgreSQL interno, binding `postgres_direct`, `rest_api` o `ssh_tunnel`, secret write-only; ADR [0001](../adr/0001-postgres-metadata-catalog.md)–[0004](../adr/0004-fastify-kysely-metadata-catalog.md) e `backend/src/routes/catalog-databases.ts`. |
|
||||
| Inventario fisico di tabelle, colonne, PK e FK | **Adottato e implementato** | La struttura osservata è distinta dai contenuti curati; `backend/src/catalog/types.ts`, `backend/src/routes/catalog-schema.ts` e ADR [0006](../adr/0006-separate-physical-and-logical-relationships.md). |
|
||||
| Riconciliazione completa e osservabile dello schema | **Implementata; semantica storica parzialmente superata** | I durable Catalog Sync Runs sono autoritativi, fail-closed, atomici e richiedono conferma per diff distruttivi. Non esiste il lifecycle `drift/removed` proposto qui: la sincronizzazione riconcilia la membership e ADR [0008](../adr/0008-allow-manual-catalog-metadata-cleanup.md) consente anche cleanup manuale esplicito, superando ADR-0005. |
|
||||
| Descrizione curata e Generated Description separate | **Adottata e implementata** | Tabelle e colonne espongono entrambi i campi in `backend/src/catalog/types.ts`; la copia selettiva AI → curato è in `backend/src/routes/catalog-description-consolidation.ts`. |
|
||||
| Generazione AI selettiva con run, stato e log | **Adottata e implementata** | Un run asincrono installazione-wide, sequenziale, con eventi persistiti e senza resume automatico; ADR [0009](../adr/0009-use-one-sequential-description-generation-run.md) e `backend/src/routes/catalog-description-generation.ts`. I thread daemon legacy sono **esclusi**. |
|
||||
| Campioni reali per la generazione e protezione dei campi sensibili | **Implementata come estensione correttiva** | ADR [0010](../adr/0010-allow-bounded-real-source-samples-for-description-generation.md) e [0011](../adr/0011-gate-source-samples-with-a-sensitive-data-flag.md): campioni bounded per colonne non sensibili e valori sintetici deterministici per quelle sensibili. |
|
||||
| Proposte persistenti, diff e versioni dei testi AI | **Escluse** | Resta un solo Generated Description modificabile. La cronologia dei run è operativa: non conserva prompt, output grezzo, proposta per colonna o audit della decisione umana. |
|
||||
| Relazioni fisiche | **Adottate e implementate** | Sono constraint immutabili con coppie ordinate di colonne; ADR [0006](../adr/0006-separate-physical-and-logical-relationships.md). |
|
||||
| Relazioni logiche curate o inferite | **Differite/aperto** | ADR-0006 riserva un modello e un lifecycle separati; non sono ancora parte del catalogo corrente. |
|
||||
| Alias semantici, descrizioni dei valori, sinonimi e concetti | **Differiti/aperti** | `PROJECT_STATE.md` li assegna a slice dedicate; non vanno dedotti dai campi fisici già implementati. |
|
||||
| Scope AI, ERD Mermaid e documentazione aggregata | **Differiti/aperti** | Restano capacità legacy inventariate, non una feature corrente del Metadata Catalog. Un eventuale lavoro dovrà avere contratto e gate propri. |
|
||||
| Export CSV e script SQL dei commenti | **Differiti/aperti; varianti insicure escluse** | Non risultano nella API corrente. Export di segreti, CSV incoerenti e SQL ricostruito da tipi incompleti restano vietati dagli anti-pattern sotto. |
|
||||
| Inferenza euristica e validazione di relazioni candidate | **Differita/aperta** | Non va confusa con la sincronizzazione delle FK fisiche; dipende dal futuro lifecycle delle relazioni logiche. |
|
||||
| Pubblicazione del catalogo al core/schema-linking/Qdrant | **Differita e richiesta come design gate successivo** | Il runtime NL→SQL continua a usare configurazione e annotations del workspace; il cutover è esplicitamente rinviato in `PROJECT_STATE.md`. |
|
||||
| Sette motori database del legacy | **Baseline superata** | La prima versione corrente supporta PostgreSQL; l'aggiunta di altri dialetti è una decisione futura, non parità automatica. |
|
||||
| GDPR e import da installazioni ThothAI | **Fuori dalla baseline iniziale; import differito** | GDPR resta escluso. Un eventuale import richiede una iniziativa idempotente e un cutover separati, non il riuso degli ID Django. |
|
||||
| Django Admin, modifica manuale della struttura sorgente, password nel catalogo, duplicazione opaca dei database | **Esclusi** | La UI e le API correnti amministrano il catalogo e non eseguono DDL sul DWH esterno; binding e segreti hanno ownership separata. |
|
||||
|
||||
## Sintesi storica
|
||||
|
||||
La baseline di parità proposta il 2026-08-23 comprende un catalogo dei database, l'inventario
|
||||
completo di tabelle, colonne e relazioni fisiche, metadati descrittivi modificabili, relazioni
|
||||
logiche, introspezione dello schema, generazione AI di descrizioni, scope, ERD Mermaid,
|
||||
documentazione ed esportazioni operative. La UI Django Admin è soltanto l'interfaccia legacy:
|
||||
non è un requisito architetturale da riprodurre.
|
||||
|
||||
Il flusso AI per le descrizioni individuato come baseline è volutamente semplice:
|
||||
|
||||
1. l'AI scrive nel campo `generated_comment` della tabella o colonna;
|
||||
2. l'utente seleziona gli elementi desiderati;
|
||||
3. un'azione copia il testo generato nel campo descrittivo canonico, sovrascrivendolo.
|
||||
|
||||
Nel codice esaminato **non esiste un'azione inversa che copi la descrizione canonica in
|
||||
`generated_comment`**. Le due azioni inverse presenti sulle colonne copiano invece il nome
|
||||
originale nel nome espanso e viceversa. Non risultano proposal, versioni, diff o workflow di
|
||||
approvazione: aggiungerli non sarebbe parità con ThothAI.
|
||||
|
||||
La parità deve essere di capacità e comportamento utile, non dei difetti del legacy. In
|
||||
particolare non vanno replicate esportazioni di password, SQL costruito con identificatori non
|
||||
quotati, job in thread daemon, incoerenze CSV e azioni admin non funzionanti.
|
||||
|
||||
## 1. Modello dati legacy
|
||||
|
||||
### Database
|
||||
|
||||
`SqlDb` contiene:
|
||||
|
||||
- identità e connessione (`name`, host, tipo motore, nome database, porta, schema, utente e
|
||||
password);
|
||||
- configurazione SSH e ambiente (`dev`, `test`, `prod`);
|
||||
- lingua per database, scope testuale e JSON, ERD Mermaid, direttive e report GDPR;
|
||||
- stato e log separati per generazione commenti tabella/colonna, introspezione, scope, ERD,
|
||||
documentazione e GDPR.
|
||||
|
||||
Evidenze: `/Thoth/ThothAI/backend/thoth_core/models.py:298-350`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/models.py:355-439`.
|
||||
|
||||
I motori dichiarati sono sette: Informix, MariaDB, MySQL, Oracle, PostgreSQL, SQL Server e
|
||||
SQLite (`/Thoth/ThothAI/backend/thoth_core/models.py:116-123`).
|
||||
|
||||
Il modello `Workspace` collega un solo `SqlDb`; contiene inoltre configurazioni degli agenti e
|
||||
duplica parte degli stati operativi (`/Thoth/ThothAI/backend/thoth_core/models.py:731-754`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/models.py:847-877`).
|
||||
|
||||
### Tabelle e colonne
|
||||
|
||||
`SqlTable` contiene nome, descrizione canonica, commento generato e riferimento al database
|
||||
(`/Thoth/ThothAI/backend/thoth_core/models.py:454-465`).
|
||||
|
||||
`SqlColumn` contiene nome originale, nome espanso, formato dati normalizzato, descrizione
|
||||
canonica, commento generato, descrizione dei valori e indicazioni PK/FK testuali
|
||||
(`/Thoth/ThothAI/backend/thoth_core/models.py:468-485`).
|
||||
|
||||
La cancellazione usa le cascade Django: database → tabelle → colonne e relazioni. Nei modelli
|
||||
non sono definite unicità composte per database/tabella/colonna. Ogni database ha un solo
|
||||
campo `schema`; tabelle e colonne non portano una propria identità di schema. Questi limiti
|
||||
non devono diventare vincoli del nuovo catalogo.
|
||||
|
||||
### Relazioni
|
||||
|
||||
`Relationship` collega tabella e colonna sorgente a tabella e colonna destinazione
|
||||
(`/Thoth/ThothAI/backend/thoth_core/models.py:488-503`). Il metodo
|
||||
`update_pk_fk_fields` ricostruisce stringhe descrittive PK/FK sulle colonne coinvolte
|
||||
(`/Thoth/ThothAI/backend/thoth_core/models.py:505-526`).
|
||||
|
||||
Il form admin verifica che le due tabelle appartengano allo stesso database e che ogni colonna
|
||||
appartenga alla tabella selezionata
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_relationship.py:19-165`).
|
||||
|
||||
Per ThothII occorre distinguere:
|
||||
|
||||
- struttura fisica importata dal database, da trattare come inventario non modificabile;
|
||||
- descrizioni e metadati semantici, modificabili con CRUD completo;
|
||||
- relazioni logiche aggiunte dall'utente, modificabili con CRUD completo.
|
||||
|
||||
Questa separazione conserva le capacità utili del legacy senza permettere che la UI alteri o
|
||||
falsifichi accidentalmente lo schema fisico osservato.
|
||||
|
||||
## 2. Capacità esposte dal Django Admin
|
||||
|
||||
La registrazione degli admin fornisce il CRUD Django standard per database, tabelle, colonne e
|
||||
relazioni (`/Thoth/ThothAI/backend/thoth_core/admin.py:13-24`). Oltre al CRUD, le azioni
|
||||
specifiche sono le seguenti.
|
||||
|
||||
### Database
|
||||
|
||||
L'admin di `SqlDb` espone:
|
||||
|
||||
- export/import CSV;
|
||||
- scansione delle tabelle, creazione delle relazioni e introspezione completa;
|
||||
- validazione FK e inferenza di relazioni candidate;
|
||||
- test della connessione;
|
||||
- duplicazione della configurazione;
|
||||
- generazione commenti AI per tabelle e colonne;
|
||||
- generazione sincrona o asincrona di scope, ERD e documentazione;
|
||||
- report GDPR;
|
||||
- export della struttura e script SQL dei commenti.
|
||||
|
||||
Evidenza: `/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqldb.py:237-274`.
|
||||
|
||||
I campi di configurazione, contenuto e stato sono esposti in fieldset distinti
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqldb.py:275-462`). In ThothII i segreti di
|
||||
connessione non devono essere campi ordinari del catalogo né essere restituiti dalle API di
|
||||
gestione metadati.
|
||||
|
||||
### Tabelle
|
||||
|
||||
L'admin delle tabelle permette export/import CSV, introspezione colonne, validazione e pulizia
|
||||
PK/FK, copia del commento AI nella descrizione, generazione commenti sincrona/asincrona e
|
||||
download dello script SQL (`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqltable.py:133-150`).
|
||||
|
||||
L'azione di applicazione AI opera solo sulle righe selezionate, ignora commenti generati vuoti
|
||||
e sovrascrive direttamente `description`
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqltable.py:165-190`).
|
||||
|
||||
### Colonne
|
||||
|
||||
L'admin delle colonne permette export/import CSV, copia del commento AI nella descrizione,
|
||||
copia bidirezionale fra nome originale e nome espanso, validazione FK e generazione AI sulle
|
||||
colonne selezionate (`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqlcolumn.py:167-196`).
|
||||
|
||||
L'applicazione AI sovrascrive `column_description` soltanto per le colonne selezionate con
|
||||
`generated_comment` valorizzato
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqlcolumn.py:219-245`). Le azioni inverse riguardano
|
||||
esclusivamente i due campi nome
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqlcolumn.py:247-261`).
|
||||
|
||||
### Relazioni
|
||||
|
||||
L'admin delle relazioni offre il CRUD standard, filtri e ricerca, export/import e dichiara
|
||||
un'azione per aggiornare i campi PK/FK
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_relationship.py:219-245`). L'ultima azione è però un
|
||||
difetto: `RelationshipAdmin` non implementa il metodo dichiarato; esiste soltanto il metodo
|
||||
statico sul model. La capacità da conservare è la ricostruzione coerente degli indicatori, non
|
||||
l'azione admin rotta.
|
||||
|
||||
## 3. Introspezione e riconciliazione dello schema
|
||||
|
||||
Il factory del database manager associa i sette motori ai rispettivi adapter e gestisce anche
|
||||
il tunnel SSH (`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:77-227`).
|
||||
|
||||
L'introspezione legacy:
|
||||
|
||||
- riduce i tipi nativi a un insieme generico limitato, con fallback `VARCHAR`
|
||||
(`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:237-266`);
|
||||
- legge e crea le colonne mancanti, ma non aggiorna tipo o commento di quelle già note
|
||||
(`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:269-351`);
|
||||
- crea le tabelle mancanti e aggiorna la descrizione di quelle esistenti
|
||||
(`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:431-481`);
|
||||
- legge le foreign key fisiche, crea al bisogno colonne mancanti e crea relazioni assenti
|
||||
(`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:484-641`);
|
||||
- esegue l'intero processo nell'ordine tabelle → colonne → relazioni
|
||||
(`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:718-891`).
|
||||
|
||||
Il comportamento è additivo: gli oggetti scomparsi dal database sorgente non sono eliminati o
|
||||
marcati come obsoleti. Per ThothII la capacità richiesta è una scansione completa e
|
||||
riconciliabile, con provenienza, data dell'osservazione e stato degli oggetti rimossi o cambiati;
|
||||
non la semantica incompleta del refresh legacy.
|
||||
|
||||
L'inferenza di relazioni candidate combina convenzioni sui nomi, individuazione euristica delle
|
||||
PK e campionamento dei valori, con soglia di corrispondenza del 70%
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqldb.py:605-801`). Deve rimanere una proposta
|
||||
esplicita da convalidare, non essere confusa con una foreign key fisica.
|
||||
|
||||
## 4. Generazione AI delle descrizioni
|
||||
|
||||
### Tabelle
|
||||
|
||||
La generazione procede in batch da dieci, utilizza lingua e contesto del database, schema
|
||||
osservato, descrizioni disponibili e fino a cinque righe di esempio; il risultato JSON aggiorna
|
||||
soltanto `table.generated_comment`
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_table_comments.py:181-267`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_table_comments.py:269-482`).
|
||||
|
||||
### Colonne
|
||||
|
||||
La generazione usa contesto della tabella, nomi delle colonne selezionate ed esempi reali, e
|
||||
scrive soltanto `column.generated_comment`
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_column_comments.py:185-280`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_column_comments.py:283-487`).
|
||||
|
||||
Provider e modello AI provengono dalla configurazione globale del backend; la lingua è invece
|
||||
per database (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/comment_generation_utils.py:156-219`).
|
||||
|
||||
### Comportamento di parità proposto il 2026-08-23
|
||||
|
||||
Il contratto funzionale minimo è esattamente questo:
|
||||
|
||||
- due campi per elemento: descrizione canonica e commento generato;
|
||||
- comando AI su elementi selezionati o su un insieme più ampio esplicitamente scelto;
|
||||
- scrittura/sovrascrittura del solo commento generato;
|
||||
- azione separata, su selezione dell'utente, che copia il generato nel canonico;
|
||||
- nessuna proposta persistente aggiuntiva, diff obbligatorio, approvazione multilivello o
|
||||
versionamento del testo.
|
||||
|
||||
Non è stata trovata una copia `descrizione → commento generato`. Se si desiderasse in futuro,
|
||||
sarebbe una nuova capacità, non parità legacy.
|
||||
|
||||
## 5. Scope, Mermaid e documentazione
|
||||
|
||||
### Scope
|
||||
|
||||
La generazione dello scope raccoglie nomi e descrizioni di tabelle e colonne, nome e lingua del
|
||||
database, richiede JSON al modello e persiste sia il JSON sia una resa Markdown. Se il JSON non
|
||||
è valido conserva il testo grezzo e svuota `scope_json`
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_db_scope.py:25-163`).
|
||||
|
||||
### ERD Mermaid
|
||||
|
||||
L'ERD è prodotto dall'AI usando tabelle, colonne, PK/FK e relazioni. Il codice estrae un blocco
|
||||
Mermaid oppure usa la risposta grezza e la salva in `SqlDb.erd`, senza una validazione
|
||||
sintattica o semantica preventiva
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/generate_db_erd.py:18-145`).
|
||||
|
||||
Il rendering attivo usa un servizio Mermaid locale: health check, POST a `/svg` o `/png`,
|
||||
timeout e file temporanei
|
||||
(`/Thoth/ThothAI/backend/thoth_ai_backend/mermaid_utils.py:29-72`,
|
||||
`/Thoth/ThothAI/backend/thoth_ai_backend/mermaid_utils.py:281-464`). Il servizio Express espone
|
||||
`/health`, `/svg` e `/png` ed applica un limite al body
|
||||
(`/Thoth/ThothAI/docker/mermaid-service/src/server.js:13-23`,
|
||||
`/Thoth/ThothAI/docker/mermaid-service/src/server.js:70-115`). È distribuito come servizio
|
||||
Compose autonomo con health check
|
||||
(`/Thoth/ThothAI/docker-compose.yml:184-201`).
|
||||
|
||||
La vista ERD renderizza il Mermaid memorizzato in SVG tramite tale servizio e poi elimina il
|
||||
file temporaneo (`/Thoth/ThothAI/backend/thoth_ai_backend/views.py:227-288`).
|
||||
|
||||
### Documento del database
|
||||
|
||||
La documentazione HTML combina scope, relazioni, tabelle e colonne. Per le descrizioni usa il
|
||||
campo canonico e, quando vuoto, il commento generato
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/generate_db_documentation.py:35-188`).
|
||||
|
||||
Il processo di generazione chiede all'AI il diagramma Mermaid, lo salva nell'ERD e costruisce
|
||||
deterministicamente l'HTML corrente; l'HTML generato non incorpora il diagramma
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/generate_db_documentation.py:767-922`). La UI espone il
|
||||
documento del database del workspace corrente e le route per HTML/PDF ed ERD/PDF
|
||||
(`/Thoth/ThothAI/backend/thoth_ai_backend/views.py:86-179`,
|
||||
`/Thoth/ThothAI/backend/thoth_ai_backend/urls.py:179-188`).
|
||||
|
||||
Per la parità ThothII servono quindi contenuto documentale strutturato, sorgente Mermaid
|
||||
persistita e rendering locale. La validazione Mermaid prima della pubblicazione è una
|
||||
correzione necessaria, non un cambiamento di scopo.
|
||||
|
||||
## 6. Export e comandi operativi
|
||||
|
||||
Le capacità utili rilevate sono:
|
||||
|
||||
- CSV di tabelle e colonne selezionate
|
||||
(`/Thoth/ThothAI/backend/thoth_core/utilities/utils.py:150-195`);
|
||||
- export CSV generico dei modelli e della struttura completa
|
||||
(`/Thoth/ThothAI/backend/thoth_core/utilities/utils.py:198-261`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/utilities/utils.py:399-569`);
|
||||
- script SQL dei commenti per PostgreSQL, SQL Server, MySQL e MariaDB
|
||||
(`/Thoth/ThothAI/backend/thoth_core/admin_utils/sql_comment_script.py:25-316`);
|
||||
- comandi `generate_scope` e `generate_documentation`, indirizzabili per workspace, database o
|
||||
tutti i database (`/Thoth/ThothAI/backend/thoth_core/management/commands/generate_scope.py:12-89`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/management/commands/generate_documentation.py:12-89`);
|
||||
- export globale e per workspace
|
||||
(`/Thoth/ThothAI/backend/thoth_core/management/commands/export_models.py:19-64`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/management/commands/export_workspace.py:19-96`);
|
||||
- aggiornamento delle descrizioni colonna da CSV per workspace
|
||||
(`/Thoth/ThothAI/backend/thoth_ai_backend/management/commands/update_column_descriptions.py:24-92`).
|
||||
|
||||
I comandi di importazione dalla produzione legacy sono deliberatamente esclusi da questo
|
||||
inventario di parità: costituiscono un progetto CLI `tht` separato, con mapping, validazione e
|
||||
cutover propri.
|
||||
|
||||
## 7. Esecuzioni asincrone e stato
|
||||
|
||||
Scope, ERD, documentazione e commenti possono essere lanciati in background. Il legacy crea
|
||||
thread daemon e memorizza task id, stato e log sui modelli
|
||||
(`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/async_scope.py:21-62`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/async_erd.py:21-30`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/async_documentation.py:21-30`,
|
||||
`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/async_table_comments.py:39-87`).
|
||||
|
||||
La capacità da mantenere è: operazione lunga non bloccante, esclusione di esecuzioni
|
||||
confliggenti, stato osservabile e log. Il meccanismo daemon non è durevole, non permette
|
||||
recovery o cancellazione e non deve essere replicato letteralmente.
|
||||
|
||||
## 8. Difetti e comportamenti da non replicare
|
||||
|
||||
| Area | Evidenza legacy | Decisione di parità |
|
||||
|---|---|---|
|
||||
| Segreti negli export | L'export struttura include `password` in chiaro (`/Thoth/ThothAI/backend/thoth_core/utilities/utils.py:516-559`); l'export generico serializza tutti i campi (`/Thoth/ThothAI/backend/thoth_core/management/commands/export_models.py:19-64`). | Escludere sempre credenziali e segreti. |
|
||||
| SQL euristico | Il campionamento per inferire FK interpola identificatori senza quoting e usa query costruite come stringhe (`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqldb.py:697-750`). | Usare adapter sicuri, quoting per dialetto e query read-only con limiti. |
|
||||
| Refresh incompleto | L'introspezione aggiunge oggetti ma non riconcilia rimozioni e non aggiorna tutte le proprietà (`/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:318-351`, `/Thoth/ThothAI/backend/thoth_core/dbmanagement.py:459-481`). | Scansioni versionate e stato drift/removed. |
|
||||
| Relazioni denormalizzate | L'aggiornamento ricostruisce stringhe PK/FK solo sulle colonne partecipanti e non ripulisce esplicitamente valori obsoleti (`/Thoth/ThothAI/backend/thoth_core/models.py:505-526`). | Derivare indicatori dalle relazioni correnti. |
|
||||
| Azione relazione rotta | L'admin dichiara `update_pk_fk_fields` ma non lo implementa (`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_relationship.py:219-245`). | Esporre un comando applicativo testato. |
|
||||
| CSV colonne incoerente | L'header ha sei colonne, le righe ne emettono otto incluse PK/FK (`/Thoth/ThothAI/backend/thoth_core/utilities/utils.py:165-195`). | Contratto CSV versionato e testato. |
|
||||
| Comando export rotto | `export_single_model` usa l'app label `toth_be` e un attributo non definito (`/Thoth/ThothAI/backend/thoth_core/management/commands/export_single_model.py:19-67`). | Non portare il comando; sostituirlo con export catalogo coerente. |
|
||||
| Batch AI colonne | Un batch usa la prima tabella selezionata come contesto per tutte le colonne (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_column_comments.py:230-268`). | Raggruppare sempre per database e tabella. |
|
||||
| Contesto AI tabelle | Il fallback al commento generato è calcolato ma non incluso nel dataframe finale (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_table_comments.py:485-525`). | Costruire il contesto dal valore effettivamente visibile. |
|
||||
| Duplicazione DB | Duplica configurazione e vector DB, azzerando soltanto una data di aggiornamento (`/Thoth/ThothAI/backend/thoth_core/admin_models/admin_sqldb.py:514-569`). | Se mantenuta, duplicare soltanto metadati esplicitamente scelti, mai segreti o stati. |
|
||||
| Scope non JSON | Il generatore intercetta internamente il JSON non valido, mentre l'azione può comunque mostrare successo (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/create_db_scope.py:92-192`). | Stato `failed` o `needs_review`, senza falso successo. |
|
||||
| Mermaid non validato | La risposta AI viene salvata dopo la sola estrazione del blocco (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/generate_db_erd.py:88-121`). | Validare prima di pubblicare e conservare l'errore di rendering. |
|
||||
| HTML non escapato | I valori descrittivi sono interpolati direttamente nell'HTML (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/generate_db_documentation.py:35-188`). | Escape/sanitizzazione obbligatori. |
|
||||
| Job daemon | I task sono thread in-process (`/Thoth/ThothAI/backend/thoth_core/thoth_ai/thoth_workflow/async_scope.py:21-62`). | Esecuzione durevole o almeno recuperabile, con idempotenza. |
|
||||
| Script MySQL | I commenti colonna usano `ALTER ... MODIFY COLUMN` basandosi sul tipo normalizzato (`/Thoth/ThothAI/backend/thoth_core/admin_utils/sql_comment_script.py:244-316`). | Generare solo con tipo nativo completo oppure bloccare l'export rischioso. |
|
||||
|
||||
Il modulo contiene anche un helper verso `mermaid.ink`, ma non risultano call site nel tree
|
||||
legacy; il percorso attivo è il servizio locale. Non va quindi considerata una dipendenza
|
||||
funzionale da conservare.
|
||||
|
||||
## 9. Baseline di parità proposta il 2026-08-23
|
||||
|
||||
### Necessario
|
||||
|
||||
- database gestiti derivati dalla configurazione dei workspace;
|
||||
- inventario completo del database, anche oltre il sottoinsieme usato dal workflow core;
|
||||
- scansione di tabelle, colonne, chiavi e relazioni fisiche con drift osservabile;
|
||||
- descrizioni canoniche e commenti AI separati per tabelle e colonne;
|
||||
- generazione AI selettiva e copia selettiva AI → descrizione, senza workflow aggiuntivo;
|
||||
- CRUD dei metadati semantici e delle relazioni logiche;
|
||||
- scope strutturato, documento generale strutturato ed ERD Mermaid;
|
||||
- servizio locale per validazione/rendering Mermaid in SVG/PNG/PDF;
|
||||
- test connessione, inferenza/validazione delle relazioni e operazioni lunghe con stato/log;
|
||||
- export CSV sicuro e script SQL commenti solo quando il dialetto può essere ricostruito senza
|
||||
perdita;
|
||||
- API e UI dedicate, separate dal workflow NL→SQL;
|
||||
- pubblicazione esplicita e controllata del sottoinsieme utile al core/Qdrant.
|
||||
|
||||
### Estensione, non requisito di parità iniziale
|
||||
|
||||
- analisi e report GDPR;
|
||||
- importazione dei dati da installazioni ThothAI in produzione, da progettare come iniziativa
|
||||
CLI `tht` separata.
|
||||
|
||||
### Esplicitamente escluso
|
||||
|
||||
- replica del Django Admin o del suo modello di permessi implicito;
|
||||
- modifica manuale della struttura fisica osservata;
|
||||
- memorizzazione o export di password nel catalogo;
|
||||
- dipendenza del workflow SQL dalla disponibilità della nuova UI;
|
||||
- proposal/versioning/diff per i commenti AI;
|
||||
- copia descrizione → commento AI, non presente nelle fonti;
|
||||
- difetti tecnici e comportamenti insicuri elencati sopra.
|
||||
|
||||
## Conclusione
|
||||
|
||||
ThothAI fornisce già il perimetro funzionale di un catalogo metadati, ma lo realizza mescolando
|
||||
configurazione di connessione, inventario fisico, contenuti semantici, job e UI nel modello
|
||||
Django. ThothII può raggiungere la parità separando questi aspetti e mantenendo invariato il
|
||||
workflow SQL: il catalogo gestisce l'intero database, mentre il core continua a consumare
|
||||
soltanto il sottoinsieme dichiarato dal workspace e pubblicato nel proprio indice Qdrant.
|
||||
|
||||
La regola di Q6 è semplice e verificata nelle fonti: generazione nel campo AI, selezione
|
||||
esplicita dell'utente, copia nel campo canonico. Ogni meccanismo ulteriore sarebbe una nuova
|
||||
funzionalità e non è necessario per la parità.
|
||||
@@ -1,206 +0,0 @@
|
||||
# PostgreSQL deployment and failure-isolation constraints for the Metadata Catalog
|
||||
|
||||
Original research: 2026-08-23
|
||||
|
||||
Last verified against the repository: 2026-08-31
|
||||
|
||||
Issue: [#8 — Assess PostgreSQL deployment and failure-isolation constraints](https://git.tylconsulting.it/mptyl/ThothII/issues/8)
|
||||
|
||||
> **Status: partially superseded by ADR-0004.** This is historical research, not the current
|
||||
> architecture contract. The recommendation to run a separate `catalog-api` process was rejected
|
||||
> by [ADR-0004](../adr/0004-fastify-kysely-metadata-catalog.md). Operational constraints that do
|
||||
> not depend on that process boundary remain useful, but the status table below is authoritative
|
||||
> for what the 2026-08-31 code actually adopts, rejects, or leaves pending.
|
||||
|
||||
## Question
|
||||
|
||||
How can a Metadata Catalog PostgreSQL service be deployed, backed up, diagnosed, and made
|
||||
non-blocking for the NL→SQL workflow across local and server installations?
|
||||
|
||||
## Current decision and implementation
|
||||
|
||||
[ADR-0001](../adr/0001-postgres-metadata-catalog.md) selects PostgreSQL as the catalog authority.
|
||||
[ADR-0003](../adr/0003-installation-local-database-bindings.md) keeps database bindings
|
||||
installation-local. [ADR-0004](../adr/0004-fastify-kysely-metadata-catalog.md) then places the
|
||||
catalog in the existing Fastify backend as an isolated Kysely module rather than a microservice.
|
||||
|
||||
The implemented dependency graph is therefore:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
UI[Frontend]
|
||||
Core[Core: Fastify workflow and catalog modules]
|
||||
Pi[Pi and tht workflow]
|
||||
PG[(catalog-db PostgreSQL)]
|
||||
Semantic[Qdrant and embedding]
|
||||
|
||||
UI --> Core
|
||||
Core --> Pi
|
||||
Core --> PG
|
||||
Core --> Semantic
|
||||
```
|
||||
|
||||
The catalog module is isolated behind a repository interface, but it is not process-isolated.
|
||||
`core` owns the catalog pool and Compose waits for `catalog-db` health before starting `core`
|
||||
(`compose.yaml`, `backend/src/app.ts`, `backend/src/catalog/repository.ts`). Database-management records still do
|
||||
not feed the NL→SQL handoff, so a running workflow does not read catalog rows; that cutover remains
|
||||
future work (`PROJECT_STATE.md`).
|
||||
|
||||
## Verification result
|
||||
|
||||
| Area | Status on 2026-08-31 | Evidence and consequence |
|
||||
| --- | --- | --- |
|
||||
| PostgreSQL as canonical catalog store | **Adopted** | ADR-0001 is implemented by the PostgreSQL-backed Kysely repository and the internal `catalog-db` service. |
|
||||
| One Workspace Database per workspace and installation-local bindings | **Adopted** | ADR-0003 and the catalog migrations enforce the model; workspace identity remains in the workspace registry. |
|
||||
| Separate `catalog-api` process | **Superseded/rejected** | ADR-0004 explicitly chooses an isolated module inside the existing Fastify process. There is no catalog microservice or separate catalog liveness endpoint. |
|
||||
| No catalog pool, credential, or Compose dependency in `core` | **Superseded/rejected** | `core` owns the runtime pool, receives the runtime password secret, and declares `depends_on: catalog-db: service_healthy`. The old process-level isolation acceptance criterion is not current architecture. |
|
||||
| Private PostgreSQL service and durable volume | **Adopted** | `catalog-db` uses a version-and-digest-pinned PostgreSQL 17.6 image, the private `thothii` network, no published host port, a `pg_isready`-based healthcheck, and `catalog-data`. Compose contract tests assert this topology (`scripts/test-default-compose.sh`). |
|
||||
| Different local and server database topology | **Superseded/rejected** | Both current profiles inherit the same internal `catalog-db` and named volume. `deploy/compose.server.yaml` does not replace it with an operator-provided endpoint. |
|
||||
| Runtime and migrator role separation | **Adopted** | `core` receives only `thothii_catalog_runtime`; the profile-gated `catalog-migrate` job receives only `thothii_catalog_migrate`. Bootstrap grants runtime DML/sequence privileges without DDL (`docker/catalog-db-init.sql`). |
|
||||
| Dedicated backup role | **Pending** | There is no `catalog_backup` role or backup secret. |
|
||||
| Explicit one-shot migrations | **Adopted** | `backend/src/catalog/migrate.ts` registers ordered Kysely migrations and uses a pool of one. `scripts/run-stack.sh` starts PostgreSQL and runs `catalog-migrate` before local startup; migrations are not hidden in backend startup. |
|
||||
| Checksums, drift/pending refusal, and migration readiness | **Pending** | No repository-owned checksum policy, drift report, or readiness gate exists for catalog migrations. The backend can start without checking the Kysely migration head when launched outside the local helper. |
|
||||
| Bounded runtime connection pool | **Adopted** | `backend/src/catalog/repository.ts` sets `max: 5` and `connectionTimeoutMillis: 3000`, and closes Kysely with the Fastify lifecycle. |
|
||||
| `lock_timeout`, `statement_timeout`, and catalog TLS policy | **Pending** | The runtime pool does not set query or lock timeouts. Catalog connection configuration has no explicit CA/hostname-verification contract; the server profile still uses the private Compose network. |
|
||||
| Process liveness independent of catalog queries | **Adopted** | `GET /health` returns `{status: "ok"}` without probing PostgreSQL, and `backend/test/health.test.ts` preserves that behavior. `/catalog/status` performs the catalog-specific availability check. |
|
||||
| Stack startup independent of catalog availability | **Superseded/rejected** | Compose blocks `core` on healthy `catalog-db`. The host service health fold does not list `catalog-db`, but it cannot make `core` start while its Compose dependency is unhealthy. |
|
||||
| Uniform catalog-outage response (`503` plus `Retry-After`) | **Pending** | Routes map the domain `CatalogUnavailableError` to a sanitized `503`, and an omitted catalog configuration uses an unavailable repository. PostgreSQL driver failures are not uniformly translated to that domain error, and no `Retry-After` contract is implemented. |
|
||||
| Catalog-specific readiness and `tht doctor` checks | **Pending** | There is no `/health/ready` for the catalog and no doctor section for connection, migration head, pool saturation, backup age, or publication lag (`tools/tht/internal/doctor/report.go`). |
|
||||
| Logical catalog backup and restore | **Pending** | Current backup archives omit `catalog-data` and do not run `pg_dump`; server archives include only Qdrant and embedding volumes. A backup can therefore succeed without preserving the Metadata Catalog (`tools/tht/internal/backup/create.go`). |
|
||||
| Last-good Publication and catalog-to-Qdrant cutover | **Pending** | The current database-management slice does not change the NL→SQL runtime or publish catalog metadata to Qdrant. |
|
||||
|
||||
## Current operational contract
|
||||
|
||||
### Deployment and credentials
|
||||
|
||||
- Local and server Compose profiles currently use the same installation-owned `catalog-db`
|
||||
container and `catalog-data` named volume. PostgreSQL is private to the Compose network.
|
||||
- The database bootstrap login is the migrator. The init script creates the separate runtime login
|
||||
from a Docker secret and grants only runtime DML and sequence access.
|
||||
- Runtime and migrator passwords are separate protected host files exposed as separate Docker
|
||||
secrets. Neither value belongs in tracked environment files
|
||||
(`deploy/env/local.env.example`, `deploy/env/server.env.example`).
|
||||
- The Fastify catalog repository uses a five-connection pool with a three-second connection
|
||||
timeout. Fastify closes the repository pool during shutdown.
|
||||
|
||||
### Migrations
|
||||
|
||||
The compiled `catalog-migrate` entry point owns schema changes and uses the migrator credential.
|
||||
The current ordered series is under
|
||||
`backend/src/catalog/migrations/`. The local launcher runs
|
||||
it before the normal stack, while production rollout must invoke the profile-gated service
|
||||
explicitly.
|
||||
|
||||
This is weaker than the original recommendation in two ways: there is no catalog readiness check
|
||||
for pending or unknown migrations, and the repository does not maintain content checksums for
|
||||
migration drift. Until those checks exist, “the migrator completed” is the available deployment
|
||||
gate; the application itself does not prove migration compatibility.
|
||||
|
||||
### Failure behavior actually provided
|
||||
|
||||
| Failure | Current catalog behavior | Current workflow behavior |
|
||||
| --- | --- | --- |
|
||||
| Catalog configuration omitted when launching the backend directly | Fastify uses `UnavailableCatalogRepository`; `/catalog/status` reports unavailable and domain-mapped catalog operations return sanitized `503` | `/health`, sessions, and SSE remain available |
|
||||
| `catalog-db` unhealthy before Compose startup | `core` is not started because its dependency is not healthy | Workflow startup is blocked |
|
||||
| PostgreSQL becomes unavailable after startup | `/health` remains process-only and `/catalog/status` reports unavailable; route errors are sanitized, but a uniform `503`/`Retry-After` mapping is not guaranteed | Existing session code does not read catalog rows, but both surfaces still share one Fastify process |
|
||||
| Migrations are pending or incompatible | No dedicated readiness refusal exists; affected catalog operations fail | No catalog-to-workflow handoff exists yet, but local deployment correctness depends on running `catalog-migrate` first |
|
||||
| Catalog backup is requested through current `tht backup` | No PostgreSQL dump is added and `catalog-data` is omitted | The archive may succeed while being unable to restore catalog state |
|
||||
|
||||
The shared process means resource exhaustion, fatal process errors, and startup hooks remain a
|
||||
common failure domain even though repository calls are separated. Conversely, placing the module
|
||||
inside Fastify does not require workflow code to consume catalog rows: preserving that data-flow
|
||||
boundary is still the useful part of the original isolation recommendation.
|
||||
|
||||
## Historical recommendations that remain valid backlog
|
||||
|
||||
The following constraints survive ADR-0004 because they can be implemented inside the current
|
||||
Fastify deployment:
|
||||
|
||||
1. **Bound every database operation.** Keep the adopted pool and connection timeout; add explicit
|
||||
request query and lock timeouts. Long model calls and source sampling must not hold catalog
|
||||
transactions.
|
||||
2. **Make failures component-specific.** Translate connection, timeout, and pool-exhaustion errors
|
||||
into one sanitized catalog-unavailable response, add bounded retry guidance, and keep `/health`
|
||||
process-only.
|
||||
3. **Make migration compatibility observable.** Report applied, pending, unknown, and drifted
|
||||
migrations through a catalog readiness check and `tht doctor`; do not put migrator credentials
|
||||
in `core`.
|
||||
4. **Define a server TLS topology before externalizing PostgreSQL.** If the server profile moves to
|
||||
an operator-provided endpoint, use a dedicated database and roles, protected CA material, and
|
||||
hostname verification. Sharing a cluster leaves connection, maintenance, WAL, and storage blast
|
||||
radius even when schemas are separate. PostgreSQL documents the relevant connection and TLS
|
||||
parameters in its
|
||||
[connection parameter reference](https://www.postgresql.org/docs/current/libpq-connect.html).
|
||||
5. **Keep derived semantic data non-canonical.** When catalog publication is implemented, activate
|
||||
complete immutable revisions and retain the last successfully activated revision rather than
|
||||
exposing mutable catalog rows to the workflow.
|
||||
|
||||
## Backup and restore target
|
||||
|
||||
The original logical-backup recommendation is still valid and is now a confirmed implementation
|
||||
gap.
|
||||
|
||||
### Backup
|
||||
|
||||
Extend `tht backup create` with a catalog step that runs `pg_dump --format=custom` through a
|
||||
one-shot helper and adds the dump plus checksum to the installation manifest. Do not treat a tar of
|
||||
a live data volume as a PostgreSQL consistency contract. PostgreSQL documents that `pg_dump`
|
||||
creates a consistent export while the database remains in use and that custom format supports
|
||||
selective restore ([`pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html)).
|
||||
|
||||
Use a dedicated least-privilege backup role, never write dumps into a workspace repository, and
|
||||
record at least the server version, migration head, checksum, creation time, and catalog revision
|
||||
identifiers. A filesystem/Qdrant archive with a failed or absent catalog dump must be reported as
|
||||
incomplete.
|
||||
|
||||
### Restore
|
||||
|
||||
Restore only through an explicit maintenance operation into an empty or deliberately cleaned
|
||||
target. Validate the archive checksum, run `pg_restore --exit-on-error --single-transaction`, then
|
||||
verify migration compatibility, referential integrity, bounded entity counts, and an authenticated
|
||||
catalog smoke test. The controls are documented by PostgreSQL
|
||||
([`pg_restore`](https://www.postgresql.org/docs/current/app-pgrestore.html)). Keep the old database
|
||||
until validation passes; rollback should switch the endpoint or retained volume, not dual-write.
|
||||
|
||||
## Diagnostics target
|
||||
|
||||
- Keep the shared `GET /health` endpoint process-only.
|
||||
- Treat `/catalog/status` as the current minimal availability surface; add a bounded catalog
|
||||
readiness check covering connection and migration compatibility before using it as a rollout
|
||||
gate.
|
||||
- Add read-only `tht doctor` checks for secret-file presence and permissions, PostgreSQL
|
||||
reachability, authentication, migration state, pool saturation, and last successful catalog
|
||||
backup. Sanitize all DSNs and errors.
|
||||
- Use `pg_isready` only for server transport readiness. Its result does not prove schema or runtime
|
||||
authorization correctness
|
||||
([`pg_isready`](https://www.postgresql.org/docs/current/app-pg-isready.html)).
|
||||
- Add structured metrics for connection acquisition failures, pool use, query/lock timeout,
|
||||
migration head, background-job backlog, and backup age. Do not log connection strings, source
|
||||
samples, prompts, or generated descriptions at info level.
|
||||
|
||||
## Recommended closure criteria
|
||||
|
||||
1. Decide whether ADR-0004's statement that catalog unavailability does not make sessions or SSE
|
||||
unavailable must also hold at Compose startup. If yes, remove or soften the hard `core` →
|
||||
`catalog-db` startup dependency without reintroducing a microservice.
|
||||
2. Prove a configured PostgreSQL outage produces the same sanitized catalog response across every
|
||||
catalog route while `/health`, session creation, and SSE continue to work.
|
||||
3. Add catalog migration compatibility to readiness and `tht doctor`, including pending, unknown,
|
||||
and drifted states.
|
||||
4. Add a real `pg_dump`/`pg_restore` round-trip to local and server backup tests, and fail backup
|
||||
publication when the catalog dump is absent or fails.
|
||||
5. Before enabling a remote server catalog, define TLS verification, credential files, connection
|
||||
limits, and the accepted cluster-level blast radius.
|
||||
6. Before the NL→SQL cutover, define and test an immutable last-good Publication boundary; do not
|
||||
dual-read mutable PostgreSQL rows and legacy metadata as competing authorities.
|
||||
|
||||
## Decision summary
|
||||
|
||||
PostgreSQL, installation-local bindings, private deployment, role separation, one-shot migrations,
|
||||
bounded pooling, and process-only liveness are implemented. The separate `catalog-api` process and
|
||||
the claim that `core` has no catalog dependency are not current design: ADR-0004 chose the existing
|
||||
Fastify process, and Compose currently blocks `core` startup on `catalog-db` health. Logical
|
||||
backup/restore, catalog migration readiness and drift detection, consistent outage mapping,
|
||||
catalog-specific doctor checks, server TLS/external topology, and last-good publication remain
|
||||
pending. Those open constraints should be treated as backlog, not as capabilities already provided
|
||||
by the repository.
|
||||
@@ -1,301 +0,0 @@
|
||||
# ThothII metadata publication and Qdrant revision seams
|
||||
|
||||
**Research question:** Which existing workspace, snapshot, preprocessing, Qdrant,
|
||||
session-pinning, and runtime read-only contracts constrain metadata publication without changing
|
||||
the NL→SQL workflow?
|
||||
|
||||
**Last verified:** 2026-08-31
|
||||
|
||||
**Validity:** Active architectural research; the catalog-to-core integration described below is
|
||||
still **deferred**, not implemented.
|
||||
|
||||
**Current authorities:** `PROJECT_STATE.md`,
|
||||
[`workspace-evidence-v3.md`](../contracts/workspace-evidence-v3.md),
|
||||
[`workspace-preprocessing-cli.md`](../contracts/workspace-preprocessing-cli.md),
|
||||
[`tht-dwh.md`](../contracts/tht-dwh.md),
|
||||
[`ADR-0001`](../adr/0001-postgres-metadata-catalog.md), and
|
||||
[`ADR-0004`](../adr/0004-fastify-kysely-metadata-catalog.md). These sources and current code
|
||||
override this research note if they diverge.
|
||||
|
||||
## Revalidation against the current implementation
|
||||
|
||||
| Finding | Status on 2026-08-31 | Current evidence and consequence |
|
||||
| --- | --- | --- |
|
||||
| PostgreSQL metadata authority in the existing Fastify backend | **Adopted/current** | ADR-0001 and ADR-0004 are implemented; the catalog is the management-plane authority. |
|
||||
| Git workspace revision, immutable registry snapshot, and revision-pinned runtime | **Adopted/current** | Registry activation and the Workspace Evidence v3 contract still provide the publication boundary for runtime-owned files. |
|
||||
| Qdrant read isolation for schema and Evidence by `workspace_id` + `workspace_revision` | **Adopted/current** | `QdrantVectorStore.search()` applies `_revision_filter()` to schema/Evidence; Memory and solved questions intentionally remain workspace-wide (`harness/tht/adapters/vector/qdrant.py`). |
|
||||
| Physical schema as a file in the Git publication | **Superseded clarification** | `physical.yaml` is owned by the immutable `.tht-dwh` generation selected by `ACTIVE`, not by the Git workspace revision ([DWH contract](../contracts/tht-dwh.md)). Git currently supplies the revision-pinned curated `schema/annotations.yaml`. |
|
||||
| Catalog-to-core publisher | **Open/deferred** | No current route or service projects catalog records into core artifacts. `PROJECT_STATE.md` explicitly defers the schema-linking integration (`PROJECT_STATE.md:160-171`). |
|
||||
| Explicit Core Schema Selection | **Open/deferred** | The workspace descriptor selects one database and one physical schema, but has no table/column allowlist (`backend/src/workspaces/schema.ts`); no catalog selection is handed to `tht`. |
|
||||
| Cross-revision hash lookup used by schema synchronization | **Open defect** | Reads are revision-filtered, but `existing_hashes()` is not. A same-key/same-content point from an older revision can suppress the required upsert into the new revision (`harness/tht/adapters/vector/qdrant.py`, `harness/tht/cli/vector_cmd.py`). |
|
||||
| Deletion/GC | **Current for Evidence; open for schema** | Evidence has generation inventory, retention, compensation, and exact-generation deletion. `sync_canonical_records()` never deletes schema records absent from the new canonical set, and no revision-retention GC exists for schema points. |
|
||||
| Annotation consumption | **Current but incomplete** | M-Schema rendering and schema embeddings consume `Annotations`; `tht schema columns` still returns only physical comments, so F4 does not display annotation descriptions (`harness/tht/cli/schema_cmd.py`, `harness/.pi/extensions/tht-gate.js`). |
|
||||
|
||||
## Conclusion
|
||||
|
||||
The lowest-impact **proposed** publication seam is not a new writer inside the NL→SQL workflow and
|
||||
is not a direct CRUD-to-Qdrant path. The existing core consumes an introspected `PhysicalSchema`
|
||||
from the active immutable DWH generation and a curated, Git-revision-pinned `Annotations`
|
||||
document. A future explicit publication operation should project the approved catalog subset into
|
||||
a new Core Schema Selection contract and the curated annotations, activate a new immutable Git
|
||||
revision, and then invoke the existing `workspace index-schema` preprocessing operation. Qdrant
|
||||
remains a derived, rebuildable projection. None of this catalog-to-core handoff exists yet;
|
||||
`PROJECT_STATE.md:160-164` deliberately defers it to the next design
|
||||
gate.
|
||||
|
||||
The proposed flow would preserve the existing runtime path:
|
||||
|
||||
```text
|
||||
approved catalog data
|
||||
-> explicit Core Schema Selection + curated annotations projection (future)
|
||||
-> workspace Git revision (annotations and selection contract; physical.yaml stays DWH-owned)
|
||||
-> immutable registry snapshot
|
||||
-> revision-bound runtime configuration
|
||||
-> existing tht vector index-schema
|
||||
-> Qdrant records filtered by workspace_id + workspace_revision
|
||||
-> existing retrieval_pack / schema render / F4 review
|
||||
```
|
||||
|
||||
The complete database inventory remains in the Metadata Catalog. Only an explicit Core Schema
|
||||
Selection and approved semantic fields should be projected into the artifacts used by the SQL
|
||||
workflow. ThothII does not currently model or publish that table/column-level selection, so both
|
||||
the projection contract and its operational publisher are new work.
|
||||
|
||||
## 1. Current authority and publication boundary
|
||||
|
||||
The workspace descriptor identifies one PostgreSQL database and one physical schema, plus one
|
||||
workspace-owned Qdrant collection; it has no table or column allowlist
|
||||
(`backend/src/workspaces/schema.ts`).
|
||||
Consequently, a full-database metadata catalog and the subset eligible for the SQL core cannot be
|
||||
represented as the same current descriptor object.
|
||||
|
||||
The existing public contract makes the Git workspace repository curator-owned. Changes occur in a
|
||||
separate authoring clone followed by installation pull, and the API does not write workspace,
|
||||
schema, or Evidence paths
|
||||
([Workspace Evidence v3 contract](../contracts/workspace-evidence-v3.md)).
|
||||
Therefore a browser CRUD service cannot silently make its PostgreSQL state authoritative for the
|
||||
core without either:
|
||||
|
||||
1. exporting/committing a deterministic workspace projection through the existing curator flow;
|
||||
or
|
||||
2. deliberately replacing this Git-authority contract.
|
||||
|
||||
The first option preserves current architecture and session reproducibility.
|
||||
|
||||
Registry activation validates every descriptor at one exact commit, validates and synchronizes
|
||||
the commit's `schema/annotations.yaml`, and rejects duplicate ownership of a Qdrant collection
|
||||
(`backend/src/workspaces/registry.ts`,
|
||||
`backend/src/workspaces/git-repository.ts`,
|
||||
`backend/src/workspaces/annotations-sync.ts`).
|
||||
It writes the candidate snapshot into a staging directory, records file digests in
|
||||
`snapshot.json`, atomically renames the directory, and only then moves active state
|
||||
(`backend/src/workspaces/registry.ts`).
|
||||
That is the existing atomic publication boundary to reuse.
|
||||
|
||||
## 2. Canonical schema inputs already consumed by the core
|
||||
|
||||
The harness separates source facts from curated semantics:
|
||||
|
||||
- `PhysicalSchema` contains database/schema identity and tables; table facts include comments,
|
||||
columns, physical foreign keys, and indexes; columns contain type, nullability, primary-key,
|
||||
default, source comment, examples, and eligibility
|
||||
(`harness/tht/mschema/models.py`).
|
||||
- `Annotations` contains curated table descriptions, concepts and notes, column descriptions,
|
||||
synonyms, concepts, evidence, notes and eligibility overrides, plus logical foreign keys
|
||||
(`harness/tht/mschema/models.py`).
|
||||
|
||||
Rendering already gives annotations precedence over source comments and merges physical and
|
||||
logical foreign keys. It also applies column eligibility before producing M-Schema context
|
||||
(`harness/tht/mschema/render.py`). This makes
|
||||
`Annotations` the natural narrow projection target for approved descriptions, synonyms, logical
|
||||
relationships, and eligibility from the new catalog.
|
||||
|
||||
There are two current compatibility gaps:
|
||||
|
||||
- `schema_records()` embeds table descriptions/concepts and column descriptions/synonyms/examples,
|
||||
but does not include physical or logical foreign keys in vector record content
|
||||
(`harness/tht/vectorstore/records.py`).
|
||||
Relationships still reach the model through deterministic schema rendering, not through schema
|
||||
candidate embeddings.
|
||||
- The F4 widget loads columns with `tht schema columns`
|
||||
(`harness/.pi/extensions/tht-gate.js`), but that
|
||||
command still returns only `PhysicalSchema.comment` values and does not merge
|
||||
`Annotations`
|
||||
(`harness/tht/cli/schema_cmd.py`).
|
||||
A publisher that writes only annotations would improve vector search and rendered M-Schema but
|
||||
not the table/column descriptions displayed by this existing reviewer widget. Fixing the command
|
||||
to use the existing merged description helpers would preserve the workflow shape while closing
|
||||
the inconsistency.
|
||||
|
||||
## 3. Existing preprocessing seam
|
||||
|
||||
`workspace index-schema` is already the supported operator seam. It creates a revision-bound
|
||||
runtime, checks collection compatibility, and runs the harness command
|
||||
`vector index-schema --json`
|
||||
(`backend/src/workspaces/preprocessing-service.ts`,
|
||||
[`workspace-preprocessing-cli.md`](../contracts/workspace-preprocessing-cli.md)).
|
||||
The full preprocessing operation performs DWH preparation, FK suggestion/review, schema indexing,
|
||||
and optional Evidence preprocessing as separate resumable stages
|
||||
(`backend/src/workspaces/preprocessing-service.ts`).
|
||||
Metadata-only publication should normally use the narrow `index-schema` operation after its
|
||||
workspace artifacts are valid, rather than coupling catalog CRUD to the full pipeline.
|
||||
|
||||
The harness indexer reads the active immutable physical schema and revision-specific annotations,
|
||||
constructs schema records, embeds only changed content, and writes them through the configured
|
||||
vector adapter
|
||||
(`harness/tht/cli/vector_cmd.py`). Its
|
||||
machine result carries the physical/annotation artifact digests, workspace revision, collection,
|
||||
and counts
|
||||
(`harness/tht/cli/vector_cmd.py`). This is
|
||||
the right place to retain publication evidence and audit linkage.
|
||||
|
||||
Preprocessing state is already revision- and binding-aware. A resumed job must match operation,
|
||||
workspace revision, descriptor/catalog blobs, runtime config and binding digests or it fails with
|
||||
`preprocessing_resume_mismatch`
|
||||
(`backend/src/workspaces/preprocessing-state.ts`).
|
||||
|
||||
There is an important operational gate: every preprocessing operation calls
|
||||
`assertSessionInventoryCompatible`; a non-finalized, non-archived session pinned to another
|
||||
revision blocks preprocessing
|
||||
(`backend/src/workspaces/preprocessing-service.ts`,
|
||||
`backend/src/workspaces/preprocessing-state.ts`).
|
||||
A catalog publication UX must expose this as a pending/blocking condition rather than report a
|
||||
generic indexing failure.
|
||||
|
||||
## 4. Qdrant identity, payload and collection contracts
|
||||
|
||||
The collection contract is fixed at the descriptor's dimensions/distance and eight keyword payload
|
||||
indexes: `content_hash`, `document_id`, `kind`, `record_key`, `record_kind`,
|
||||
`vector_generation`, `workspace_id`, and `workspace_revision`
|
||||
(`backend/src/workspaces/qdrant-collection.ts`).
|
||||
`self_heal` may create a missing compatible collection or indexes; `require_existing` only validates
|
||||
and refuses an incompatible collection
|
||||
(`backend/src/workspaces/qdrant-collection.ts`).
|
||||
The publication path must use this shared manager instead of inventing collection setup.
|
||||
|
||||
Schema payloads include both the workspace and workspace revision, record identity, semantic kind,
|
||||
content and content hash
|
||||
(`harness/tht/vectorstore/records.py`).
|
||||
Qdrant point IDs for schema and Evidence also include the revision, and upserts use the same
|
||||
revision in the payload
|
||||
(`harness/tht/adapters/vector/qdrant.py`).
|
||||
Reads always filter by `workspace_id`; schema and Evidence reads additionally filter by the bound
|
||||
`workspace_revision`, while memory and solved-question records intentionally remain
|
||||
workspace-wide
|
||||
(`harness/tht/adapters/vector/qdrant.py:125-145`).
|
||||
|
||||
This means an approved semantic change needs a new workspace revision if old sessions must retain
|
||||
their previous view. Directly overwriting points under the same Git revision would mutate the
|
||||
meaning of that supposedly immutable revision; adding an independent catalog-publication version
|
||||
would require changing the current runtime filter contract.
|
||||
|
||||
### Qdrant synchronization defect to resolve before catalog publication
|
||||
|
||||
The current incremental schema synchronizer compares canonical records by content hash and upserts
|
||||
changed records, but it has no deletion step
|
||||
(`harness/tht/cli/vector_cmd.py:77-99`). More
|
||||
importantly, `QdrantVectorStore.existing_hashes()` filters by workspace and record kind but does not
|
||||
apply `_revision_filter()`
|
||||
(`harness/tht/adapters/vector/qdrant.py:266-286`),
|
||||
even though point IDs and reads are revision-scoped. Therefore a same-key/same-content record from
|
||||
an older revision may be classified as unchanged and never written under the new revision. This is
|
||||
an implementation defect/risk inferred directly from the two code paths, and it should be fixed
|
||||
and regression-tested before the catalog relies on `index-schema` for multi-revision publication.
|
||||
|
||||
Deletion/GC must be stated per record family. Evidence cleanup is implemented: the corpus pipeline
|
||||
retains the configured number of published generations, protects active/job-referenced
|
||||
generations, and calls exact-generation deletion for evicted or compensated generations
|
||||
(`harness/tht/evidence/corpus/pipeline.py`,
|
||||
`harness/tht/adapters/vector/qdrant.py:350-390`). Schema cleanup is
|
||||
not implemented: `delete_kinds()` exists as a workspace-scoped adapter primitive, but the schema
|
||||
synchronizer never calls it, it is not revision-scoped, and there is no retention policy for old
|
||||
schema revisions. Publication therefore still needs exact current-revision deletion semantics and
|
||||
separate safe GC for unleased historical schema revisions.
|
||||
|
||||
## 5. Session pinning and why the SQL workflow can remain unchanged
|
||||
|
||||
Normal session creation acquires an immutable registry revision, passes its snapshot path,
|
||||
workspace ID and commit to `tht session new`, and only releases the retention lease after the
|
||||
manifest has been persisted
|
||||
(`backend/src/routes/sessions.ts`). The
|
||||
manifest stores `workspace_id` and `workspace_revision` next to database/schema identity
|
||||
(`harness/tht/session/store.py`). Resume and
|
||||
saved-SQL paths reopen that exact retained snapshot rather than the current installation default
|
||||
(`backend/src/routes/sessions.ts`,
|
||||
`backend/src/routes/sql.ts`).
|
||||
|
||||
The runtime renderer places the same workspace revision in `runtime_identity`, points the harness
|
||||
at the descriptor-owned Qdrant collection, and supplies the internal embedding service
|
||||
(`backend/src/workspaces/runtime-renderer.ts`).
|
||||
The vector adapter is constructed directly from that configuration, including the revision
|
||||
(`harness/tht/adapters/factory.py`).
|
||||
|
||||
At session bootstrap the backend invokes the existing `search pack` command
|
||||
(`backend/src/routes/sessions.ts`). That
|
||||
command queries schema records with the existing schema kinds, ranks tables and persists the
|
||||
candidate list
|
||||
(`harness/tht/cli/search_cmd.py`). The Pi
|
||||
extension reads the persisted retrieval pack through the CLI
|
||||
(`harness/.pi/extensions/tht-gate.js`),
|
||||
and F4 starts from those candidates while loading full table/column context through existing schema
|
||||
commands. Thus catalog publication can improve the inputs without changing phases, gate semantics,
|
||||
or persisted session artifacts.
|
||||
|
||||
## 6. DWH reuse across metadata-only revisions
|
||||
|
||||
DWH preparation uses immutable generations selected by an `ACTIVE` pointer
|
||||
([DWH contract](../contracts/tht-dwh.md)). The effective-configuration
|
||||
identity deliberately excludes `runtime_identity`, so a content-only Git revision does not force a
|
||||
database re-introspection
|
||||
([DWH contract](../contracts/tht-dwh.md)). This is the key enabling property for future metadata
|
||||
publication: a new Git revision can carry updated curated annotations and a future Core Schema
|
||||
Selection contract, reuse the compatible DWH-owned `physical.yaml`, and rebuild only the
|
||||
revision-scoped schema projection. Today only the curated annotations part of that statement exists.
|
||||
|
||||
## 7. Constraints for the Metadata Catalog design
|
||||
|
||||
The following remain proposed requirements for the deferred catalog-to-core design gate; they are
|
||||
not claims about current implementation:
|
||||
|
||||
1. **Separate full inventory from core projection.** PostgreSQL may hold the complete database
|
||||
catalog, drafts and AI-generated text. Only an explicit Core Schema Selection and approved
|
||||
semantic fields are exported to core artifacts/Qdrant.
|
||||
2. **Publish; do not live-link.** CRUD changes are not visible to the SQL workflow until an explicit,
|
||||
audited publication succeeds. A failed projection, Git activation or Qdrant index operation
|
||||
leaves the previous revision active.
|
||||
3. **Use a new Git revision as the publication identity.** This preserves current snapshot,
|
||||
retention, session resume and Qdrant filtering semantics. A separate mutable catalog revision
|
||||
cannot be safely introduced without changing runtime reads.
|
||||
4. **Respect artifact ownership.** Keep introspected physical facts in the immutable DWH generation;
|
||||
project the future Core Schema Selection through an explicit contract and approved semantic
|
||||
edits into `Annotations`. Keep Mermaid and long-form database documentation outside Qdrant
|
||||
unless a separate record kind and retrieval policy is designed.
|
||||
5. **Reuse the operator boundary.** Trigger `workspace index-schema`, observe its schema-versioned
|
||||
result and persist its artifact identities. Do not call Qdrant from browser CRUD handlers.
|
||||
6. **Keep runtime read-only.** The session/Pi process continues to read the pinned snapshot,
|
||||
retrieval pack and Qdrant projection. AI generation and catalog writes belong to the separate
|
||||
management control plane.
|
||||
7. **Surface publication gates.** UI status must distinguish Git activation, incompatible/missing
|
||||
collection, resumable-session revision conflict, embedding failure and completed publication.
|
||||
8. **Repair and test cross-revision schema synchronization first.** Scope `existing_hashes()` to
|
||||
the bound revision, delete records removed from the current revision's canonical schema, and
|
||||
define safe schema-revision GC. Reuse rather than duplicate the already implemented Evidence
|
||||
generation GC.
|
||||
9. **Close the annotation display gap without changing the workflow.** Make `schema columns` read
|
||||
the same merged descriptions used by M-Schema/vector rendering, so the current F4 widget sees
|
||||
the approved catalog text.
|
||||
|
||||
## Proposed decision summary for the Wayfinder map
|
||||
|
||||
- Keep the Metadata Catalog as a separate management subsystem and source of editable metadata.
|
||||
- Keep Qdrant derived and revision-scoped; it is not the catalog database or source of truth.
|
||||
- Publish through immutable workspace revisions plus the existing preprocessing service.
|
||||
- Preserve the current NL→SQL workflow, Pi extension, phase model and session artifacts.
|
||||
- Add a new, explicit Core Schema Selection contract because no table/column selection exists in
|
||||
the current descriptor.
|
||||
- Treat direct same-revision Qdrant writes, implicit CRUD publication, and bypassing the Git
|
||||
snapshot boundary as rejected integration paths.
|
||||
|
||||
This summary remains design input. The authoritative current state is that catalog-to-core
|
||||
integration and Sensitive Data Policy enforcement in schema-linking are deferred in
|
||||
`PROJECT_STATE.md:160-171`.
|
||||
@@ -114,7 +114,7 @@ La review dei join durante una sessione è distinta dalla curatela globale: il r
|
||||
| Retrieval | Le relationship entrano nel render M-Schema ma non nei record vettoriali | Va deciso se e come influenzano selezione tabelle, ranking e descrizioni, oltre al rendering finale |
|
||||
| Drift | Sync fisica è autoritativa; annotazioni sono una revisione separata | Servono semantiche per endpoint rinominati/eliminati, candidate stale, orphan e riapprovazione |
|
||||
|
||||
Le analisi già presenti nel repository trattano l'integrazione catalogo→core, la selezione pubblicabile e la riparazione degli indici come questioni ancora aperte; le loro proposte non sono decisioni implementate (`docs/research/2026-08-23-thothii-metadata-publication-qdrant-seams.md:20-43`; `docs/research/2026-08-23-thothii-metadata-publication-qdrant-seams.md:239-301`). Anche il piano di migrazione rinvia il lifecycle/admin delle relationship logiche (`docs/plans/2026-08-26-metadata-catalog-from-thothai.md:681-691`).
|
||||
Nota storica: questa analisi precede il passaggio PostgreSQL catalog-to-core. Per il contratto implementato usare [architettura corrente](../architecture/overview.md) e ADR 0016; le vecchie ipotesi di pubblicazione non sono istruzioni operative.
|
||||
|
||||
## Direzione confermata nel grill
|
||||
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
# Google Antigravity e Gemini 3.8 Flash: convenienza costo/qualità
|
||||
|
||||
Verifica effettuata il **7 settembre 2026**, privilegiando documentazione e annunci
|
||||
ufficiali Google. Le prove indipendenti su Gemini 3.8 Flash sono ancora limitate perché il
|
||||
modello è stato pubblicato il 2 settembre 2026.
|
||||
|
||||
## Giudizio sintetico
|
||||
|
||||
- **Registrazione gratuita: decisamente conveniente.** Il piano Individual da $0 include
|
||||
Gemini 3.8 Flash, l'ultima versione Flash, oltre alla CLI e alle funzioni principali di
|
||||
Antigravity. È difficile ottenere un rapporto costo/qualità migliore di un accesso gratuito
|
||||
a un modello di questa fascia.
|
||||
- **Google AI Pro da circa $20/mese: probabilmente conveniente per uso regolare**, ma solo dopo
|
||||
aver misurato il consumo sul piano gratuito. Google non pubblica un numero fisso di prompt o
|
||||
token inclusi, quindi non è possibile calcolare un break-even affidabile contro l'API.
|
||||
- **Ultra da $100 o $200: non lo comprerei per il solo Gemini Flash** senza aver già dimostrato
|
||||
di saturare Pro. Il piano da $100 offre 5 volte la quota Pro; quello da $200 ne offre 20 volte.
|
||||
- Per il server dietro CyberArk, Antigravity ha un vantaggio concreto: la CLI ufficiale `agy`
|
||||
funziona direttamente in Linux e prevede esplicitamente un flusso OAuth remoto tramite URL e
|
||||
codice, senza tunnel né port forwarding.
|
||||
|
||||
## Accesso e prezzi
|
||||
|
||||
La [pagina ufficiale dei piani Antigravity](https://www.antigravity.google/docs/plans/) e la
|
||||
[tabella dei modelli](https://www.antigravity.google/docs/models/) indicano che Gemini 3.8 Flash
|
||||
è disponibile su Individual gratuito, AI Plus, AI Pro, AI Ultra ed Enterprise. Il piano gratuito
|
||||
include anche completamenti Tab illimitati e tutte le funzioni del prodotto, inclusa la CLI, ma
|
||||
ha un limite settimanale di base.
|
||||
|
||||
Google AI Pro costa normalmente **$19,99/mese** nella pagina internazionale di
|
||||
[Google One](https://one.google.com/about/plans) e offre quote Antigravity superiori, con rinnovo
|
||||
ogni cinque ore finché non viene raggiunto il limite settimanale. Google AI Ultra è offerto a
|
||||
[$100/mese con quota 5× Pro oppure $200/mese con quota 20× Pro](https://blog.google/products-and-platforms/products/google-one/google-ai-subscriptions/).
|
||||
|
||||
Il problema è la misurabilità: Google dichiara che i limiti dipendono dalla capacità disponibile
|
||||
e dalla quantità di lavoro compiuta dall'agente, possono cambiare e non corrispondono a un numero
|
||||
pubblico fisso di richieste o token. Pro e Ultra possono acquistare crediti per continuare oltre
|
||||
la quota base, con consumo ai prezzi della piattaforma Gemini.
|
||||
|
||||
Usando direttamente la Gemini API, Gemini 3.8 Flash costa fino al 31 dicembre 2026:
|
||||
|
||||
- **$0,75 per milione di token di input**;
|
||||
- **$3,75 per milione di token di output**, inclusi i token di ragionamento;
|
||||
- la metà in modalità Batch o Flex.
|
||||
|
||||
Dal 1º gennaio 2027 questi prezzi raddoppieranno a $1,50/$7,50. Esiste anche un free tier API,
|
||||
con limiti, nel quale input e output sono gratuiti ma i contenuti possono essere usati per
|
||||
migliorare i prodotti Google. Fonte: [pricing ufficiale Gemini API](https://ai.google.dev/gemini-api/docs/pricing).
|
||||
|
||||
## Qualità del modello
|
||||
|
||||
[Gemini 3.8 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash) è GA, offre un
|
||||
contesto da 1.048.576 token, output fino a 65.536 token, livelli di ragionamento low/medium/high e
|
||||
strumenti per code execution, computer use, file search, function calling e search grounding.
|
||||
|
||||
I risultati pubblicati da Google lo collocano molto vicino ai modelli flagship su alcuni test di
|
||||
coding, ma non su tutti:
|
||||
|
||||
| Benchmark | Gemini 3.8 Flash | Claude Opus 5 | GPT-5.6 Sol | Lettura onesta |
|
||||
|---|---:|---:|---:|---|
|
||||
| DeepSWE v1.1 | 73,7% | 74,0% | 72,7% | Prestazione quasi flagship sul software engineering end-to-end |
|
||||
| Terminal-Bench 2.1 | 89,4% | 89,1% | 88,8% | Eccellente nel terminale sul benchmark più maturo |
|
||||
| Terminal-Bench 4.0 | 19,1% | 51,8% | 37,3% | Forte calo sul test nuovo e più difficile: non è universalmente al livello dei flagship |
|
||||
|
||||
La [metodologia ufficiale Google](https://deepmind.google/models/evals-methodology/gemini-3-8-flash/)
|
||||
precisa che diversi punteggi Gemini sono calcolati internamente e che i concorrenti provengono
|
||||
anche da risultati auto-dichiarati; inoltre DeepSWE usa mini-swe, mentre Terminal-Bench usa un
|
||||
harness diverso. I numeri vanno quindi letti come indicazione, non come garanzia. Una
|
||||
[ricostruzione della tabella e dei confronti](https://www.vellum.ai/blog/gemini-3-8-flash-benchmarks-explained)
|
||||
mostra lo stesso andamento: molto competitivo sui compiti di coding già ben rappresentati, più
|
||||
debole su alcune prove nuove e aperte.
|
||||
|
||||
La conclusione qualitativa è: **ottimo implementatore quotidiano e subagente veloce**, con qualità
|
||||
da modello molto più costoso in diversi task; per architettura difficile, debugging ambiguo o
|
||||
lavori ad alto rischio è ancora sensato affiancargli un modello più forte come pianificatore o
|
||||
revisore.
|
||||
|
||||
## Perché Antigravity è particolarmente adatto al server
|
||||
|
||||
La [CLI ufficiale Antigravity](https://antigravity.google/docs/cli/overview/) è una TUI interattiva
|
||||
con editing multi-file, cronologia, tool calling, sandbox e subagenti. La
|
||||
[guida d'installazione e autenticazione](https://antigravity.google/docs/cli/install/) conferma:
|
||||
|
||||
- esecuzione nativa su Linux, macOS e Windows;
|
||||
- binario `agy` installato in `~/.local/bin` su Linux/macOS;
|
||||
- quando rileva SSH, stampa un URL da aprire sul Mac e richiede di incollare nel terminale il
|
||||
codice ottenuto;
|
||||
- nessuna porta in ascolto e nessun port forwarding sono necessari per questo login.
|
||||
|
||||
Questo risolve meglio di ZCode il vincolo CyberArk, purché il server possa effettuare connessioni
|
||||
HTTPS in uscita e sia consentita l'installazione del binario.
|
||||
|
||||
Per consumare la quota della registrazione Antigravity bisogna usare il client ufficiale. I
|
||||
[termini Antigravity](https://antigravity.google/terms) vietano di riutilizzare il login/OAuth con
|
||||
Pi, OMP, Claude Code, OpenCode o altri client. Con questi harness si può invece usare una normale
|
||||
chiave Gemini API, pagando o consumando la quota API separata.
|
||||
|
||||
## Privacy e codice aziendale
|
||||
|
||||
Con un account personale Google registra le interazioni e può usarle per valutare e migliorare
|
||||
prodotti e modelli; l'utente può disattivare l'uso dalle impostazioni. I termini Enterprise sono
|
||||
diversi e la documentazione dichiara che codice, prompt e trascrizioni delle organizzazioni non
|
||||
sono usati per addestrare i modelli Google. Fonti:
|
||||
[termini Antigravity](https://antigravity.google/terms) e
|
||||
[integrazioni Enterprise](https://antigravity.google/docs/ide/extensions/).
|
||||
|
||||
Su un server aziendale protetto da CyberArk userei quindi una registrazione personale solo dopo
|
||||
aver verificato la policy interna; in caso contrario sceglierei l'accesso Antigravity Enterprise
|
||||
tramite il progetto Google Cloud dell'organizzazione.
|
||||
|
||||
## Raccomandazione finale
|
||||
|
||||
1. Creare l'account gratuito e usare `agy` sul server per una settimana con task reali.
|
||||
2. Tenere disabilitato l'uso automatico dei crediti extra e osservare i due indicatori di quota.
|
||||
3. Passare a Pro soltanto se il limite gratuito interferisce con il lavoro.
|
||||
4. Non acquistare Ultra finché Pro non viene saturato con regolarità.
|
||||
5. Usare Gemini 3.8 Flash come modello principale per esplorazione, implementazione e test; per le
|
||||
decisioni più difficili, mantenere Codex/Sol/Opus o un altro modello forte come revisore.
|
||||
|
||||
In breve: **sì, oggi Antigravity gratuito o Pro offre uno dei migliori rapporti costo/qualità per
|
||||
Gemini 3.8 Flash**, e nel caso specifico la CLI ufficiale senza tunnel aumenta ulteriormente il
|
||||
valore. Il limite commerciale da accettare è la quota non numerica e modificabile da Google.
|
||||
@@ -1,154 +0,0 @@
|
||||
# DeepSeek Harness su un server raggiunto tramite CyberArk
|
||||
|
||||
Data della verifica: 7 settembre 2026.
|
||||
|
||||
## Risposta breve
|
||||
|
||||
Sì. Il progetto che ha attirato molta attenzione è **DeepSeek Harness**, comando
|
||||
`dsh`, pubblicato da DeepSeek nel repository ufficiale
|
||||
[`deepseek-ai/deepseek-harness`](https://github.com/deepseek-ai/deepseek-harness).
|
||||
Può lavorare direttamente sul server senza SSH port forwarding usando il profilo
|
||||
ufficiale **headless**:
|
||||
|
||||
```sh
|
||||
export DEEPSEEK_API_KEY='...'
|
||||
npx @deepseek-ai/dsh --profile headless \
|
||||
"Esamina questo repository e correggi i test che falliscono"
|
||||
```
|
||||
|
||||
Questo profilo esegue un incarico, stampa la risposta e termina. Non avvia GUI,
|
||||
browser o server HTTP e, soprattutto, **non apre alcuna porta**. Lo documentano sia
|
||||
il [README del profilo headless](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/headless/README.md)
|
||||
sia il [riferimento della CLI](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/reference/README.md).
|
||||
Pertanto il port forwarding non serve: basta la shell che CyberArk già consente e
|
||||
connettività HTTPS in uscita.
|
||||
|
||||
La limitazione importante è che non si tratta, per ora, di un'interfaccia terminale
|
||||
interattiva come Pi, OMP, Claude Code o Codex: il profilo ufficiale headless accetta
|
||||
**un solo task per invocazione e non permette follow-up interattivi**.
|
||||
|
||||
## Che cos'è, e cosa non è
|
||||
|
||||
DeepSeek lo presenta come un harness open source in *developer preview*, basato su
|
||||
un'architettura in cui modelli, strumenti, skill, sessioni, sandbox, storage,
|
||||
subagenti e UI sono plugin componibili. La pagina ufficiale descrive inoltre
|
||||
modalità Standard, Code, Minimal e Creator e la registrazione append-only delle
|
||||
esecuzioni. Non è semplicemente il modello DeepSeek e non è uno dei numerosi wrapper
|
||||
creati dalla comunità. Fonti: [pagina ufficiale DeepSeek Harness](https://www.deepseek.com/harness/en/)
|
||||
e [README ufficiale](https://github.com/deepseek-ai/deepseek-harness#readme).
|
||||
|
||||
L'identità del pacchetto è verificabile anche nel
|
||||
[`package.json` della CLI](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/package.json):
|
||||
il pacchetto pubblico è `@deepseek-ai/dsh` e installa l'eseguibile `dsh`.
|
||||
Il [record ufficiale del repository](https://api.github.com/repos/deepseek-ai/deepseek-harness)
|
||||
ne data la creazione al 13 agosto 2026; alla data di questa verifica la release
|
||||
più recente è la prerelease
|
||||
[`dsh-v0.1.3-alpha.2`](https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.3-alpha.2),
|
||||
pubblicata il 7 settembre 2026. Questo conferma quanto il progetto sia giovane e
|
||||
rafforza l'avvertenza sulla stabilità delle interfacce.
|
||||
|
||||
## Le tre modalità rilevanti nel tuo scenario
|
||||
|
||||
| Modalità | Porta/tunnel | Interazione | Utilità con CyberArk |
|
||||
|---|---:|---|---|
|
||||
| `dsh --profile headless "task"` | Nessuna | One-shot, non interattiva | **Sì, è la soluzione semplice** |
|
||||
| `dsh web` | HTTP locale su `127.0.0.1:3080` | Web interattiva | No dal Mac senza forwarding, reverse proxy autorizzato o browser sul server |
|
||||
| `dsh --profile acp` | Nessuna porta; JSON-RPC su stdin/stdout | Persistente, pilotata da un client ACP | Possibile, ma l'integrazione attraverso CyberArk va provata |
|
||||
|
||||
La Web UI ufficiale ascolta per default su `127.0.0.1:3080`; il README afferma
|
||||
esplicitamente che, durante un lancio SSH, il forwarding è responsabilità del client
|
||||
SSH o dell'editor. È quindi inadatta al vincolo descritto, a meno di cambiare
|
||||
l'architettura di accesso con l'approvazione dell'amministrazione
|
||||
([README ufficiale](https://github.com/deepseek-ai/deepseek-harness#run)).
|
||||
|
||||
Il profilo ACP ufficiale è invece un server di automazione persistente su
|
||||
**JSON-RPC stdio**, senza UI. Un client ACP avvia `dsh --profile acp`, crea una
|
||||
sessione indicando una directory di lavoro assoluta e scambia richieste e risposte
|
||||
su standard input/output
|
||||
([README ACP ufficiale](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/acp-app/README.md)).
|
||||
|
||||
Da ciò segue una possibilità tecnica: un client locale potrebbe usare come comando
|
||||
qualcosa di equivalente a `ssh <server> dsh --profile acp`, trasportando lo stdio
|
||||
senza alcun port forwarding. Questa è però un'**inferenza architetturale**, non una
|
||||
configurazione dichiarata compatibile con CyberArk da DeepSeek. Banner di login,
|
||||
MFA interattivo, testo aggiunto su stdout, divieto di `ssh host command`, timeout o
|
||||
riscrittura dei flussi da parte del proxy CyberArk possono corrompere JSON-RPC o
|
||||
impedire del tutto l'avvio. Se CyberArk offre soltanto una console web/interattiva,
|
||||
ACP non collega automaticamente Zed sul Mac al processo remoto.
|
||||
|
||||
## Requisiti di rete e di sistema
|
||||
|
||||
- Il repository richiede Node.js `^22.19.0` oppure `>=24.0.0`, come specificato
|
||||
nel [`package.json` ufficiale](https://github.com/deepseek-ai/deepseek-harness/blob/master/package.json).
|
||||
- Il primo `npx` deve poter scaricare `@deepseek-ai/dsh` dal registry npm. In un
|
||||
ambiente bloccato occorre un mirror aziendale o un'installazione preventiva
|
||||
autorizzata.
|
||||
- Per usare il provider predefinito occorrono `DEEPSEEK_API_KEY` e traffico HTTPS
|
||||
in uscita verso `https://api.deepseek.com`. `DEEPSEEK_BASE_URL` può sostituire
|
||||
l'endpoint, per esempio con un proxy OpenAI-compatible
|
||||
([adapter DeepSeek ufficiale](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-deepseek/README.md)).
|
||||
- Se la rete aziendale impone un proxy HTTP, il riferimento della CLI indica
|
||||
`NODE_USE_ENV_PROXY=1` affinché una versione Node compatibile rispetti
|
||||
`HTTP_PROXY` e `HTTPS_PROXY`
|
||||
([riferimento della CLI, sezione Source execution](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/reference/README.md#source-execution)).
|
||||
- Le operazioni richieste dall'agente possono necessitare altri host in uscita
|
||||
(`git`, registry dei pacchetti, documentazione). Non sono necessari per il
|
||||
trasporto DSH in sé, ma possono esserlo per il task affidato.
|
||||
|
||||
In altre parole, serve **HTTPS outbound**, non una connessione in ingresso verso il
|
||||
server e non un tunnel dal Mac.
|
||||
|
||||
## Limiti pratici specifici di CyberArk
|
||||
|
||||
1. **Accesso alla shell:** se CyberArk consente di aprire una normale sessione shell
|
||||
e di eseguire Node, `headless` funziona concettualmente come qualunque altro
|
||||
comando. Se applica allowlist ai binari, servirà l'autorizzazione per `node`,
|
||||
`npx`/`dsh` e per gli strumenti che l'agente vuole eseguire.
|
||||
2. **Egress:** firewall e proxy devono consentire almeno l'endpoint del modello;
|
||||
CyberArk non sostituisce questa autorizzazione di rete.
|
||||
3. **Durata della sessione:** un timeout o la chiusura della sessione privilegiata
|
||||
può terminare il task. `headless` non lascia un demone dietro di sé, ma incarichi
|
||||
lunghi vanno confrontati con i limiti della sessione CyberArk.
|
||||
4. **Credenziali e registrazione:** evitare di digitare o stampare la chiave API in
|
||||
una sessione registrata. Conviene usare il meccanismo aziendale approvato per
|
||||
iniettare il secret e verificare cosa CyberArk registra.
|
||||
5. **Approvals:** l'headless ufficiale non ha un interlocutore umano integrato. Le
|
||||
richieste di escalation senza un *answerer* vengono negate in modo fail-closed;
|
||||
le normali scritture consentite nella workspace restano possibili
|
||||
([contratto delle approvazioni](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-approval/README.md)).
|
||||
6. **Sicurezza:** DeepSeek dichiara il progetto non sottoposto a security audit e
|
||||
non pronto per produzione. Può eseguire codice generato dal modello e accedere
|
||||
a file, processi, rete e credenziali disponibili al processo. Il progetto stesso
|
||||
raccomanda privilegi minimi e un ambiente dedicato o usa-e-getta
|
||||
([Safety notice ufficiale](https://github.com/deepseek-ai/deepseek-harness/blob/master/SAFETY.md)).
|
||||
|
||||
Un dettaglio importante in un server aziendale: la sandbox corrente descritta da
|
||||
DeepSeek governa gli effetti sul filesystem, mentre rete e visibilità dei processi
|
||||
sono fuori dal suo vocabolario di enforcement. Non considerarla quindi un sostituto
|
||||
di firewall, container, account dedicato e policy CyberArk
|
||||
([documentazione sandbox ufficiale](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/sandbox.md)).
|
||||
|
||||
## TUI interattiva: stato reale
|
||||
|
||||
Il prodotto ufficiale offre oggi Web UI, headless one-shot e interfacce di
|
||||
automazione SDK/ACP. Una TUI a schermo intero chiamata `dsh-tui` è stata presentata
|
||||
nell'area community del repository, ma il pacchetto e il repository appartengono a
|
||||
terzi, non a DeepSeek
|
||||
([discussione nella community DSH](https://github.com/deepseek-ai/deepseek-harness/discussions/3715)).
|
||||
Non va confusa con la CLI ufficiale e, dato che DSH avverte di possibili cambiamenti
|
||||
incompatibili durante la developer preview, non la considererei la prima scelta su
|
||||
un server aziendale protetto.
|
||||
|
||||
## Giudizio
|
||||
|
||||
Per il tuo vincolo concreto la risposta è **sì, ma in modalità one-shot**:
|
||||
`dsh --profile headless` è utilizzabile dalla normale shell CyberArk, non apre porte
|
||||
e non richiede tunnel. È una soluzione tecnicamente più adatta della Web UI, ma
|
||||
meno comoda di Pi/OMP o Codex CLI per un dialogo iterativo.
|
||||
|
||||
La proverei inizialmente su una copia non sensibile del repository, con
|
||||
`workspace-write`, egress ristretto e secret iniettato secondo le regole aziendali.
|
||||
Se vuoi un'esperienza persistente dal Mac, ACP su stdio merita un piccolo test di
|
||||
compatibilità con il gateway CyberArk; non lo darei per funzionante finché non si
|
||||
verifica che il gateway permetta un comando remoto non interattivo e mantenga
|
||||
stdin/stdout completamente puliti.
|
||||
@@ -1,127 +0,0 @@
|
||||
# OMP con GPT-5.6 Sol, Codex ufficiale e ZCode CLI
|
||||
|
||||
_Verifica effettuata il 7 settembre 2026 su documentazione e codice/fonti primarie correnti._
|
||||
|
||||
## Risposta breve
|
||||
|
||||
Se l'obiettivo è usare **GPT-5.6 Sol attraverso la quota inclusa nel piano ChatGPT/Codex**, la
|
||||
scelta consigliata è **Codex ufficiale**: CLI per il lavoro da terminale, app desktop per più task,
|
||||
worktree e revisione visuale. OMP è un harness molto capace e può essere preferibile per ACP/Zed,
|
||||
multi-provider, LSP/DAP e orchestrazione dei subagenti, ma il suo accesso “OpenAI Codex OAuth” non
|
||||
è una superficie che OpenAI documenta ufficialmente come client supportato.
|
||||
|
||||
Se invece OMP usa una **chiave API OpenAI**, l'integrazione è tecnicamente normale e GPT-5.6 Sol è
|
||||
disponibile tramite Responses API con function calling, structured outputs e diversi tool. In quel
|
||||
caso, però, il consumo è fatturato come API e non attinge alla quota inclusa nel piano ChatGPT.
|
||||
|
||||
Per **ZCode di Z.ai**, la documentazione ufficiale corrente presenta un'app desktop/ADE, non una
|
||||
CLI pubblica autonoma. Esiste `zcode-app-cli`, ma è un progetto comunitario che si dichiara non
|
||||
ufficiale ed estrae il runtime distribuito con l'app. Non esiste una garanzia ufficiale che riceva
|
||||
un presunto bonus di quota del 50%; la documentazione corrente non promette neppure un diritto
|
||||
fisso “150%” per tutti gli utenti ZCode.
|
||||
|
||||
## 1. OMP + GPT-5.6 Sol oppure Codex?
|
||||
|
||||
### Il modello è solo una parte del risultato
|
||||
|
||||
Usare lo stesso modello non rende equivalenti due agenti. L'harness decide prompt di sistema,
|
||||
selezione e schema dei tool, raccolta del contesto, compaction, gestione degli errori, permessi,
|
||||
parallelismo e verifica. Non risultano benchmark first-party che confrontino direttamente
|
||||
GPT-5.6 Sol dentro OMP contro lo stesso modello dentro Codex: un vincitore assoluto non è quindi
|
||||
dimostrabile.
|
||||
|
||||
GPT-5.6 Sol è il modello flagship general-purpose della famiglia 5.6 e supporta Responses API,
|
||||
function calling, structured outputs, hosted shell, apply patch, skills, MCP e tool search.
|
||||
[Scheda ufficiale GPT-5.6 Sol](https://developers.openai.com/api/docs/models/gpt-5.6-sol).
|
||||
|
||||
### Accesso tramite abbonamento
|
||||
|
||||
OMP dichiara un provider **OpenAI Codex OAuth** e consente il login dal proprio harness.
|
||||
[README OMP](https://github.com/can1357/oh-my-pi/blob/daf07999c2fee9b22edc7bf8fea1fb6272e0df5e/README.md).
|
||||
|
||||
La documentazione OpenAI, però, indica il login ChatGPT per l'accesso in abbonamento soltanto per
|
||||
l'app desktop ChatGPT/Codex, Codex CLI e l'estensione IDE. Non include OMP tra i client supportati.
|
||||
Questo non prova che OMP non funzioni, ma significa che compatibilità, continuità dell'accesso e
|
||||
interpretazione della quota non sono garantite da OpenAI per quel percorso.
|
||||
[Autenticazione ufficiale Codex](https://learn.chatgpt.com/docs/auth).
|
||||
|
||||
Con una chiave API la situazione è diversa: l'accesso al modello è ufficiale, ma è fatturato ai
|
||||
prezzi API. OpenAI specifica inoltre che l'autenticazione API usa il pricing API invece dei crediti
|
||||
inclusi nel piano ChatGPT.
|
||||
[Pricing Codex](https://learn.chatgpt.com/docs/pricing),
|
||||
[pricing del modello](https://developers.openai.com/api/docs/models/gpt-5.6-sol).
|
||||
|
||||
### Confronto operativo
|
||||
|
||||
| Priorità | Scelta migliore | Motivo |
|
||||
|---|---|---|
|
||||
| GPT-5.6 Sol con quota ChatGPT e supporto prevedibile | Codex ufficiale | Login, quota e aggiornamenti sono first-party |
|
||||
| Esperienza terminale, scripting e CI | Codex CLI | Loop locale, `codex exec`, review e handoff cloud |
|
||||
| Task paralleli, worktree e review visuale | App desktop Codex | Gestione visuale dei task e isolamento mediante Git worktree |
|
||||
| ACP/Zed, molti provider, LSP/DAP e Agent Hub | OMP | Harness più estensibile e ricco di strumenti |
|
||||
| OMP con stabilità contrattuale dell'accesso | OMP + API key | API ufficiale, ma costo separato dal piano ChatGPT |
|
||||
|
||||
La CLI ufficiale è consigliata per terminale, automazione e CI.
|
||||
[Codex CLI](https://learn.chatgpt.com/docs/codex/cli). L'app desktop è più comoda per task
|
||||
concorrenti isolati, diff visuali e passaggio fra checkout locale e worktree.
|
||||
[Worktree Codex](https://learn.chatgpt.com/docs/environments/git-worktrees).
|
||||
|
||||
CLI e app non danno due quote separate: quando si accede con ChatGPT, fanno parte dello stesso
|
||||
ecosistema Codex/ChatGPT e consumano la stessa quota del piano. Il consumo concreto dipende da
|
||||
modello, lunghezza del contesto e complessità del task.
|
||||
[Pricing e limiti](https://learn.chatgpt.com/docs/pricing).
|
||||
|
||||
### Giudizio
|
||||
|
||||
Per un flusso principale basato su GPT-5.6 Sol sceglierei **Codex CLI**; affiancherei l'app quando
|
||||
servono task paralleli, worktree e review visuale. Sceglierei OMP come harness principale soltanto
|
||||
se le sue capacità specifiche — soprattutto Zed/ACP, routing multi-provider o Agent Hub — valgono
|
||||
più del supporto first-party. Se OMP deve essere affidabile nel tempo, userei una API key anziché
|
||||
fondare il workflow sul login OAuth non documentato da OpenAI per client terzi.
|
||||
|
||||
## 2. Il “150%” di Codex non è quota aggiuntiva
|
||||
|
||||
Nella documentazione OpenAI, **1,5× indica la velocità del Fast mode**, non un aumento della quota.
|
||||
Con GPT-5.6, Fast mode consuma crediti a **2,5×** il tasso Standard. È disponibile nei client
|
||||
Codex ufficiali quando si accede con ChatGPT.
|
||||
[Fast mode](https://learn.chatgpt.com/docs/agent-configuration/speed).
|
||||
|
||||
## 3. Esiste una CLI ufficiale ZCode?
|
||||
|
||||
La guida ufficiale ZCode offre download desktop per macOS, Windows e Linux e descrive ZCode come
|
||||
ADE con terminale integrato. Non documenta un comando autonomo ufficiale equivalente a `codex`.
|
||||
La presenza di directory chiamate `~/.zcode/cli/` riguarda il runtime/config interno e non equivale
|
||||
alla pubblicazione di una CLI supportata.
|
||||
[Installazione ZCode](https://zcode.z.ai/en/docs/install),
|
||||
[FAQ ufficiale](https://zcode.z.ai/en/docs/qa).
|
||||
|
||||
Esiste il progetto comunitario
|
||||
[`zcode-app-cli`](https://github.com/kingsword09/zcode-cli), installabile con npm. Il progetto si
|
||||
definisce esplicitamente non affiliato né approvato da Z.ai e dichiara di estrarre il runtime
|
||||
dall'app desktop. Va quindi considerato non ufficiale e soggetto a possibili rotture e problemi di
|
||||
compatibilità o licenza.
|
||||
|
||||
### Ha il 150% della quota?
|
||||
|
||||
Non c'è una conferma ufficiale corrente. Le pagine ZCode attuali descrivono quote Coding Plan su
|
||||
finestre di cinque ore e settimanali, quota MCP mensile, crediti e reset card promozionali/dinamiche;
|
||||
non dichiarano un moltiplicatore fisso 150% applicabile alla CLI.
|
||||
[Statistiche e quota ZCode](https://zcode.z.ai/en/docs/usage-stats),
|
||||
[connessione al Coding Plan](https://zcode.z.ai/en/docs/configuration).
|
||||
|
||||
Alcuni benefici sono esplicitamente legati all'app e al login ZCode: per esempio le reset card
|
||||
richiedono di essere connessi a ZCode, mentre gli idle-time task gratuiti sono una funzione
|
||||
dell'app in rollout. Questo non autorizza a concludere che un client comunitario riceva gli stessi
|
||||
benefici.
|
||||
[ZCode Usage Stats](https://zcode.z.ai/en/docs/usage-stats),
|
||||
[ZCode overview](https://zcode.z.ai/en/docs/welcome).
|
||||
|
||||
Inoltre, i termini del GLM Coding Plan avvertono che l'uso tramite strumenti non autorizzati o non
|
||||
supportati può comportare restrizioni di alcuni benefici. Di conseguenza non userei una CLI
|
||||
comunitaria con l'obiettivo specifico di ottenere quota extra.
|
||||
[Termini del GLM Coding Plan](https://docs.z.ai/legal-agreement/subscription-terms).
|
||||
|
||||
La scelta prudente è usare l'app ZCode ufficiale — incluso il suo terminale integrato o Remote
|
||||
Development — e considerare valido soltanto il saldo mostrato in tempo reale nell'app. Se Z.ai
|
||||
pubblicherà una CLI ufficiale o una regola “+50%”, servirà una dichiarazione esplicita applicabile
|
||||
alla versione e al piano usati.
|
||||
@@ -1,148 +0,0 @@
|
||||
# Pi + `pi-config` di Amos vs Oh My Pi
|
||||
|
||||
_Ricerca aggiornata al 7 settembre 2026. Fonti: esclusivamente repository, documentazione, sorgenti, issue tracker e release ufficiali dei progetti._
|
||||
|
||||
## Risposta breve
|
||||
|
||||
**Per la maggior parte degli sviluppatori che vuole un agente completo e pronto all'uso, sceglierei Oh My Pi (OMP), ma non con le impostazioni di sicurezza predefinite.** OMP integra provider, routing per ruolo, LSP/DAP, subagent, web, browser, sessioni, memoria, marketplace e una UX terminale molto più ampia. È un prodotto coerente, installabile e aggiornabile come tale.
|
||||
|
||||
**Sceglierei invece Pi con pezzi selezionati di `pi-config` se volessi un nucleo piccolo, leggibile e fortemente personalizzabile**, accettando di assemblare, verificare e mantenere personalmente ogni componente. Il vantaggio non è avere più funzioni: è sapere con precisione quali funzioni si stanno aggiungendo.
|
||||
|
||||
La prima distinzione è fondamentale:
|
||||
|
||||
- [`amosblomqvist/pi-config`](https://github.com/amosblomqvist/pi-config) **non è una distribuzione alternativa di Pi**. È la configurazione personale di Amos Blomqvist: una raccolta di estensioni e skill da copiare selettivamente sopra il [Pi ufficiale](https://github.com/earendil-works/pi). Il README invita esplicitamente a non installarla come un unico pacchetto e a non clonarla sopra la propria configurazione.
|
||||
- Per “Oh My Pi” qui si intende [`can1357/oh-my-pi`](https://github.com/can1357/oh-my-pi), il fork integrato di Pi che si presenta come agente “batteries included”. Non è un semplice tema o dotfile pack.
|
||||
|
||||
Di conseguenza il confronto corretto è **Pi ufficiale + componenti scelti da `pi-config` e dai repository companion** contro **OMP come fork/prodotto integrato**.
|
||||
|
||||
## Confronto spalla a spalla
|
||||
|
||||
| Area | Pi + `pi-config` | Oh My Pi | Valutazione |
|
||||
|---|---|---|---|
|
||||
| Installazione | Prima si installa [Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md), poi si copiano singole estensioni/skill in `~/.pi/agent/`; alcuni componenti richiedono `npm install`, Chromium, Python o tool di sistema. Il [README di `pi-config`](https://github.com/amosblomqvist/pi-config#installation) raccomanda la selezione manuale. | Installer shell/PowerShell, Homebrew, Bun, Nix e `mise`, più binari multipiattaforma nelle [release](https://github.com/can1357/oh-my-pi/releases). | **OMP**: onboarding e aggiornamento più coerenti. |
|
||||
| Filosofia | Pi è un harness terminale minimale, esteso tramite TypeScript, skill, prompt template, temi e pacchetti; evita intenzionalmente alcune funzionalità integrate, inclusi subagent e plan mode, per lasciarle alle estensioni ([README Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md)). `pi-config` porta questa filosofia all'estremo: si prendono solo i pezzi voluti. | Fork “batteries included”: molte capacità sono native o integrate e configurabili da una superficie comune ([README OMP](https://github.com/can1357/oh-my-pi)). | **Dipende**: controllo e semplicità a Pi; completezza a OMP. |
|
||||
| Provider e modelli | `pi-config` non aggiunge provider. Eredita da Pi login per Anthropic/OpenAI/Copilot, numerosi provider API, servizi cloud, OpenRouter e modelli locali/custom ([provider Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md#providers-and-models)). | Dichiara oltre 60 provider e modelli locali/remoti; assegna modelli distinti ai ruoli `default`, `smol`, `slow`, `plan`, `commit`, `vision`, `task`, `advisor` e `tiny`, con fallback e credenziali multiple ([model routing OMP](https://github.com/can1357/oh-my-pi#sixty-plus-providers-a-thousand-models-one-model-away)). | **OMP** per ampiezza e routing; Pi resta già provider-agnostic. |
|
||||
| Prompt e istruzioni | Pi supporta `AGENTS.md`, `SYSTEM.md`, `APPEND_SYSTEM.md` e prompt template. `prompt-snippets` aggiunge piccoli frammenti attivabili per singolo messaggio, poi azzerati ([sorgente/README](https://github.com/amosblomqvist/pi-config/tree/main/extensions/prompt-snippets)). | Stessi concetti di personalizzazione del prompt, con override globali/progetto/modello ([documentazione](https://github.com/can1357/oh-my-pi/blob/main/docs/system-prompt-customization.md)); aggiunge ruoli modello, advisor e agent personalizzati. | **OMP** per orchestrazione; **pi-config** ha la migliore micro-UX per regole effimere per messaggio. |
|
||||
| Subagent | Non nativi nel core. Il companion [`pi-interactive-subagents`](https://github.com/amosblomqvist/pi-interactive-subagents) avvia agent asincroni in pannelli tmux, persistenti e pilotabili; include `scout`, `researcher` e `worker`, loadout a allowlist e nesting esplicito. | Subagent di prima classe con batch, modalità sincrona/asincrona, output strutturato, Agent Hub, steering/revive/kill e ricorsione controllata. L'isolamento del workspace esiste, ma è **opt-in**, non una proprietà automatica di ogni spawn ([task](https://github.com/can1357/oh-my-pi/blob/main/docs/tools/task.md)). | **OMP** per orchestrazione complessiva; **Amos** per pannelli tmux e minimo privilegio più semplice da verificare. |
|
||||
| Tool di coding | Il core Pi espone un set volutamente piccolo; `pi-config` aggiunge soprattutto browser, fetch/search, guard e UI di domande. | Lettura/scrittura/editing e AST, grep/glob, shell ed evaluator persistenti, LSP, DAP, code review, security scan, checkpoint/rewind e altri tool elencati nel [README](https://github.com/can1357/oh-my-pi#thirty-one-first-class-tools). Alcuni sono disattivati inizialmente. | **OMP**, nettamente, per intelligence sul codice e debug. |
|
||||
| Web e browser | [`browser`](https://github.com/amosblomqvist/pi-config/tree/main/extensions/browser) usa Playwright/Chromium headless ed è spento di default; è una singola pagina senza download/upload. `web-search` usa Google Custom Search e richiede API key/CSE ([sorgente](https://github.com/amosblomqvist/pi-config/blob/main/extensions/web-search/index.ts)); c'è anche `web-fetch`. | Browser/computer integrati e ricerca con numerosi backend, inclusi servizi a pagamento, locali/pubblici e motori specializzati ([README](https://github.com/can1357/oh-my-pi#web-search)). | **OMP** per copertura; `pi-config` è più piccolo e comprensibile. |
|
||||
| Skill e plugin | Skill file-based native di Pi più quattro skill incluse: analisi sessioni, PDF, web debug e trascrizione YouTube ([inventario](https://github.com/amosblomqvist/pi-config#skills)). `learn`, dictation, memoria e subagent sono repository separati. | Skill caricate progressivamente tramite metadata e URI `skill://` ([skill docs](https://github.com/can1357/oh-my-pi/blob/main/docs/skills.md)); marketplace per plugin Git/local/catalogo, con skill, comandi, agent, hook, tool, MCP e LSP ([marketplace](https://github.com/can1357/oh-my-pi/blob/main/docs/marketplace.md)). | **OMP** per distribuzione e composizione. |
|
||||
| MCP e interoperabilità | Dipende dalle capacità/estensioni del Pi base; `pi-config` non offre un livello MCP proprio. | Configurazione MCP utente/progetto e discovery di configurazioni provenienti anche da altri editor/agenti ([MCP docs](https://github.com/can1357/oh-my-pi/blob/main/docs/mcp-config.md)). | **OMP**. |
|
||||
| UX/TUI | TUI Pi pulita con editor, fuzzy file search, immagini, shell, steering/follow-up e alberi di sessione. `ask-user-question` aggiunge un dialogo strutturato; snippets e pannelli tmux sono distintivi. [`pi-dictate`](https://github.com/amosblomqvist/pi-dictate) aggiunge dettatura Deepgram. | TUI più ricca con card dei tool, preview/accettazione edit, picker, Agent Hub e time-travel; include sia sintesi vocale sia STT tramite scorciatoia `Alt+H` ([README OMP](https://github.com/can1357/oh-my-pi)). | **OMP** in generale; la semplicità di Pi può essere un pregio. La voce non è esclusiva della configurazione Amos. |
|
||||
| Sessioni | Pi salva JSONL ad albero, consente resume/fork/clone/tree e compaction conservando lo storico ([sessioni Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/README.md#sessions)). | JSONL append-only, struttura ad albero, blob esterni e ricostruzione versionata ([formato](https://github.com/can1357/oh-my-pi/blob/main/docs/session.md)); dump/export/share/fork/resume sono documentati come operazioni native ([operazioni](https://github.com/can1357/oh-my-pi/blob/main/docs/session-operations-export-share-fork-resume.md)). | **OMP**, di poco, per operazioni integrate; i due condividono una base concettuale simile. |
|
||||
| Memoria | [`pi-observational-memory`](https://github.com/amosblomqvist/pi-observational-memory) è opzionale e spento di default: observer LLM paralleli distillano i turni, una compaction deterministica crea un ledger e un consolidatore produce file Markdown per sessione. È auditabile, ma aggiunge costo e complessità. | Memoria spenta di default con backend `local`, Hindsight, Mnemopi e Sharpshooter; sommari/lezioni possono attraversare sessioni e alimentare skill, con esplicita avvertenza che la memoria può essere obsoleta ([memory docs](https://github.com/can1357/oh-my-pi/blob/main/docs/memory.md)). | **OMP** per scelta e integrazione; **Amos** per un modello per-sessione semplice da ispezionare. |
|
||||
| Sicurezza applicativa | Pi dichiara di non avere un permission system integrato per filesystem, processi, rete o credenziali e consiglia container/microVM ([security Pi](https://github.com/earendil-works/pi#permissions--containerization)). [`bash-guard`](https://github.com/amosblomqvist/pi-config/tree/main/extensions/bash-guard) intercetta euristicamente solo chiamate al tool `bash`: non protegge `write`, `edit` né i comandi `!`. | Ha policy per tool e tre approval mode, ma il default è **`yolo`**; in tale modalità gli override di comandi bash critici non forzano il prompt. Anche quando si approva un comando non c'è contenimento di filesystem, rete o subprocessi ([approval docs](https://github.com/can1357/oh-my-pi/blob/main/docs/approval-mode.md)). L'offuscamento dei segreti esiste ma è spento di default ([secrets docs](https://github.com/can1357/oh-my-pi/blob/main/docs/secrets.md)). | **Nessun vincitore sicuro di default**. OMP offre controlli migliori, ma sceglie un default molto permissivo. |
|
||||
| Isolamento | Nessun sandbox OS o worktree per-agent documentato; l'allowlist del loadout limita i tool, non il filesystem raggiungibile dai tool concessi. | Gli spawn normali condividono la `cwd` del parent. Workspace separato e merge patch/branch richiedono `task.isolation.enabled` **e** `isolated: true` sul task; l'opzione non è disponibile in plan mode ([task](https://github.com/can1357/oh-my-pi/blob/main/docs/tools/task.md#inputs)). Neppure questo è un sandbox OS. | **OMP** per isolamento anti-collisione opt-in; **parità negativa** come confine di sicurezza. |
|
||||
| Portabilità | I componenti sono piccoli file TypeScript/Markdown copiabili, quindi il lock-in concettuale è basso. Però molte estensioni Amos importano ancora il vecchio scope `@mariozechner/*`; il Pi attuale usa `@earendil-works/*`. L'[advisory ufficiale](https://github.com/earendil-works/pi/security/advisories/GHSA-r95r-rj6r-c39x) depreca il vecchio pacchetto, quindi oggi serve una verifica/possibile migrazione degli import. | Binari e setup multipiattaforma; importa varie convenzioni esterne. Tuttavia si è allontanato dal Pi upstream: scope `@oh-my-pi`, runtime/test Bun, moduli nativi, auth e API proprie sono differenze dichiarate nella [guida di porting](https://github.com/can1357/oh-my-pi/blob/main/docs/porting-from-pi-mono.md). | **Pi + selezione manuale** per lock-in ridotto; **OMP** per portabilità operativa immediata. |
|
||||
| Migrazione delle estensioni | È l'ambiente nativo della raccolta Amos, salvo la transizione di package scope appena citata. | Non tratta `.pi/extensions` come root nativa. Può leggere dichiarazioni `pi.extensions` nei manifest, ma il caricamento e le API non rendono la migrazione automaticamente compatibile ([extension loading](https://github.com/can1357/oh-my-pi/blob/main/docs/extension-loading.md)). | **Non è drop-in in nessuna direzione**; verificare ogni estensione. |
|
||||
| Aggiornamenti e manutenzione | `pi-config` è un piccolo snapshot personale, senza release versionate; il [registro commit](https://github.com/amosblomqvist/pi-config/commits/main/) mostra pochissimi cambiamenti e l'integrazione è responsabilità dell'utente. I companion hanno cicli propri. | Distribuzione versionata con release frequenti e asset per piattaforma; al 7 settembre 2026 la release più recente è [`v18.1.13`](https://github.com/can1357/oh-my-pi/releases/tag/v18.1.13). | **OMP** per manutenzione di prodotto; le release molto rapide aumentano anche il rischio di churn. |
|
||||
| Maturità pratica | Il Pi sottostante è un progetto attivo e maturo, ma `pi-config` non è testato o pubblicato come distribuzione unitaria. L'autore di `pi-dictate`, per esempio, lo presenta esplicitamente come tool personale mantenuto per il proprio uso ([README](https://github.com/amosblomqvist/pi-dictate)). | Repository ampio, migliaia di commit e cadenza di release elevata ([storia](https://github.com/can1357/oh-my-pi/commits/main/), [release](https://github.com/can1357/oh-my-pi/releases)). Più integrazione e utenti implicano più validazione reale, ma anche superficie di bug e regressioni maggiore. | **OMP** come prodotto; nessuna garanzia che “più grande” significhi “più stabile”. |
|
||||
|
||||
## Approfondimento: gestione dei subagenti
|
||||
|
||||
**Sì: OMP ha una gestione dei subagenti paragonabile e, come orchestratore automatico, più completa.** La proposta Amos non è però semplicemente inferiore: privilegia un diverso modello operativo, nel quale ogni agente vive in un vero pannello tmux che l'utente può osservare e usare direttamente, con un loadout strettamente autorizzato.
|
||||
|
||||
| Capacità | Pi + Amos `pi-interactive-subagents` | Oh My Pi |
|
||||
|---|---|---|
|
||||
| Esecuzione e fan-out | Sempre asincrono e non bloccante; più chiamate partono in parallelo e notificano il parent indipendentemente ([README, “How it works”](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#how-it-works)). Non è documentato un limite di concorrenza configurabile. | `task.batch` è attivo di default e accetta `tasks[]`; con `async.enabled=true` gli agenti sono job in background, altrimenti il parent attende. Un semaforo `task.maxConcurrency` limita sia sync sia async ([task: input, modi e limiti](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#modes--variants)). |
|
||||
| Messaggi fra agenti | `subagent_message` corregge uno spawn in corsa al prossimo confine di turno o riapre quello concluso; `ask_question` permette al child di parcheggiarsi e interrogare il parent ([messaging](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#messaging)). | `hub send` consegna steering/follow-up, anche agli agenti parcheggiati, che vengono riattivati; la messaggistica peer è disponibile anche ai child ([task, “Notes”](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#notes)). Limite documentato: lo steering è testo libero, non uno stato condiviso strutturato di goal/todo. |
|
||||
| Supervisione e intervento umano | Widget con stati `starting/active/waiting/stalled/running`, tool corrente e completamenti espandibili; il pannello tmux è la sessione reale, quindi l'utente può entrarvi e scrivere direttamente ([status widget](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#status-widget--configuration)). | `Alt+A` apre Agent Hub: roster/albero, attività, modello, costo/token, transcript live, steering, revive e kill; l'utente può mettere a fuoco la sessione del child e scrivergli ([Agent Hub](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/agent-hub.md)). **OMP non manca quindi della supervisione interattiva**; Amos la rende più concreta e terminal-native tramite pannelli separati. |
|
||||
| Resume e persistenza | Registro nome→sessione persistente attraverso i riavvii; il resume ripristina lo snapshot del loadout originale. Supporta sessioni `standalone`, `lineage-only` o `fork` con contesto del parent ([resume](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#messaging), [session mode](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#session-mode)). | Salva output e transcript (`agent://`, `history://`); agenti idle/parcheggiati sono riattivabili anche dopo il resume del parent ([Agent Hub, “Persisted agents”](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/agent-hub.md#persisted-agents-and-advisors)). Eccezione importante: un task eseguito in workspace isolato viene smontato dopo merge/cattura patch e **non è riattivabile** ([task flow](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#flow)). |
|
||||
| Definizioni e routing modelli | File Markdown in `.pi/agents` o `~/.pi/agent/agents`, con modello, thinking, skill, tool, `cwd` e modalità sessione; il singolo spawn può sovrascrivere il modello. Include tre profili (`scout`, `researcher`, `worker`) ([custom agents](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#custom-agents)). | File Markdown `.omp/agents`, agent inclusi e provenienti da estensioni/plugin; routing con override per nome, lista fallback e alias `modelRoles`, più effort per task, prewalk e advisor opzionali ([agent definition](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/task-agent-discovery.md#agent-definition-shape), [routing](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/task-agent-discovery.md#model-and-structured-output-precedence)). |
|
||||
| Tool e sicurezza applicativa | Allowlist stretta: il child parte con `--no-extensions` e riceve soltanto i tool e le estensioni esplicitamente elencati; lo snapshot preserva il vincolo al resume ([tool access](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#tool-access-control)). È minimo privilegio applicativo, non sandbox OS. | Ogni definizione può limitare `tools` e `spawns`, e il limite di profondità rimuove `task`; però i child headless forzano `tools.approvalMode: yolo`, perché non hanno una UI locale per le conferme ([task flow](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#flow)). Di conseguenza la qualità dell'allowlist/deny policy del parent è un confine essenziale. |
|
||||
| Agenti annidati | Solo se `subagent_agents` è presente; la lista autorizza nomi precisi a ogni livello e non esiste uno spawn senza profilo nominato ([tool access](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#tool-access-control)). Il parent attende anche i nipoti prima dell'auto-exit. | Supportati con policy `spawns` e limite `task.maxRecursionDepth` (default `2`); al limite il tool `task` viene rimosso ([recursion gating](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/task-agent-discovery.md#recursion-depth-gating)). Agent Hub conserva la gerarchia parent/child. |
|
||||
| Filesystem, worktree e conflitti | `cwd` può assegnare una directory diversa, ma il README non documenta workspace/worktree isolati né merge automatici ([role folders](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#role-folders)). **Inferenza:** più worker scriventi nella stessa checkout possono quindi collidere; separare le `cwd` resta responsabilità dell'orchestratore/utente. | Lo spawn ordinario usa la `cwd` del parent. L'isolamento è disponibile soltanto con configurazione globale attiva, `isolated: true`, repository Git e fuori dal plan mode; può applicare patch o cherry-pickare un branch ([task modes](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#modes--variants)). Verifica l'applicabilità della patch; in caso di conflitto lascia l'artefatto per intervento manuale e preserva lo stash in branch mode ([gestione conflitti](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#notes)). |
|
||||
| Output | Il risultato è l'ultimo messaggio assistant, inoltrato al parent; non è documentato un contratto JSON Schema né un merge di file ([auto-exit](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#auto-exit)). | `outputSchema` per item, modalità `permissive`/`strict`, risultato parsato e artefatti completi tramite `agent://`; il child deve concludere con `yield`, con fino a tre reminder ([task outputs](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#outputs), [flow](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#flow)). |
|
||||
| Portabilità e prerequisiti | Questa variante è esplicitamente **tmux-only** e richiede Pi + tmux ([requirements](https://github.com/amosblomqvist/pi-interactive-subagents/blob/c3e8b53c0754ae5ccc19fdab5a7481ec039bc2f7/README.md#requirements)); l'upstream HazAT supporta più multiplexer, ma non è il componente qui confrontato. | Il runtime OMP è multipiattaforma; l'isolamento seleziona backend diversi per Linux, macOS e Windows e ricade su copia ricorsiva quando necessario ([backend di isolamento](https://github.com/can1357/oh-my-pi/blob/4c6feacddb6ff26e5219df7283bc371ad7e1de55/docs/tools/task.md#side-effects)). |
|
||||
|
||||
### Giudizio mirato
|
||||
|
||||
**Per orchestrazione di subagenti sceglierei OMP**, perché combina fan-out controllato, sync/async, Agent Hub, messaggistica peer, output tipizzato, nesting con limiti e isolamento anti-collisione opzionale. Quindi la risposta alla domanda “ce l'ha anche OMP?” è **sì, e sul piano funzionale offre di più**.
|
||||
|
||||
**Pi + Amos resta preferibile in due casi:** quando si vuole entrare fisicamente nei pannelli dei worker mentre lavorano, oppure quando si considera prioritaria una politica child “deny by default” molto leggibile. La sua gestione può essere ottimale per un power user tmux; non è però altrettanto completa come orchestratore automatico, soprattutto per output strutturato, concorrenza limitata e gestione/merge degli artefatti.
|
||||
|
||||
Due caveat impediscono un verdetto semplicistico:
|
||||
|
||||
1. in OMP “subagent isolato” non significa “ogni subagent”: senza entrambi i toggle necessari, gli agenti scriventi condividono la checkout;
|
||||
2. isolamento e continuità sono in tensione: il child OMP isolato evita collisioni, ma dopo il merge/cleanup non può essere riattivato; uno non isolato può invece essere parcheggiato e ripreso.
|
||||
|
||||
## Cosa include davvero `pi-config`
|
||||
|
||||
Nel repository principale ci sono:
|
||||
|
||||
- `ask-user-question`: richiesta strutturata con popup TUI e serializzazione dell'interazione;
|
||||
- `bash-guard`: conferma/blocco euristico di comandi shell pericolosi;
|
||||
- `browser`: automazione Playwright su Chromium headless, disattivata inizialmente;
|
||||
- `custom-header`: header TUI personalizzato;
|
||||
- `prompt-snippets`: regole brevi attivabili sul singolo messaggio;
|
||||
- `web-fetch` e `web-search`;
|
||||
- skill per analisi sessioni, PDF, debug web e trascrizione YouTube.
|
||||
|
||||
L'elenco e i prerequisiti sono nel [README ufficiale](https://github.com/amosblomqvist/pi-config). Le capacità più ambiziose sono in repository distinti:
|
||||
|
||||
- [`pi-interactive-subagents`](https://github.com/amosblomqvist/pi-interactive-subagents), subagent interattivi in tmux;
|
||||
- [`pi-observational-memory`](https://github.com/amosblomqvist/pi-observational-memory), memoria osservazionale per sessione;
|
||||
- [`pi-dictate`](https://github.com/amosblomqvist/pi-dictate), STT con Deepgram;
|
||||
- [`learn`](https://github.com/amosblomqvist/learn), ambiente didattico con quiz, log e agent di ricerca/visualizzazione.
|
||||
|
||||
Questi componenti **non formano automaticamente una singola installazione testata, aggiornata e versionata insieme**. Considerarli una “suite” è un'inferenza utile per il confronto, non una promessa del maintainer.
|
||||
|
||||
## Dove OMP è realmente superiore
|
||||
|
||||
1. **È coerente come prodotto.** Installazione, configurazione YAML, schema, tool, sessioni e aggiornamenti fanno parte dello stesso rilascio ([settings](https://github.com/can1357/oh-my-pi/blob/main/docs/settings.md)).
|
||||
2. **Il routing dei modelli è molto più sofisticato.** Non si sceglie soltanto un modello: si possono assegnare costi/capacità differenti a pianificazione, task, vision, commit, advisor e attività leggere.
|
||||
3. **L'intelligence sul codice è integrata.** LSP, DAP, editing AST, evaluator persistenti e review non richiedono di costruire un proprio stack di estensioni.
|
||||
4. **Subagent e memoria sono parti del sistema**, non componenti companion da sincronizzare a mano.
|
||||
5. **Ha più opzioni di interoperabilità**: MCP, marketplace e discovery di configurazioni da altri strumenti.
|
||||
|
||||
Questa superiorità è soprattutto di **copertura e integrazione**, non una prova automatica di qualità superiore per ogni singola funzione. Le quantità dichiarate nel README di OMP sono affermazioni del progetto, non benchmark indipendenti.
|
||||
|
||||
## Dove Pi + la configurazione Amos è migliore
|
||||
|
||||
1. **È più facile capire il perimetro.** Ogni estensione è piccola, selezionabile e sostituibile. Si può usare `prompt-snippets` senza accettare browser, memoria o subagent.
|
||||
2. **Ha meno lock-in architetturale.** Le skill Markdown e molte estensioni TypeScript restano vicine all'ecosistema Pi, anche se oggi gli import verso il vecchio package scope richiedono attenzione.
|
||||
3. **Alcune idee sono più eleganti che “integrate”.** Gli snippet effimeri per messaggio, gli agent visibili nei pannelli tmux e la memoria in file Markdown per sessione sono facili da osservare e modificare.
|
||||
4. **Favorisce l'apprendimento del sistema.** È una buona base per chi vuole costruirsi il proprio harness anziché adottare una piattaforma già opinionata.
|
||||
|
||||
Il prezzo è tempo operativo: installazione, dipendenze, compatibilità, aggiornamenti e test ricadono sull'utente.
|
||||
|
||||
## Sicurezza: la conclusione scomoda
|
||||
|
||||
**Né Pi + `pi-config` né OMP forniscono, da soli, un sandbox di sicurezza.**
|
||||
|
||||
- In Pi, `bash-guard` è un buon guardrail UX, ma non vede tutte le scritture e non contiene il processo. Le estensioni Pi hanno accesso al sistema con i privilegi dell'utente; la documentazione raccomanda esplicitamente container o microVM ([Pi security](https://github.com/earendil-works/pi#permissions--containerization)).
|
||||
- In OMP esistono più policy, deny list e modalità di approvazione. Tuttavia `tools.approvalMode` parte da **`yolo`**, i safety override bash non diventano prompt in quella modalità, un comando approvato conserva accesso ambientale e le estensioni girano nello stesso processo ([approval mode](https://github.com/can1357/oh-my-pi/blob/main/docs/approval-mode.md), [extension loading](https://github.com/can1357/oh-my-pi/blob/main/docs/extension-loading.md)). Anche la protezione dei segreti è opt-in.
|
||||
|
||||
Se scegliessi OMP imposterei subito almeno:
|
||||
|
||||
1. `tools.approvalMode: always-ask` per un ambiente sensibile, oppure `write` come compromesso;
|
||||
2. deny/prompt espliciti per evaluator, browser/computer e tool non necessari;
|
||||
3. offuscamento segreti abilitato e configurato;
|
||||
4. esecuzione in container, VM o microVM quando repository, credenziali o rete sono sensibili.
|
||||
|
||||
Con Pi farei la stessa cosa a livello OS e tratterei `bash-guard` come seconda cintura, non come sandbox.
|
||||
|
||||
## Raccomandazione per profilo
|
||||
|
||||
| Profilo | Scelta consigliata | Perché |
|
||||
|---|---|---|
|
||||
| Sviluppatore che vuole essere produttivo subito | **Oh My Pi** | Meno assemblaggio; LSP/DAP, modelli, agent e sessioni sono già integrati. |
|
||||
| Power user multi-model / molti provider | **Oh My Pi** | Routing per ruolo, fallback e credenziali multiple sono capacità native. |
|
||||
| Team che vuole una configurazione ripetibile | **Oh My Pi**, release fissata | Installer, Nix/mise, config e release versionate sono più riproducibili; fissare la versione riduce il churn. |
|
||||
| Hacker di Pi che vuole costruire il proprio ambiente | **Pi + componenti `pi-config`** | Superficie ridotta, sorgenti leggibili, composizione libera. |
|
||||
| Utente che vuole solo snippet, guard o browser | **Pi + singole estensioni** | Non serve adottare un fork molto più grande per tre capacità. |
|
||||
| Chi apprezza subagent visibili e interattivi in tmux | **Pi + `pi-interactive-subagents`** | È una scelta UX specifica e ben distinta dall'Agent Hub. |
|
||||
| Ambiente ad alta sicurezza | **Nessuno dei due senza isolamento OS** | I controlli applicativi non sostituiscono container/microVM; OMP va inoltre tolto da `yolo`. |
|
||||
| Runtime Pi già integrato via RPC, come ThothII | **Restare su Pi salvo progetto di migrazione dedicato** | OMP offre RPC/ACP, ma package scope, caricamento estensioni, eventi e semantiche del fork richiedono test contrattuali: non è una sostituzione drop-in. |
|
||||
|
||||
### Nota specifica per ThothII
|
||||
|
||||
Per usare un agente nel terminale del repository, OMP può essere valutato senza cambiare l'architettura. **Sostituire invece il processo Pi che ThothII avvia in modalità RPC è un'altra decisione.** ThothII dipende dal contratto degli eventi RPC, dall'estensione gate, dal resume e dal comportamento di sessione. La [guida di porting di OMP](https://github.com/can1357/oh-my-pi/blob/main/docs/porting-from-pi-mono.md) e la sua [documentazione di caricamento estensioni](https://github.com/can1357/oh-my-pi/blob/main/docs/extension-loading.md) mostrano divergenze sufficienti da richiedere almeno una suite di compatibilità end-to-end prima di considerarlo un sostituto.
|
||||
|
||||
## Verdetto
|
||||
|
||||
**Il migliore in assoluto, per me, è Oh My Pi — con una release fissata e una configurazione iniziale più restrittiva del default.** Vince quasi tutte le categorie funzionali e riduce drasticamente il lavoro di integrazione.
|
||||
|
||||
Non lo sceglierei però “alla cieca”: `yolo` come default è un caveat serio, la superficie enorme rende probabile qualche regressione e il fork crea più dipendenza dalle proprie API. Per una workstation con codice e credenziali reali lo metterei dietro approvazioni esplicite e isolamento OS.
|
||||
|
||||
**Pi + `pi-config` è la scelta migliore quando l'obiettivo è un ambiente personale minimale e intenzionale**, non quando si cerca il maggior numero di funzioni. Installerei solo i componenti necessari, controllerei gli import dopo la migrazione da `@mariozechner/*` a `@earendil-works/*` e aggiungerei test prima di usarli in un flusso critico.
|
||||
@@ -1,44 +0,0 @@
|
||||
# Z.ai Coding Plan: bonus di quota e client CLI
|
||||
|
||||
Verifica effettuata il **7 settembre 2026**, esclusivamente su fonti ufficiali Z.ai/ZCode.
|
||||
|
||||
## Risposta breve
|
||||
|
||||
**No: Z.ai non documenta un bonus permanente del 150% (+50%) per un altro harness CLI.** La sola pagina ufficiale che usa oggi l'espressione “150% quota boost” è quella di **AutoClaw**: lo presenta come vantaggio a tempo limitato per piani Individual e Team, ma non precisa se significhi quota finale al 150% o incremento del 150%. AutoClaw è inoltre descritto come applicazione desktop per macOS e Windows, non come CLI da installare su un server. ([AutoClaw](https://autoclaw.z.ai/))
|
||||
|
||||
C'è però una promozione temporanea più interessante e formulata senza ambiguità: dal **3 al 20 settembre 2026**, ogni giorno fra le **23:00 e le 09:00 UTC+8**, GLM-5.3-Flash consuma zero quota in ZCode, mentre negli **altri agenti ufficialmente supportati la quota disponibile è raddoppiata**. In Italia, nel periodo della campagna, la finestra corrisponde alle **17:00–03:00 CEST**. La promozione vale per tutti i piani a pagamento e soltanto per GLM-5.3-Flash; GLM-5.3 continua a consumare la quota normale. ([GLM-5.3-Flash Usage Campaign](https://docs.z.ai/devpack/notice/event-glm-5.3-flash))
|
||||
|
||||
## Quali alternative CLI sono ufficialmente ammesse
|
||||
|
||||
La pagina corrente dei tool supportati nomina espressamente questi client utilizzabili da terminale:
|
||||
|
||||
| Harness | CLI/server | Stato nella documentazione Z.ai | Quota |
|
||||
|---|---:|---|---|
|
||||
| **Pi** | Sì | Esplicitamente incluso fra i Coding Agent Tool | Quota ordinaria; **2× su GLM-5.3-Flash nella finestra della campagna** |
|
||||
| **Codex** | Sì | Esplicitamente incluso fra i Coding Agent Tool | Come sopra |
|
||||
| **Claude Code** | Sì | Supportato e corredato da guida CLI ufficiale Z.ai | Come sopra |
|
||||
| **OpenCode** | Sì | Supportato; guida ufficiale intitolata esplicitamente “OpenCode CLI” | Come sopra |
|
||||
| **Droid** | Sì | Descritto da Z.ai come agente che gira nel terminale | Come sopra |
|
||||
| **Crush** | Sì | Descritto esplicitamente come CLI/TUI | Come sopra |
|
||||
| **Goose** | Sì | Incluso fra i Coding Agent Tool, con esecuzione locale | Come sopra |
|
||||
| **Oh My Pi (OMP)** | Sì, tecnicamente | **Non è nominato** nell'elenco ufficiale; Z.ai nomina Pi, non OMP | Bonus e conformità **non confermati ufficialmente** |
|
||||
|
||||
Fonti: [elenco ufficiale dei tool e endpoint Coding Plan](https://docs.z.ai/devpack/tool/others), [guida Claude Code](https://docs.z.ai/devpack/tool/claude), [guida OpenCode CLI](https://docs.z.ai/devpack/tool/opencode).
|
||||
|
||||
Z.ai espone endpoint Coding Plan per Anthropic Messages, OpenAI Chat Completions e OpenAI Responses, ma questo **non rende automaticamente autorizzato qualunque client compatibile**: le condizioni limitano la quota ai tool ufficialmente supportati e avvertono che l'uso con integrazioni non autorizzate può comportare restrizioni. ([Subscription Terms](https://docs.z.ai/legal-agreement/subscription-terms), [Usage Policy](https://docs.z.ai/devpack/usage-policy))
|
||||
|
||||
## Implicazione pratica per il server
|
||||
|
||||
Per il caso in esame sceglierei **Pi + configurazione Amos direttamente sul server**: Pi è ora nominato ufficialmente da Z.ai, funziona da terminale e, durante la campagna attuale, rientra ragionevolmente negli “other supported Agents” con quota raddoppiata per GLM-5.3-Flash. La configurazione Amos estende Pi senza sostituire il client; resta comunque prudente verificare nel pannello consumi che le chiamate vengano classificate come Pi.
|
||||
|
||||
La seconda scelta è **OpenCode**, perché Z.ai fornisce una procedura CLI esplicita (`opencode auth login` → `Z.AI Coding Plan`). Claude Code è altrettanto documentato, ma la scelta dipende dalla preferenza per il suo harness.
|
||||
|
||||
Non sceglierei OMP confidando nel bonus: benché possa usare endpoint compatibili, **Oh My Pi non compare per nome** nell'elenco autorizzato. La risposta ufficialmente difendibile è quindi: **Pi sì; OMP non confermato**.
|
||||
|
||||
Infine, ZCode dispone oggi di pacchetti Linux, ma la documentazione li definisce sempre **desktop app** (`.AppImage`, `.deb`, `.rpm`) da lanciare con interfaccia grafica; non documenta una modalità CLI/headless equivalente a Pi o OpenCode. ([Installazione ZCode](https://zcode.z.ai/en/docs/install))
|
||||
|
||||
## Verdetto
|
||||
|
||||
- Se si cerca **esattamente un +50% permanente**, non risulta alcun harness CLI ufficialmente documentato.
|
||||
- Se si vuole sfruttare la **promozione corrente**, Pi, Codex, Claude Code, OpenCode, Droid, Crush e Goose sono alternative CLI ufficialmente supportate; nel periodo e nella fascia indicati ottengono **2×**, non 150%, usando GLM-5.3-Flash.
|
||||
- Per questa infrastruttura sceglierei **Pi+Amos sul server**, oppure **OpenCode** se si desidera il percorso d'installazione più esplicitamente documentato da Z.ai.
|
||||
@@ -1,67 +0,0 @@
|
||||
# ACP di Zed, Oh My Pi e Pi
|
||||
|
||||
_Verifica effettuata il 7 settembre 2026 su documentazione e codice sorgente primari._
|
||||
|
||||
## In breve
|
||||
|
||||
ACP (Agent Client Protocol) è un protocollo aperto che standardizza il collegamento tra un
|
||||
editor/IDE e un coding agent. Il paragone utile è con LSP: LSP standardizza editor ↔ language
|
||||
server, ACP standardizza editor ↔ agente. Il client (per esempio Zed) ospita l'interfaccia;
|
||||
l'agent process conserva normalmente runtime, modelli, autenticazione, strumenti e configurazione.
|
||||
|
||||
ACP usa JSON-RPC 2.0. Copre inizializzazione e autenticazione, creazione/ripristino delle sessioni,
|
||||
prompt e cancellazione, streaming di testo e pensieri, piani e tool call, comandi, richieste di
|
||||
permesso e — se entrambe le parti lo supportano — operazioni su filesystem e terminale.
|
||||
|
||||
Fonti: [introduzione ACP](https://agentclientprotocol.com/overview/introduction),
|
||||
[flusso e metodi del protocollo](https://agentclientprotocol.com/protocol/overview),
|
||||
[External Agents in Zed](https://zed.dev/docs/ai/external-agents).
|
||||
|
||||
## Confronto in Zed
|
||||
|
||||
| Aspetto | Oh My Pi | Pi |
|
||||
|---|---|---|
|
||||
| Tipo di integrazione | Server ACP incorporato: `omp acp` | Adapter comunitario `pi-acp`, installabile dal registry di Zed |
|
||||
| Collegamento al motore | ACP è una modalità dello stesso motore OMP | L'adapter avvia `pi --mode rpc` e traduce RPC ↔ ACP |
|
||||
| Output e tool call | Streaming e tool call ACP nativi | Streaming, tool card, posizioni nei file e diff strutturati tradotti dall'adapter |
|
||||
| File | Può inoltrare `read`/`write` al filesystem del client | Nessuna delega ACP `fs/*`; Pi legge e scrive localmente |
|
||||
| Terminale | Può creare e seguire terminali del client | Nessuna delega ACP `terminal/*`; i comandi girano localmente |
|
||||
| Permessi | `edit` e `bash` possono usare `session/request_permission` nell'editor | La UI riceve i tool call, ma non ha la stessa integrazione nativa di file/terminale |
|
||||
| Sessioni | Implementazione diretta di sessioni, comandi e configurazione ACP | Mappa le sessioni ACP ai file di sessione Pi e supporta `session/load` |
|
||||
| Skills/comandi | Carica skills, estensioni e slash command OMP | Carica skills e comandi Pi; l'adapter aggiunge comandi per l'uso headless |
|
||||
| MCP configurati in Zed | OMP contiene il plumbing ACP/MCP nel proprio server | Accettati nei parametri ACP ma non inoltrati a Pi dall'adapter corrente |
|
||||
| Maturità dichiarata | Funzionalità first-class del progetto | L'adapter si definisce “MVP-style” e centrato soprattutto su Zed |
|
||||
|
||||
L'integrazione OMP non è solo una dichiarazione nel README: il comando ACP è parte del sorgente e
|
||||
il `ClientBridge` instrada `read`, `write`, `bash`, `edit` e richieste di permesso verso il client
|
||||
quando Zed annuncia le capacità corrispondenti. Fonti:
|
||||
[README OMP](https://github.com/can1357/oh-my-pi/blob/daf07999c2fee9b22edc7bf8fea1fb6272e0df5e/README.md),
|
||||
[comando ACP](https://github.com/can1357/oh-my-pi/blob/daf07999c2fee9b22edc7bf8fea1fb6272e0df5e/packages/coding-agent/src/commands/acp.ts),
|
||||
[ACP ClientBridge](https://github.com/can1357/oh-my-pi/blob/daf07999c2fee9b22edc7bf8fea1fb6272e0df5e/packages/coding-agent/src/modes/acp/acp-client-bridge.ts).
|
||||
|
||||
Pi è comunque supportato esplicitamente da Zed: si installa `pi ACP` dal registry. L'integrazione
|
||||
è però un progetto separato e non una modalità presente nel core Pi. L'adapter corrente conserva
|
||||
molto dell'esperienza utile — streaming, tool call, diff, resume, comandi e skills — ma dichiara
|
||||
esplicitamente di non delegare filesystem o terminale a Zed e di non collegare a Pi gli MCP server
|
||||
ricevuti dal client. Fonti:
|
||||
[scheda Pi nel registry Zed](https://zed.dev/acp/agent/pi),
|
||||
[manifest del registry](https://github.com/agentclientprotocol/registry/blob/9ec416a76f69c9ff8a8316931e38f4c74ad41fa8/pi-acp/agent.json),
|
||||
[README e limiti di `pi-acp`](https://github.com/svkozak/pi-acp/blob/d1cffc047ab37a096ee70ca39cfc1de463db8d12/README.md),
|
||||
[RPC di Pi](https://github.com/earendil-works/pi/blob/9211da172325117dc59e6f9f25f248dc628b3f81/packages/coding-agent/docs/rpc.md).
|
||||
|
||||
## Giudizio
|
||||
|
||||
**OMP si trova meglio con ACP perché ACP è una sua interfaccia nativa e il suo livello strumenti è
|
||||
stato progettato per delegare operazioni all'editor.** Zed non è soltanto una finestra per la chat:
|
||||
partecipa a file, terminale e autorizzazioni.
|
||||
|
||||
**Pi si trova comunque bene con Zed per l'uso quotidiano**, specialmente per conversazione,
|
||||
streaming, modifiche, diff e ripresa delle sessioni. Oggi, però, l'integrazione è meno profonda:
|
||||
Zed controlla un adapter che controlla Pi via RPC, mentre file e shell rimangono dal lato Pi.
|
||||
|
||||
Per Pi+Amos, i subagenti tmux non diventano automaticamente thread/subagenti nativi di Zed: ACP
|
||||
espone la sessione Pi principale, mentre l'orchestrazione Amos continua nel proprio runtime e nei
|
||||
pane tmux. È quindi una combinazione possibile, ma per osservare e pilotare direttamente quei pane
|
||||
l'esperienza terminale/tmux resta più fedele. Questa conclusione è un'inferenza dall'architettura
|
||||
dell'adapter (`pi-acp` avvia una singola sessione Pi RPC per sessione ACP) e dai limiti dichiarati,
|
||||
non una garanzia esplicita del progetto Amos.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Qwen 3.6: session tool-call failure and correction
|
||||
|
||||
Date: 2026-09-21. Verified runtime: Pi coding agent and Pi AI 0.80.3.
|
||||
|
||||
## Cause and correction
|
||||
|
||||
Interactive sessions returned text resembling a bash call and stopped before the
|
||||
first review widget. The Evidence-only extension `tht-evidence-json-mode.ts` lived
|
||||
under `.pi/extensions`, so Pi automatically loaded it into interactive sessions.
|
||||
Its `before_provider_request` hook imposed `response_format: {type: "json_object"}`
|
||||
and temperature zero on every request.
|
||||
|
||||
Replaying the captured startup request, with all original hooks preserved, isolated
|
||||
the cause. With JSON response format, Qwen returned the command as text and finish
|
||||
reason `stop`. Removing only that field produced a native `bash` call and finish
|
||||
reason `tool_calls`. Both requests contained the same 15 tools and used High thinking.
|
||||
|
||||
The extension now lives in `.pi/evidence-extensions` and is loaded explicitly by
|
||||
`PiEvidenceRestructurer`. Evidence retains JSON output. Interactive sessions retain
|
||||
native tool calls. No changes to the remote Qwen server were required.
|
||||
|
||||
Earlier SDK probes replaced `session.agent.onPayload`, inadvertently bypassing the
|
||||
extension hooks. Their success did not reproduce the application path and did not
|
||||
establish a model or server fault.
|
||||
|
||||
## Model configuration
|
||||
|
||||
The installation catalog now accepts optional `session.compatibility.thinkingFormat`
|
||||
values `qwen` and `qwen-chat-template`, requiring `reasoning: true`. Go validation,
|
||||
the backend schema, and generated catalog/Pi projections preserve this setting.
|
||||
It controls thinking; it was not the cause or correction of the tool-call failure.
|
||||
|
||||
For the verified endpoint, `qwen-chat-template` sends `enable_thinking` and
|
||||
`preserve_thinking` inside `chat_template_kwargs`. Selecting Off explicitly disables
|
||||
thinking. Declaring `reasoning: false` alone does not disable thinking on the server.
|
||||
See the [operator configuration](../general/pi-configuration.md#qwen-36-sessions-and-thinking-controls)
|
||||
and [Pi 0.80.3 model documentation](https://github.com/earendil-works/pi/blob/v0.80.3/packages/coding-agent/docs/models.md#openai-compatibility).
|
||||
|
||||
## Validation and local delivery
|
||||
|
||||
- Catalog and projection regression tests failed before the compatibility change,
|
||||
then passed. Go config/modelprojection/CLI tests, 84 targeted backend tests,
|
||||
TypeScript checking, and the strict documentation build passed.
|
||||
- The extension-isolation regression failed before relocation. All 46 Evidence
|
||||
authoring/restructurer tests and Ruff checks on changed Python files passed.
|
||||
- The rebuilt local core image has digest
|
||||
`sha256:9cd593d7362dcbefe177f1b9eb4b9ffdf3010ced7bd7efc8fc3fdcd288f24579`.
|
||||
Core/frontend were recreated, healthy, and returned HTTP 200.
|
||||
- A real `pi --mode rpc --no-session` probe with Qwen and High thinking executed
|
||||
`tht session show` successfully and reached the first clarification widget.
|
||||
The probe allowed only that read and `reviewer_select`; it stopped without
|
||||
submitting a human response or recording decisions. Its temporary configuration
|
||||
referenced the mounted credential because the original runtime lease had expired.
|
||||
- The user subsequently confirmed that the application now works.
|
||||
|
||||
This verifies recovery from the startup failure. It does not certify every workflow
|
||||
phase or the separate LiteLLM metadata-generation path.
|
||||
|
||||
## Public manual publication
|
||||
|
||||
- Source: `84084bba37d4985658174db04f8e9195c0435d72`, pushed to Gitea `main`.
|
||||
- Actions generated `pages` commit `1fe88f99228e06d10e8ecd92556c1ef0d52526e8`
|
||||
for that exact source revision.
|
||||
- Live release: `20260921T142437Z-84084bba`; previous release retained for rollback:
|
||||
`20260916-css-b1c510a0`.
|
||||
- Built from a clean checkout with the locked strict MkDocs build and all four
|
||||
authentication documentation verification scripts passing. The public boundary
|
||||
contains exactly 20 pages. The committed Go tests, Evidence tests, targeted
|
||||
backend tests, and TypeScript check also passed from that checkout.
|
||||
- Recreated only the `thothii-docs` Compose service. It is healthy, its mounted
|
||||
`current` release is correct, and `nginx -t` passed.
|
||||
- Anonymous requests to home, search, both installation manuals, and the model
|
||||
configuration page returned 200 with bytes matching the clean build. Styles,
|
||||
scripts, and referenced fonts returned 200 with the expected content types.
|
||||
The retired/internal overview, memory-plan, and Compose-reference paths returned 404.
|
||||
- Browser checks of both installation manuals and the Qwen section confirmed
|
||||
loaded stylesheets and styled, readable layouts.
|
||||
|
||||
Published page: [Qwen 3.6 configuration](https://git.tylconsulting.it/thothii-docs/general/pi-configuration/#qwen-36-sessions-and-thinking-controls).
|
||||
@@ -0,0 +1,49 @@
|
||||
# Dimensioni dei sei database candidati
|
||||
|
||||
Verifica del 27 settembre 2026 tramite lettura HTTP Range della directory centrale
|
||||
degli archivi ZIP ufficiali. I valori sono le dimensioni non compresse dichiarate
|
||||
per i singoli file, non il consumo misurato dopo importazione in PostgreSQL.
|
||||
GB e MB sono decimali: 1 GB = 1.000.000.000 byte.
|
||||
|
||||
| Database | Formato | Byte | GB | MB |
|
||||
| --- | --- | ---: | ---: | ---: |
|
||||
| Financial, BIRD Mini-Dev | SQLite | 71.294.976 | 0,071295 | 71,295 |
|
||||
| European Football, BIRD Mini-Dev | SQLite | 597.754.880 | 0,597755 | 597,755 |
|
||||
| F1, Spider 2.0-Lite | SQLite | 74.940.416 | 0,074940 | 74,940 |
|
||||
| Shopify, Spider 2.0-DBT, shopify001 | DuckDB iniziale | 19.935.232 | 0,019935 | 19,935 |
|
||||
| QuickBooks, Spider 2.0-DBT, quickbooks001 | DuckDB iniziale | 50.606.080 | 0,050606 | 50,606 |
|
||||
| Workday, Spider 2.0-DBT, workday001 | DuckDB iniziale | 28.323.840 | 0,028324 | 28,324 |
|
||||
| Totale | | 842.855.424 | 0,842855 | 842,855 |
|
||||
|
||||
## Provenienza
|
||||
|
||||
- [BIRD Mini-Dev ZIP](https://bird-bench.oss-cn-beijing.aliyuncs.com/minidev.zip),
|
||||
collegato dal [repository ufficiale](https://github.com/bird-bench/mini_dev).
|
||||
Archivio: 800.943.648 byte; Last-Modified 20 giugno 2024.
|
||||
Entry: `minidev/MINIDEV/dev_databases/financial/financial.sqlite` e
|
||||
`minidev/MINIDEV/dev_databases/european_football_2/european_football_2.sqlite`.
|
||||
- [Spider database locali](https://drive.google.com/file/d/1coEVsCZq-Xvj9p2TnhBFoFTsY-UoYGmG/view),
|
||||
collegati dal [README Lite](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/README.md).
|
||||
Archivio: 456.643.204 byte; entry `f1.sqlite`.
|
||||
- [DBT_start_db.zip](https://drive.google.com/file/d/1N3f7BSWC4foj-V-1C9n8M2XmgV7FOcqL/view),
|
||||
collegato dal [README DBT](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/README.md).
|
||||
Archivio: 377.819.033 byte; Last-Modified 19 dicembre 2024.
|
||||
Entry: `shopify001/shopify.duckdb`, `quickbooks001/quickbooks.duckdb`,
|
||||
`workday001/workday.duckdb`.
|
||||
|
||||
I pesi degli archivi completi non sono quelli dei soli database selezionati:
|
||||
contengono anche altri esempi. Non sommarli alla tabella salvo voler conservare
|
||||
localmente tutti i pacchetti originali.
|
||||
|
||||
Per confronto, l'archivio ufficiale `dbt_gold.zip` contiene file corrispondenti di
|
||||
22.032.384 byte (Shopify), 54.013.952 byte (QuickBooks) e 28.848.128 byte (Workday).
|
||||
Sono versioni di risultato del benchmark, non la base scelta per la tabella e non
|
||||
una previsione del consumo finale di ThothII.
|
||||
|
||||
## Limiti
|
||||
|
||||
Il totale esclude descrizioni, Evidence, CSV esportati, indici aggiuntivi, log,
|
||||
PostgreSQL, Qdrant, immagini Docker e modelli locali. La conversione può modificare
|
||||
sensibilmente l'occupazione. Non sono state estratte tutte le tabelle né contate
|
||||
le righe: il peso del file non prova che tutte le tabelle documentate siano popolate.
|
||||
La complessità di schema e dominio non implica grandi volumi nei dati dimostrativi.
|
||||
@@ -0,0 +1,117 @@
|
||||
# Candidati Spider 2.0-DBT con documentazione di dominio
|
||||
|
||||
Ricerca del 27 settembre 2026. Obiettivo: scegliere un database locale complesso,
|
||||
con materiale da curare come Source Evidence di ThothII. Non vengono usate
|
||||
domande del benchmark, SQL attesi o punteggi come criterio di selezione.
|
||||
|
||||
## Raccomandazione
|
||||
|
||||
**Shopify è il candidato da verificare per primo**, perché combina commercio,
|
||||
pagamenti, rimborsi, inventario e ordini con documentazione dei significati e
|
||||
delle misure. Offre inoltre un dominio diverso dal Financial BIRD già proposto.
|
||||
QuickBooks è una valida alternativa se si preferisce la contabilità; Workday
|
||||
se si preferiscono personale e storia organizzativa. Questa priorità è una
|
||||
valutazione per il progetto, non una classificazione ufficiale Spider.
|
||||
|
||||
| Progetto Spider 2.0-DBT | Tabelle sorgente dichiarate | Coppie tabella/colonna descritte e distinte | Database locale indicato dal profilo |
|
||||
| --- | ---: | ---: | --- |
|
||||
| Shopify, `shopify001` | 34 | 578 | `shopify.duckdb` |
|
||||
| QuickBooks, `quickbooks001` | 40 | 426 | `quickbooks.duckdb` |
|
||||
| Workday, `workday001` | 21 | 436 | `workday.duckdb` |
|
||||
|
||||
Conteggi ricavati analizzando i rispettivi YAML `sources[].tables[]` e le
|
||||
descrizioni delle colonne; **non sono un'ispezione delle tabelle materializzate
|
||||
nei file DuckDB**. Alcune tabelle possono essere opzionali. Shopify ha 581
|
||||
dichiarazioni di colonna, ma tre sono duplicate: `order.total_shipping_price_set`,
|
||||
`order_line.tax_code`, `order_line_refund.subtotal_set`. I conteggi comprendono
|
||||
anche metadati tecnici e riferimenti `doc(...)`: **non equivalgono a un numero
|
||||
di Evidence Unit**. Sono esclusi i pacchetti di utilità generica dbt.
|
||||
Fonti: [Shopify schema](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/shopify001/dbt_packages/shopify_source/models/src_shopify.yml),
|
||||
[QuickBooks schema](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/quickbooks001/dbt_packages/quickbooks_source/models/src_quickbooks.yml),
|
||||
[Workday schema](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/workday001/models/staging/src_workday.yml).
|
||||
|
||||
## Shopify: commercio e operazioni
|
||||
|
||||
Lo schema documenta ordini e righe d'ordine, clienti, prodotti e varianti,
|
||||
transazioni, rimborsi, rettifiche, spedizioni, imposte, sconti, inventario,
|
||||
sedi e checkout abbandonati. Le descrizioni specificano sia la granularità
|
||||
delle entità sia il significato dei campi. Esempi di materiale semanticamente
|
||||
utile: il subtotale è dopo gli sconti e prima di spedizione, imposte e mance;
|
||||
`processed_at` è la data usata nei report analitici; l'ID API dell'ordine è
|
||||
distinto dal numero mostrato al cliente; valuta del negozio e valuta presentata
|
||||
al cliente hanno ruoli distinti. Le tre dichiarazioni duplicate richiedono
|
||||
normalizzazione prima dell'importazione documentale.
|
||||
[Dizionario sorgente](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/shopify001/dbt_packages/shopify_source/models/src_shopify.yml).
|
||||
|
||||
Il progetto aggiunge definizioni di modelli analitici, inclusi ordini, coorti
|
||||
clienti e aggregazioni giornaliere del negozio; il solo `models/shopify.yml`
|
||||
ne dichiara 10. Sono modelli dbt, da tenere distinti dalle 34 sorgenti e dalle
|
||||
tabelle fisiche effettivamente disponibili. Queste definizioni sono un secondo
|
||||
livello di materiale per Evidence su granularità e metriche.
|
||||
[Modelli analitici](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/shopify001/models/shopify.yml).
|
||||
|
||||
Il profilo indica esplicitamente DuckDB, percorso `./shopify.duckdb`, schema
|
||||
`main`. Non è necessario collegare un negozio Shopify reale per leggere il
|
||||
database distribuito dal progetto.
|
||||
[Profilo](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/shopify001/profiles.yml).
|
||||
|
||||
## QuickBooks: contabilità e documenti commerciali
|
||||
|
||||
Le 40 sorgenti dichiarate coprono conti, clienti, fornitori, fatture e righe,
|
||||
pagamenti, depositi, acquisti, ordini, note di credito, trasferimenti e
|
||||
registrazioni contabili. Il dizionario definisce classificazioni dei conti e
|
||||
tipi delle righe fattura, distinguendo elementi di vendita, descrizione,
|
||||
sconto e subtotale.
|
||||
[Dizionario sorgente](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/quickbooks001/dbt_packages/quickbooks_source/models/src_quickbooks.yml).
|
||||
|
||||
La documentazione del libro mastro contiene una regola esplicita utile come
|
||||
Evidence: l'importo aumenta il conto quando il tipo di movimento corrisponde
|
||||
al lato di incremento del conto, e lo diminuisce altrimenti. Definisce inoltre
|
||||
importi convertiti e saldi progressivi. `models/quickbooks.yml` dichiara 29
|
||||
modelli tra intermedi e analitici: non sono 29 ulteriori tabelle sorgente
|
||||
garantite. I due file di documentazione contengono complessivamente 120 blocchi
|
||||
`docs` (68 nel progetto, 52 nel pacchetto sorgente); anche qui sono definizioni
|
||||
da selezionare e curare, non 120 Evidence Unit già validate.
|
||||
[Modelli e regole contabili](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/quickbooks001/models/quickbooks.yml),
|
||||
[glossario progetto](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/quickbooks001/models/docs.md),
|
||||
[glossario sorgente](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/quickbooks001/dbt_packages/quickbooks_source/models/docs.md).
|
||||
|
||||
Il profilo usa `./quickbooks.duckdb`.
|
||||
[Profilo](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/quickbooks001/profiles.yml).
|
||||
|
||||
## Workday: personale, ruoli e storia organizzativa
|
||||
|
||||
Le sorgenti documentate comprendono lavoratori, posizioni, famiglie
|
||||
professionali, organizzazioni, assegnazioni e diverse tabelle storiche.
|
||||
Il glossario contiene 409 blocchi `docs`; molti sono definizioni brevi di
|
||||
attributi, non regole articolate. Fra i concetti documentati figurano FTE
|
||||
retribuito e lavorato, stato attivo/cessato, compensi, date di assunzione e
|
||||
appartenenze organizzative. La complessità temporale e organizzativa è
|
||||
interessante, ma il glossario da solo non giustifica chiamarlo il candidato
|
||||
con più Evidence di qualità.
|
||||
[Sorgenti](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/workday001/models/staging/src_workday.yml),
|
||||
[glossario](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/workday001/models/docs.md).
|
||||
|
||||
Il profilo usa `./workday.duckdb`.
|
||||
[Profilo](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/examples/workday001/profiles.yml).
|
||||
|
||||
## Download e prossimo controllo prima della scelta definitiva
|
||||
|
||||
Il README ufficiale fornisce due download Google Drive. Lo script di setup
|
||||
attende `DBT_start_db.zip` e `dbt_gold.zip`, estrae i file DuckDB e li distribuisce
|
||||
nei progetti e nella suite di riferimento. Per ThothII va scelto consapevolmente
|
||||
il contenuto da usare come esempio: non occorre importare il meccanismo di
|
||||
valutazione del benchmark. Questa ricerca verifica la pubblicazione del
|
||||
percorso di download e la configurazione locale; **non verifica il download
|
||||
integrale, dimensioni, righe, licenza dei singoli dati o schema fisico**.
|
||||
[README](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/README.md),
|
||||
[setup ufficiale](https://github.com/xlang-ai/Spider2/blob/main/spider2-dbt/setup.py).
|
||||
|
||||
Prima di promettere il pacchetto di installazione occorre scaricare il
|
||||
candidato, confrontare tabelle e colonne reali con la documentazione,
|
||||
verificare copertura delle entità e consistenza dei dati, e scegliere quali
|
||||
definizioni diventino Source Evidence. Per PostgreSQL la conversione proposta
|
||||
è schema esplicito più dati esportati; CSV sarebbe un formato derivato.
|
||||
Vanno preservati tipi numerici, date, valute, valori nulli e contenuti
|
||||
strutturati eventualmente presenti, adattando le sole trasformazioni
|
||||
necessarie. Non è ancora stato implementato o testato alcun convertitore.
|
||||
@@ -0,0 +1,86 @@
|
||||
# Alternative Spider 2.0-Lite per database dimostrativi con Evidence
|
||||
|
||||
Verifica del 27 settembre 2026. Il criterio è complessità del database e qualità
|
||||
della documentazione di dominio da curare in ThothII, non prestazioni sul benchmark
|
||||
né numero di domande pubblicate. Nessun database è stato installato.
|
||||
|
||||
## Metodo e limiti
|
||||
|
||||
Ispezionati DDL, metadati per tabella e documenti ufficiali in
|
||||
[Spider2](https://github.com/xlang-ai/Spider2), revisione osservata
|
||||
`cafb867313aab4e674652054198f383cf4018943`. I conteggi sotto sono delle tabelle
|
||||
dichiarate nei DDL e delle colonne nei JSON, non un'ispezione dei file SQLite.
|
||||
La [procedura ufficiale](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/README.md)
|
||||
offre un archivio dei database locali. I database cloud seguono un percorso diverso.
|
||||
|
||||
## Candidati locali
|
||||
|
||||
| Database | Tabelle / colonne nei metadati | Materiale semantico riscontrato | Valutazione |
|
||||
| --- | --- | --- | --- |
|
||||
| `E_commerce` | 11 / 70 | Documento RFM; documentazione originale Olist da integrare | Il più coerente dei candidati Lite esaminati per una demo aziendale, ma complessità media |
|
||||
| `complex_oracle` | 10 / 140 | Proiezione vendite e conversioni valutarie; dizionario originale Oracle SH da confrontare | Buon caso analitico, meno esteso relazionalmente |
|
||||
| `oracle_sql` | 38 / 124 | Documento sul rapporto vendite/media mobile e finestre temporali | Molte tabelle, documentazione semantica allegata troppo parziale |
|
||||
| `AdventureWorks` | 13 / 120 | Documentazione originale Microsoft, da riallineare al sottoinsieme Spider | Non confondere questo estratto con l'intero AdventureWorks |
|
||||
|
||||
Conteggi ricavati dai DDL e JSON ufficiali: [E_commerce](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite/resource/databases/sqlite/E_commerce),
|
||||
[complex_oracle](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite/resource/databases/sqlite/complex_oracle),
|
||||
[oracle_sql](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite/resource/databases/sqlite/oracle_sql),
|
||||
[AdventureWorks](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite/resource/databases/sqlite/AdventureWorks).
|
||||
In tutti i JSON di questi quattro candidati, gli array `description` controllati
|
||||
sono vuoti: tipi e righe di esempio non costituiscono da soli un dizionario di dominio.
|
||||
|
||||
### E_commerce
|
||||
|
||||
Comprende ordini, righe d'ordine, pagamenti, recensioni, prodotti, clienti, venditori,
|
||||
geolocalizzazione e lead. Il [documento RFM](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/RFM.md)
|
||||
definisce recency, frequency, monetary e undici segmenti con regole di assegnazione.
|
||||
Sono fonti concrete di formule e regole, da rivedere e collegare allo schema.
|
||||
|
||||
La [fonte originale Olist](https://www.kaggle.com/olistbr/brazilian-ecommerce/metadata)
|
||||
fornisce CSV e spiega una distinzione utile: `customer_id` identifica il cliente
|
||||
nel contesto dell'ordine, mentre `customer_unique_id` permette di riconoscere acquisti
|
||||
ripetuti della stessa persona. La distribuzione Olist di base contiene nove file;
|
||||
non equivale automaticamente alle undici tabelle Spider, che includono i lead.
|
||||
|
||||
### complex_oracle
|
||||
|
||||
Il [documento allegato](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/projection_calculation.md)
|
||||
descrive proiezione mensile delle vendite, crescita rispetto all'anno precedente,
|
||||
conversione in USD e gestione di cambi mancanti. Lo schema ha vendite e costi con
|
||||
dimensioni prodotto, cliente, calendario, canale, promozione e geografia.
|
||||
|
||||
Nomi e struttura sono riconducibili al [Sales History di Oracle](https://github.com/oracle-samples/db-sample-schemas/tree/main/sales_history).
|
||||
Il suo script `sh_create.sql` contiene 88 commenti `COMMENT ON TABLE/COLUMN` e la
|
||||
distribuzione comprende CSV. È materiale aggiuntivo utile, ma ogni corrispondenza
|
||||
con lo schema Spider, incluse estensioni come `currency`, va verificata: non si
|
||||
deve importare la documentazione dell'originale come se descrivesse automaticamente
|
||||
ogni adattamento Spider.
|
||||
|
||||
### oracle_sql
|
||||
|
||||
Le tabelle coprono magazzino, ordini, confezioni annidate, vendite mensili e altri
|
||||
sottodomini eterogenei. Il [documento di calcolo](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/calculation_method.md)
|
||||
tratta tre aspetti: rapporto fra vendite e media mobile centrata, finestre di dodici
|
||||
mesi e limiti temporali per evitare effetti ai bordi. Questo non documenta in modo
|
||||
completo le altre parti del database: sconsigliato come scelta basata sulla sola
|
||||
abbondanza di tabelle.
|
||||
|
||||
## Alternativa cloud con documentazione più ricca
|
||||
|
||||
`ga4` offre tre documenti complementari: [dizionario degli eventi](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/ga4_obfuscated_sample_ecommerce.events.md),
|
||||
[dimensioni e metriche](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/ga4_dimensions_and_metrics.md)
|
||||
e [categorie delle pagine](https://github.com/xlang-ai/Spider2/blob/main/spider2-lite/resource/documents/ga4_page_category.md).
|
||||
Coprono campi annidati, classificazione dei canali e regole di interpretazione;
|
||||
sono più vicini al requisito semantico. Tuttavia la
|
||||
[distribuzione Spider è BigQuery](https://github.com/xlang-ai/Spider2/tree/main/spider2-lite/resource/databases/bigquery/ga4):
|
||||
molte tabelle sono partizioni giornaliere dello stesso schema logico. Il conteggio
|
||||
fisico non è una misura utile di complessità relazionale. Esportazione locale e
|
||||
adattamento PostgreSQL sarebbero lavoro aggiuntivo, non un semplice import SQLite.
|
||||
|
||||
## Esito
|
||||
|
||||
Nessuno dei quattro candidati SQLite esaminati combina da solo schema molto esteso
|
||||
e documentazione di dominio completa già pronta. Per cercare una scelta più forte,
|
||||
confrontare con i progetti Spider 2.0-DBT nella ricerca separata
|
||||
`2026-09-27-spider2-dbt-evidence-candidates.md`. I modelli documentati di dbt non
|
||||
vanno confusi con tabelle fisiche già presenti, né le librerie di utility con Evidence.
|
||||
@@ -1,33 +0,0 @@
|
||||
# Prodotti text-to-SQL e natural-language-to-SQL
|
||||
|
||||
Ricognizione di prodotti e siti ufficiali che consentono di interrogare dati strutturati
|
||||
in linguaggio naturale e/o di generare SQL. Sono escluse pubblicazioni accademiche,
|
||||
benchmark e articoli di terze parti. Le descrizioni riportano solo capacità dichiarate
|
||||
nelle fonti ufficiali collegate.
|
||||
|
||||
Data della ricerca: 2026-09-09.
|
||||
|
||||
Nota di verifica: al 2026-09-09 SQLPilot non è stato verificato come raggiungibile. Il fetch
|
||||
del sito ufficiale `https://sqlpilot.ai/` restituisce `502 Bad Gateway`; anche
|
||||
`https://www.sqlpilot.ai/`, `http://sqlpilot.ai/`, `/download` e `/signup` non risultano
|
||||
raggiungibili dal controllo diretto (risoluzione DNS fallita), senza redirect osservabili.
|
||||
La pagina ufficiale indicizzata in precedenza resta una fonte storica, non una conferma di
|
||||
disponibilità odierna. Non è stato individuato un URL ufficiale alternativo funzionante.
|
||||
|
||||
| Prodotto | URL ufficiale | Descrizione verificabile | Modello |
|
||||
|---|---|---|---|
|
||||
| [Vanna AI](https://vanna.ai/) | [Sito](https://vanna.ai/) · [Documentazione](https://vanna.ai/docs/index.html) | Framework/agente SQL che permette agli utenti di porre domande in linguaggio naturale su un database. La documentazione descrive un flusso RAG: si addestra il modello con SQL, DDL e documentazione, poi `ask` genera SQL che può essere eseguito sul database. | Open source; disponibile anche come servizio/soluzione hosted ed enterprise. |
|
||||
| [Wren AI](https://github.com/Canner/WrenAI) | [Repository ufficiale](https://github.com/Canner/WrenAI) · [Documentazione CLI](https://github.com/Canner/WrenAI/blob/main/docs/core/reference/cli.md) | Layer semantico open source per agenti e applicazioni GenBI. Il progetto dichiara supporto a text-to-SQL su oltre 20 sorgenti dati; la CLI conserva coppie natural-language-to-SQL e usa il contesto semantico/MDL per scrivere ed eseguire query. | Open source (licenza Apache-2.0 per il core dichiarato nel repository). |
|
||||
| [Dataherald](https://github.com/Dataherald/dataherald) | [Repository ufficiale](https://github.com/Dataherald/dataherald) | Engine natural-language-to-SQL per domande su dati relazionali. Il repository descrive un’API che espone un database in modo interrogabile in linguaggio naturale e include componenti per engine, API enterprise, console amministrativa e Slackbot. | Open source (Apache-2.0); include componenti enterprise self-hosted. |
|
||||
| [DB-GPT](https://github.com/eosphoros-ai/DB-GPT) | [Repository ufficiale](https://github.com/eosphoros-ai/DB-GPT) · [DB-GPT-Hub](https://github.com/eosphoros-ai/DB-GPT-Hub) | Framework open source per applicazioni data-driven e agenti, con un workflow Text-to-SQL documentato e un progetto Hub per dataset, modelli e fine-tuning dedicati alla conversione testo-SQL. | Open source. |
|
||||
| [Snowflake Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) | [Documentazione ufficiale](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) | Servizio gestito di Snowflake con cui utenti business pongono domande in linguaggio naturale e ricevono risposte senza scrivere SQL. La documentazione lo descrive esplicitamente come sistema agentico che genera risposte text-to-SQL, usando semantic model/views per il contesto. | SaaS/enterprise gestito nella piattaforma Snowflake. |
|
||||
| [Databricks Genie / Genie Agents](https://docs.databricks.com/gcp/en/genie-agents/concepts) | [Documentazione ufficiale](https://docs.databricks.com/gcp/en/genie-agents/concepts) · [API](https://docs.databricks.com/gcp/en/genie-agents/conversation-api) | Funzionalità Databricks per interagire con dati tramite linguaggio naturale. La documentazione dichiara che Genie converte i prompt in SQL, restituisce quando possibile la query generata e i risultati, e può porre domande di chiarimento. | SaaS/enterprise, integrato in Databricks. |
|
||||
| [ThoughtSpot Spotter](https://www.thoughtspot.com/product/spotter-semantics) | [Pagina prodotto ufficiale](https://www.thoughtspot.com/product/spotter-semantics) · [SpotGuide](https://tsa-guide.thoughtspot.com/) | Interfaccia di analytics conversazionale: l’utente descrive ciò che vuole in linguaggio naturale e il motore genera query SQL deterministiche tramite il layer semantico. La guida ufficiale presenta Spotter come esperienza “no SQL” per cercare e interrogare i dati. | SaaS/enterprise analytics. |
|
||||
| [Seek AI](https://www.seek.ai/ai-data-analyst) | [AI Data Analyst](https://www.seek.ai/ai-data-analyst) · [Product Overview](https://www.seek.ai/product-overview) | Piattaforma/agent per dati strutturati con un Dialogue Agent che interpreta domande in linguaggio naturale e un Semantic Parsing Agent che genera query; l’offerta include anche un’interfaccia embedded per prodotti SaaS e un’app nativa Snowflake. | SaaS/enterprise; disponibile anche come componente embedded e Snowflake Native App. |
|
||||
| ~~SQLPilot~~ | [Sito ufficiale](https://sqlpilot.ai/) | **Non verificato al 2026-09-09**: il dominio ufficiale non è risultato raggiungibile (502/DNS) e non è stato trovato un redirect o un URL ufficiale alternativo funzionante. Una precedente indicizzazione ufficiale descriveva un editor SQL assistito da AI, ma non costituisce conferma di disponibilità odierna. | Non verificato. |
|
||||
|
||||
## Note di perimetro
|
||||
|
||||
- “Open source” indica un progetto il cui repository ufficiale dichiara una licenza o un core open source; non implica che eventuali servizi hosted siano gratuiti.
|
||||
- “SaaS/enterprise” indica un prodotto gestito o venduto come piattaforma aziendale; le fonti ufficiali non sempre pubblicano prezzi o dettagli contrattuali.
|
||||
- Le capacità possono dipendere dal database collegato, dal modello semantico configurato e dai permessi dell’installazione.
|
||||
@@ -62,8 +62,9 @@ to the reviewer. A correction can reopen the CTE plan without discarding decisio
|
||||
|
||||
## F8: Memory promotion
|
||||
|
||||
At the end of the session, the system proposes reusable clarifications. The reviewer decides which
|
||||
ones to promote to the global registry, and the session is then finalized.
|
||||
At the end of the session, the system proposes reusable Memory cards, including the approved
|
||||
solved question. The reviewer selects and edits the additions or updates to retain in the
|
||||
workspace's Memory archive, or declines them all. The session is then finalized.
|
||||
|
||||
## Available gates
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ Il comportamento da verificare deriva da:
|
||||
|
||||
- stato corrente del progetto in `PROJECT_STATE.md`;
|
||||
- [contratto Catalog Schema Snapshot](../contracts/catalog-schema-snapshot.md);
|
||||
- [piano del Metadata Catalog](../plans/2026-08-26-metadata-catalog-from-thothai.md);
|
||||
- [specifica della generazione descrizioni](../plans/2026-08-28-ai-catalog-description-generation-spec.md);
|
||||
- [piano del Metadata Catalog](../reports/knowledge-archives-release.md);
|
||||
- [specifica della generazione descrizioni](../reports/knowledge-archives-release.md);
|
||||
- [ADR 0007: sincronizzazione autorevole durevole](../adr/0007-durable-authoritative-schema-synchronization.md);
|
||||
- [ADR 0009: un solo run sequenziale di generazione](../adr/0009-use-one-sequential-description-generation-run.md);
|
||||
- [ADR 0010: campioni reali limitati](../adr/0010-allow-bounded-real-source-samples-for-description-generation.md);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Use and administer Memory
|
||||
|
||||
Memory stores reusable knowledge for a workspace. It is separate from Evidence sources
|
||||
and from the saved documents of an individual session.
|
||||
|
||||
| Card family | Purpose |
|
||||
| --- | --- |
|
||||
| Domain clarification | Define a term or interpretation, with its scope. |
|
||||
| SQL rule | Explain how to construct SQL and why. |
|
||||
| Solved question | Retain an approved question and SQL as a consultative example. |
|
||||
| Explained error | Record a correction and its rationale. |
|
||||
|
||||
## Browse and edit
|
||||
|
||||
Open **Administration → Memory management** and select the workspace. Administration
|
||||
requires the appropriate permissions. You can search, filter, open a card's complete
|
||||
content, edit it, manage its dependencies and links, or explicitly confirm deletion.
|
||||
|
||||
Browsing and editing require the PostgreSQL archive but do not require an active session
|
||||
or a working DWH or search index. Cards retain their identity and origin when edited;
|
||||
there is no editorial revision history. Deleting a card also removes its links and
|
||||
dependencies, not the other cards or the workspace's Evidence.
|
||||
|
||||
Links connect cards in the same workspace. Record scope and physical dependencies
|
||||
carefully so knowledge is not applied to unrelated databases, tables or columns.
|
||||
|
||||
## Saved content and search availability
|
||||
|
||||
Saving a card and updating its search index are different outcomes. **Saved, index update
|
||||
incomplete** means the content is already in the archive but is not ready for recall.
|
||||
Use **Pending index updates** to retry. Do not create a duplicate card to work around an
|
||||
indexing failure. A restart does not discard the pending operation.
|
||||
|
||||
Qdrant is a rebuildable search projection, not the authoritative archive. Rebuilding it
|
||||
does not recover deleted cards from old sessions or vector payloads. Back up the
|
||||
authoritative installation data before maintenance.
|
||||
|
||||
After a successful physical schema synchronization, cards dependent on removed database
|
||||
objects can be deleted. Workspace-wide cards and unrelated dependencies remain. Review
|
||||
the synchronization result and any pending cleanup before starting another synchronization.
|
||||
|
||||
## Memory in a reviewed session
|
||||
|
||||
The workflow proposes relevant clarifications, rules and examples. A search result is
|
||||
not approval: the reviewer decides whether it applies. At the final Memory review,
|
||||
select the additions or updates worth retaining, edit their content and scope, or decline
|
||||
them all. Finalizing a session does not silently approve every proposed card.
|
||||
|
||||
Approved SQL is read-only at that final review. To change the solution, return to SQL
|
||||
review. See the [workflow guide](../skills.md) and [user guide](../guida-utente.md).
|
||||
@@ -80,6 +80,44 @@ async function navigation(page: Page) {
|
||||
if (await trigger.isVisible()) await trigger.click();
|
||||
}
|
||||
|
||||
for (const mode of ["full", "embedded"] as const) {
|
||||
for (const viewport of [{ width: 1280, height: 720 }, { width: 390, height: 844 }]) {
|
||||
test(`catalog configuration scrolls to all fields and actions in ${mode} at ${viewport.width}px`, async ({ page }, testInfo) => {
|
||||
await page.setViewportSize(viewport);
|
||||
const writes = await fixtures(page, mode);
|
||||
await page.route("**/api/catalog/databases", route => route.fulfill({ json: [{
|
||||
workspaceId: workspace, workspaceName: title, workspaceAvailable: true,
|
||||
workspaceRevision: revision, workspaceEvidence: { sourceType: null, state: "not_declared" },
|
||||
runtimeBinding: null, configured: false, engine: "postgres", databaseName: "warehouse",
|
||||
schema: "public", version: 0, createdAt: "", updatedAt: "",
|
||||
binding: { transport: "postgres_direct", port: 5432 }, connectionStatus: "untested",
|
||||
secrets: { password: false, apiKey: false, sshPrivateKey: false,
|
||||
sshPrivateKeyPassphrase: false, sshKnownHosts: false, tlsCa: false },
|
||||
}] }));
|
||||
await page.goto("/?thoth_route=administration/database");
|
||||
await page.getByRole("button", { name: `Configure catalog for ${title}`, exact: true }).click();
|
||||
const form = page.getByRole("region", { name: "Configure catalog form", exact: true });
|
||||
await expect(form).toBeVisible();
|
||||
const scrollArea = page.locator(".thot-fleet-ledger__workspace");
|
||||
const box = await scrollArea.boundingBox();
|
||||
expect(box).not.toBeNull();
|
||||
await page.mouse.move(box!.x + box!.width / 2, box!.y + box!.height - 30);
|
||||
await page.mouse.wheel(0, 3000);
|
||||
await expect(form.getByRole("button", { name: "Save catalog configuration", exact: true })).toBeInViewport();
|
||||
await expect(form.getByLabel("Password", { exact: true })).toBeInViewport();
|
||||
expect(await scrollArea.evaluate(el => el.scrollTop)).toBeGreaterThan(0);
|
||||
expect((await inspect(page)).overflow).toBe(0);
|
||||
await page.screenshot({ path: testInfo.outputPath("catalog-configuration-bottom.png") });
|
||||
await page.mouse.wheel(0, -3000);
|
||||
await expect.poll(() => scrollArea.evaluate(el => el.scrollTop)).toBe(0);
|
||||
await form.getByRole("button", { name: "Back to list", exact: true }).scrollIntoViewIfNeeded();
|
||||
await form.getByRole("button", { name: "Back to list", exact: true }).click();
|
||||
await expect(page.getByRole("button", { name: `Configure catalog for ${title}`, exact: true })).toBeVisible();
|
||||
expect(writes).toEqual([]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function admin(page: Page, name: string) {
|
||||
await navigation(page);
|
||||
const toggle = page.getByRole("button", { name: "Administration", exact: true });
|
||||
|
||||
@@ -31,6 +31,7 @@ export interface SchemaTable {
|
||||
|
||||
export interface WidgetDescriptor {
|
||||
id: string;
|
||||
interaction_language?: string;
|
||||
schema_version?: number;
|
||||
session_id?: string;
|
||||
phase?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useSyncExternalStore } from "react";
|
||||
import { createContext, useCallback, useContext, useSyncExternalStore, type ReactNode } from "react";
|
||||
import { itCore } from "./locales/it-core";
|
||||
import { itAdmin } from "./locales/it-admin";
|
||||
import { itWorkflow } from "./locales/it-workflow";
|
||||
@@ -63,8 +63,18 @@ export function translate(message: string, params?: TranslationParams): string {
|
||||
return translateIn(locale, message, params);
|
||||
}
|
||||
|
||||
const InteractionLocale = createContext<string | undefined>(undefined);
|
||||
|
||||
/** Scope HITL controls to the session language without changing application navigation. */
|
||||
export function InteractionLanguage({ language, children }: { language?: string; children: ReactNode }) {
|
||||
return <InteractionLocale.Provider value={language ? resolveLocale(language) : undefined}>
|
||||
{children}
|
||||
</InteractionLocale.Provider>;
|
||||
}
|
||||
|
||||
export function useI18n() {
|
||||
const current = useSyncExternalStore(subscribe, getLocale, () => "en");
|
||||
const uiLocale = useSyncExternalStore(subscribe, getLocale, () => "en");
|
||||
const current = useContext(InteractionLocale) ?? uiLocale;
|
||||
const t = useCallback(
|
||||
(message: string, params?: TranslationParams) => translateIn(current, message, params),
|
||||
[current],
|
||||
|
||||
@@ -1213,7 +1213,39 @@ test("closing and reopening Model activity preserves the complete activity log",
|
||||
expect(useSessionStore.getState().activityLog).toEqual(beforeClose);
|
||||
});
|
||||
|
||||
test("session finalization shows the completion banner and returns to landing", async () => {
|
||||
test.each(["stop", "session_exit"])("%s restores the empty landing with model activity closed", async (exit) => {
|
||||
const close = vi.fn(() => new HttpResponse(null, { status: 204 }));
|
||||
server.use(
|
||||
http.post("/api/sessions/:id/resume", () => resumeResult("s1")),
|
||||
http.post("/api/sessions/:id/close", close),
|
||||
);
|
||||
wrap(adminUser);
|
||||
await userEvent.click(await screen.findByText("Attiva uno"));
|
||||
await userEvent.click(await screen.findByRole("button", { name: "Resume" }));
|
||||
await userEvent.click(screen.getByRole("button", { name: "Show model activity" }));
|
||||
act(() => useSessionStore.getState().setLastUserEntry({ kind: "input", text: "Previous question" }));
|
||||
expect(screen.getByLabelText("Model activity timeline")).toHaveTextContent("Previous question");
|
||||
const source = FakeEventSource.instances.at(-1)!;
|
||||
|
||||
if (exit === "stop") {
|
||||
await userEvent.click(screen.getByRole("button", { name: /stop and save session/i }));
|
||||
await userEvent.click(screen.getAllByRole("button", { name: "Stop & save" })[0]);
|
||||
} else {
|
||||
act(() => source.emit({ type: "system_event", event: "session_exit" }));
|
||||
}
|
||||
|
||||
expect(await screen.findByText(/type your question/i)).toBeInTheDocument();
|
||||
expect(screen.queryByRole("heading", { name: "Model activity" })).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId("app-shell")).toHaveAttribute("data-activity-layout", "closed");
|
||||
expect(screen.queryByRole("complementary", { name: "Session summary" })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("complementary", { name: "Session navigation" })).toBeVisible();
|
||||
expect(screen.getByRole("textbox", { name: /new question/i })).toHaveValue("");
|
||||
expect(useSessionStore.getState().activityLog).toEqual([]);
|
||||
expect(source.closed).toBe(true);
|
||||
expect(close).toHaveBeenCalledTimes(exit === "stop" ? 1 : 0);
|
||||
});
|
||||
|
||||
test("a new question after finalization restores the landing and administration navigation", async () => {
|
||||
useSessionStore.getState().resetSession();
|
||||
let finalized = false;
|
||||
server.use(
|
||||
@@ -1221,7 +1253,7 @@ test("session finalization shows the completion banner and returns to landing",
|
||||
http.get("/api/sessions", () =>
|
||||
HttpResponse.json(finalized ? [{ ...LIST[0], status: "finalized" }] : LIST)),
|
||||
);
|
||||
wrap();
|
||||
wrap(adminUser);
|
||||
await userEvent.click(await screen.findByText("Attiva uno"));
|
||||
await userEvent.click(await screen.findByRole("button", { name: /resume/i }));
|
||||
// The final turn ends: the session is now finalized on disk and agent_end
|
||||
@@ -1233,9 +1265,18 @@ test("session finalization shows the completion banner and returns to landing",
|
||||
});
|
||||
const cta = await screen.findByRole("button", { name: /start a new question/i });
|
||||
expect(screen.getByText(/session completed and finalized/i)).toBeInTheDocument();
|
||||
await userEvent.click(screen.getByRole("button", { name: /show model activity/i }));
|
||||
expect(screen.getByRole("heading", { name: "Model activity" })).toBeVisible();
|
||||
expect(screen.queryByRole("complementary", { name: "Session navigation" })).not.toBeInTheDocument();
|
||||
await userEvent.click(cta);
|
||||
// Landing state: the composer invites a brand-new question.
|
||||
expect(await screen.findByText(/type your question/i)).toBeInTheDocument();
|
||||
expect(screen.queryByRole("heading", { name: "Model activity" })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/session completed and finalized/i)).not.toBeInTheDocument();
|
||||
const navigation = screen.getByRole("complementary", { name: "Session navigation" });
|
||||
expect(within(navigation).getByRole("button", { name: "Administration" })).toBeVisible();
|
||||
expect(screen.getByRole("textbox", { name: /new question/i })).toHaveValue("");
|
||||
expect(useSessionStore.getState().activityLog).toEqual([]);
|
||||
});
|
||||
|
||||
test("renaming a group reassigns its members via setSessionGroup", async () => {
|
||||
|
||||
@@ -694,6 +694,20 @@ export function AppShell({ canLogout }: AppShellProps) {
|
||||
authGeneration,
|
||||
);
|
||||
|
||||
function resetSessionView() {
|
||||
invalidateResumeIntent();
|
||||
newSessionOperationRef.current = null;
|
||||
resetSession();
|
||||
selectActiveSession(null);
|
||||
// Panel visibility belongs to the shell, outside the session store.
|
||||
// Clear it too so leaving a session restores the initial landing layout.
|
||||
setPanelSession(null);
|
||||
setShowActivity(false);
|
||||
setCreatingSession(false);
|
||||
setAwaitingQuestion(false);
|
||||
setStopConfirm(false);
|
||||
}
|
||||
|
||||
// A backend "session_exit" system event (e.g. the replay server emitting it
|
||||
// when the reviewer picks "Esci") asks us to leave the live session view and
|
||||
// return to the landing state. We deliberately do NOT also POST /close here —
|
||||
@@ -705,10 +719,7 @@ export function AppShell({ canLogout }: AppShellProps) {
|
||||
if (ev === "session_exit") {
|
||||
// Never let a streamed event terminate the managed Pi child. Only the
|
||||
// explicit “Stop & save” action is allowed to call /close.
|
||||
invalidateResumeIntent();
|
||||
resetSession();
|
||||
selectActiveSession(null);
|
||||
setAwaitingQuestion(false);
|
||||
resetSessionView();
|
||||
}
|
||||
// The final workflow turn ends with the session already finalized on disk:
|
||||
// refetch now instead of waiting for the 10s poll, so the completed state
|
||||
@@ -725,15 +736,8 @@ export function AppShell({ canLogout }: AppShellProps) {
|
||||
}
|
||||
if (!canLeaveDatabaseManagement()) return;
|
||||
navigate({ surface: "core" }, true);
|
||||
invalidateResumeIntent();
|
||||
newSessionOperationRef.current = null;
|
||||
resetSession();
|
||||
// Starting a new question closes any open session detail panel: the reader is
|
||||
// moving away from that session, so its left-hand box must not linger.
|
||||
setPanelSession(null);
|
||||
resetSessionView();
|
||||
setAwaitingQuestion(true);
|
||||
setCreatingSession(false);
|
||||
selectActiveSession(null);
|
||||
// Best effort only: session creation keeps the authoritative readiness gate.
|
||||
// Composer focus is deliberately independent of this network request.
|
||||
void prewarmRuntime().catch(() => undefined);
|
||||
@@ -781,9 +785,7 @@ export function AppShell({ canLogout }: AppShellProps) {
|
||||
} finally {
|
||||
if (!isAuthOperationCurrent(guard, { sessionId: id, disposalEpoch: operationEpochRef.current })
|
||||
|| activeSessionIdRef.current !== id) return;
|
||||
resetSession();
|
||||
selectActiveSession(null);
|
||||
setAwaitingQuestion(false);
|
||||
resetSessionView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,3 +23,23 @@ test("gate chrome follows UI locale while model questions and choices remain in
|
||||
expect(screen.getByRole("button", { name: "Salva e procedi" })).toBeInTheDocument();
|
||||
expect(useSessionStore.getState().pendingWidget?.options?.[0].label).toBe("Salva e procedi");
|
||||
});
|
||||
|
||||
test.each([
|
||||
["en", "it", "Save and proceed", "Other — specify"],
|
||||
["it", "en", "Salva e procedi", "Altro: specifica"],
|
||||
])("HITL controls follow question language %s even when the UI locale changes", (language, uiLocale, save, other) => {
|
||||
setLocale(uiLocale);
|
||||
useSessionStore.setState({ pendingWidget: {
|
||||
id: "language-gate", widget: "select", interaction_language: language,
|
||||
title: "Which admission date should be used?",
|
||||
options: [{ id: "approve", label: "Save and proceed", label_i18n: "Save and proceed" }],
|
||||
reserved: ["back", "exit", "other"],
|
||||
} });
|
||||
render(<WidgetHost sessionId="s1" />);
|
||||
expect(screen.getByRole("button", { name: save })).toBeVisible();
|
||||
expect(screen.getByRole("button", { name: other })).toBeVisible();
|
||||
act(() => setLocale(language));
|
||||
act(() => setLocale(uiLocale));
|
||||
expect(screen.getByRole("button", { name: other })).toBeVisible();
|
||||
expect(screen.getByText("Which admission date should be used?")).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useI18n } from "../i18n";
|
||||
import { InteractionLanguage, useI18n } from "../i18n";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useSessionStore } from "../store/sessionStore";
|
||||
import { resolve } from "../widgets";
|
||||
@@ -9,6 +9,13 @@ import { captureAuthOperation, isAuthOperationCurrent } from "../auth/authOperat
|
||||
import { localizeWidget } from "../widgets/localize";
|
||||
|
||||
export function WidgetHost({ sessionId }: { sessionId: string | null }) {
|
||||
const language = useSessionStore((s) => s.pendingWidget?.interaction_language);
|
||||
return <InteractionLanguage language={language}>
|
||||
<SessionWidgetHost sessionId={sessionId} />
|
||||
</InteractionLanguage>;
|
||||
}
|
||||
|
||||
function SessionWidgetHost({ sessionId }: { sessionId: string | null }) {
|
||||
const { t: translate } = useI18n();
|
||||
const source = useSessionStore((s) => s.pendingWidget);
|
||||
const pending = source ? localizeWidget(source, translate) : null;
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
background-color: oklch(var(--sidebar));
|
||||
container-name: fleet-workspace;
|
||||
container-type: inline-size;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||
|
||||
// Loaded explicitly by PiEvidenceRestructurer. Keep outside .pi/extensions:
|
||||
// JSON-only output prevents interactive sessions from emitting native tool calls.
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
pi.on("before_provider_request", (event) => {
|
||||
if (typeof event.payload !== "object" || event.payload === null) {
|
||||
@@ -43,6 +43,8 @@ for (const [language, workspaceLanguage, entry, title, yes, no] of [
|
||||
assert.ok(injected.systemPrompt.includes(`interaction_language=${language}`));
|
||||
assert.ok(injected.systemPrompt.includes(`workspace_language=${workspaceLanguage}`));
|
||||
assert.match(injected.systemPrompt, /reviewer questions, explanations, and choices/);
|
||||
const name = new Intl.DisplayNames(["en"], { type: "language" }).of(language);
|
||||
assert.ok(injected.systemPrompt.includes(`artifact explanation in ${name}`));
|
||||
}
|
||||
let widget;
|
||||
ctx.ui.input = async title => {
|
||||
@@ -51,10 +53,19 @@ for (const [language, workspaceLanguage, entry, title, yes, no] of [
|
||||
};
|
||||
await tools.get("reviewer_datamart").def.execute("call", { session: "s1" }, null, null, ctx);
|
||||
assert.equal(widget.title, title);
|
||||
assert.equal(widget.interaction_language, language);
|
||||
assert.equal(widget.title_i18n, "Generate a datamart?");
|
||||
assert.deepEqual(widget.options.map(o => [o.id, o.label]), [
|
||||
["generate", yes], ["skip", no],
|
||||
]);
|
||||
// Pi may supply a new context object for a tool; language must come from
|
||||
// the manifest even for a model-authored select, not just generated chrome.
|
||||
await tools.get("reviewer_select").def.execute("select", {
|
||||
session: "s1", title: "Choose the admission date",
|
||||
options: [{ id: "skip", label: "First admission" }],
|
||||
}, null, null, { ...ctx });
|
||||
assert.equal(widget.interaction_language, language);
|
||||
assert.equal(widget.title, "Choose the admission date");
|
||||
} finally {
|
||||
cp.execFileSync = previous.exec;
|
||||
for (const [key, value] of [["THT_SESSION", previous.session],
|
||||
|
||||
@@ -40,6 +40,8 @@ const CATALOG = {
|
||||
let _handler = null;
|
||||
const _origExecFileSync = cp.execFileSync;
|
||||
cp.execFileSync = function delegatingStub(file, args, opts) {
|
||||
if (args[0] === "session" && args[1] === "ensure-interaction-language")
|
||||
return JSON.stringify({ interaction_language: "en", workspace_language: "it" });
|
||||
if (_handler) return _handler(file, args, opts);
|
||||
return _origExecFileSync.call(cp, file, args, opts);
|
||||
};
|
||||
|
||||
@@ -293,10 +293,14 @@ function sessionLanguage(ctx, sessionId) {
|
||||
}
|
||||
|
||||
function languageContext(manifest) {
|
||||
const name = new Intl.DisplayNames(["en"], { type: "language" }).of(manifest.interaction_language);
|
||||
return "\n\n<session-language>\n" +
|
||||
`interaction_language=${manifest.interaction_language}\n` +
|
||||
`workspace_language=${manifest.workspace_language}\n` +
|
||||
"Use interaction_language for all newly generated reviewer questions, explanations, and choices. " +
|
||||
`Write every reviewer-visible title, intro, option label, rationale and artifact explanation in ${name}. ` +
|
||||
"This language was selected from the original question. Before calling a reviewer tool, " +
|
||||
"check each prose field and rewrite any field in another language into the interaction language. " +
|
||||
"This persisted session setting is authoritative on every turn, including resume and steering. " +
|
||||
"Preserve workspace documents, quoted sources, prior decisions, SQL, identifiers and literal values. " +
|
||||
"Interpret domain terms in workspace_language. Instruction/example language does not change these settings.\n" +
|
||||
@@ -590,9 +594,11 @@ export function isJoinReviewApproval(resp, optionIds) {
|
||||
[...chosen].every((id) => expected.has(id));
|
||||
}
|
||||
|
||||
export async function emitAndWait(ctx, descriptor) {
|
||||
export async function emitAndWait(ctx, descriptor, sessionId) {
|
||||
const language = sessionId ? sessionLanguage(ctx, sessionId).interaction_language : contextLanguages.get(ctx);
|
||||
const localized = language ? { ...descriptor, interaction_language: language } : descriptor;
|
||||
for (;;) {
|
||||
const value = await ctx.ui.input(JSON.stringify(descriptor), "");
|
||||
const value = await ctx.ui.input(JSON.stringify(localized), "");
|
||||
if (value === undefined || value === null) {
|
||||
await reLoop(ctx);
|
||||
continue;
|
||||
@@ -826,7 +832,7 @@ export default function (pi) {
|
||||
return {
|
||||
message: {
|
||||
role: "user",
|
||||
content: [{ type: "text", text: "Esegui ora il workflow richiesto. Non scrivere analisi, spiegazioni o un elenco: usa il tool bash per `tht session show` e, se la sessione e' in Fase 1 senza decisioni, invoca immediatamente reviewer_select. La tua prossima risposta visibile deve essere una tool call." }],
|
||||
content: [{ type: "text", text: "Run the requested workflow now: use bash for `tht session show` and, if the session is in Phase 1 without decisions, immediately call reviewer_select. Your next visible response must be a tool call. Write every reviewer-facing field in the interaction_language specified in <session-language>, including titles, introductions and option labels." }],
|
||||
},
|
||||
systemPrompt:
|
||||
`${event.systemPrompt}\n\n` +
|
||||
@@ -922,7 +928,7 @@ export default function (pi) {
|
||||
ctx, params, `u${Date.now()}`,
|
||||
);
|
||||
if (prepared.result) return prepared.result;
|
||||
const response = await emitAndWait(ctx, prepared.widget);
|
||||
const response = await emitAndWait(ctx, prepared.widget, prepared.session);
|
||||
const outcome = disambiguationGate.resolveClarification(prepared, response);
|
||||
if (outcome.decision) {
|
||||
const err = relayIfThtFails(
|
||||
@@ -1000,7 +1006,7 @@ export default function (pi) {
|
||||
id: option.id, label: option.label, label_i18n: option.label_i18n,
|
||||
})),
|
||||
});
|
||||
const resp = await emitAndWait(ctx, widget);
|
||||
const resp = await emitAndWait(ctx, widget, session);
|
||||
const outcome = resolveSelectOutcome(options, resp);
|
||||
if (outcome.kind === "freetext")
|
||||
return textResult(`Altro (reviewer): ${outcome.text}`);
|
||||
@@ -1102,7 +1108,7 @@ export default function (pi) {
|
||||
});
|
||||
let resp;
|
||||
for (;;) {
|
||||
resp = await emitAndWait(ctx, widget);
|
||||
resp = await emitAndWait(ctx, widget, session);
|
||||
if (resp.control === "freetext" || resp.control === "back" || resp.control === "exit")
|
||||
break;
|
||||
if (!joinOnly || isJoinReviewApproval(resp, meritOptions.map((option) => option.id)))
|
||||
@@ -1243,7 +1249,7 @@ export default function (pi) {
|
||||
title,
|
||||
tables: enriched,
|
||||
});
|
||||
const resp = await emitAndWait(ctx, widget);
|
||||
const resp = await emitAndWait(ctx, widget, session);
|
||||
if (resp.control === "back") return textResult("Il reviewer vuole tornare indietro.");
|
||||
if (resp.control === "exit") return textResult("Il reviewer vuole uscire.");
|
||||
if (resp.control === "freetext")
|
||||
@@ -1494,7 +1500,7 @@ export default function (pi) {
|
||||
});
|
||||
let outcome;
|
||||
for (;;) {
|
||||
const resp = await emitAndWait(ctx, widget);
|
||||
const resp = await emitAndWait(ctx, widget, session);
|
||||
outcome = resolveConfirmOutcome(resp);
|
||||
if (outcome.kind !== "unknown") break;
|
||||
await ctx.ui.notify(gateText(locale, "chooseApproval"), "warning");
|
||||
|
||||