Compare commits

..
5 changed files with 275 additions and 3 deletions
+14 -3
View File
@@ -16,8 +16,13 @@ and invariants are in [AGENTS.md](AGENTS.md); prior snapshots remain in Git.
bindings. Ticket #45 adds host `installation preflight` and `installation plan`
with release/image checks, canonical external diagnostics and private input seals;
see [the preflight reference](docs/install/installation-preflight.md).
The remainder of the installation tickets,
Docker Hub publication and example databases remain pending.
Ticket #46 adds the maintainer release producer and the first public
[Linux amd64 prerelease](https://git.tylconsulting.it/mptyl/ThothII/releases/tag/installation-v0.1.0-install-preview.1),
with Docker Hub core/frontend images and a downloadable native operator bundle.
See [publication instructions](docs/install/publishing-images.md) and
[verification evidence](docs/reports/2026-09-28-installation-prerelease.md).
Non-interactive execution (#47 onward), real-host acceptance and example
databases remain pending; the prerelease does not certify a complete installer.
- React supports full/embedded rendering independently of local/OIDC/upstream auth,
with EN/IT UI and immutable session interaction language. See
@@ -80,6 +85,12 @@ A later deployment does not prove every earlier acceptance item passed.
## Remaining acceptance and design gates
- The first installation acceptance uses an ad hoc
[Chinook workspace without Evidence](docs/testing/chinook-installation-smoke.md),
backed by a separate local PostgreSQL test container. Its fixture import,
read-only credentials and offline workspace validation were verified; full
installation/readiness and a human-reviewed question remain pending. Evidence
acceptance and the three curated examples are separate later work.
- 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
@@ -98,7 +109,7 @@ A later deployment does not prove every earlier acceptance item passed.
## Documentation maintenance
MkDocs publishes only 20 product/operator pages and five approved assets.
MkDocs publishes only 22 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.
+10
View File
@@ -11,6 +11,12 @@ Prerequisiti del manutentore: Git, Node 24/npm, Go indicato in `tools/tht/go.mod
Docker con Buildx e capacità di eseguire Linux amd64, `tar`. Bun viene installato
dal lock npm e serve soltanto per compilare il pacchetto. Il commit da pubblicare
deve essere già disponibile sul repository Gitea pubblico.
Eseguire il produttore su Linux, WSL2 o macOS; la shell Windows nativa non è supportata.
La prima [prerelease Linux amd64](https://git.tylconsulting.it/mptyl/ThothII/releases/tag/installation-v0.1.0-install-preview.1)
è disponibile: `0.1.0-install-preview.1`, con immagini pubbliche
[core](https://hub.docker.com/r/tylconsulting/thothii-core) e
[frontend](https://hub.docker.com/r/tylconsulting/thothii-frontend).
1. Eseguire `docker login` sul computer di pubblicazione con un account autorizzato
a creare repository pubblici e pubblicare immagini nel namespace scelto.
@@ -66,6 +72,10 @@ Bun for producer builds only. Push the selected source commit to the public Gite
repository before publication. Use Docker's credential store for `docker login`
and Git's credential helper for Gitea release/attachment permissions. Never pass
tokens as command arguments or include them in a checkout or archive.
Run the producer on Linux, WSL2 or macOS, not a native Windows shell.
The first [Linux amd64 prerelease](https://git.tylconsulting.it/mptyl/ThothII/releases/tag/installation-v0.1.0-install-preview.1)
is available as `0.1.0-install-preview.1`, with public Docker Hub core/frontend images.
From `backend`, run `npm ci`, then the command above with an explicit revision,
version, namespace, platforms and a new private output directory. A temporary Git
@@ -0,0 +1,74 @@
# First installation prerelease — ticket #46
Date: 2026-09-28. Source: `ec0421e9fd47176f4883a4e9b4054d5c2a3ad2b8`.
Branch: `codex/guided-standalone-install`. Platform: **linux/amd64**.
## Public artifacts
- [Gitea prerelease and downloads](https://git.tylconsulting.it/mptyl/ThothII/releases/tag/installation-v0.1.0-install-preview.1)
- [Docker Hub core](https://hub.docker.com/r/tylconsulting/thothii-core)
- [Docker Hub frontend](https://hub.docker.com/r/tylconsulting/thothii-frontend)
- Image version: `0.1.0-install-preview.1`.
- Git tag: `installation-v0.1.0-install-preview.1`.
The release was created as a draft, then made public only after image pulls,
smoke tests and uploaded attachment checks passed. Docker and Git credential
stores supplied publisher authentication; no token is present in this report,
the source worktree or the release bundle.
Archive: `thothii-0.1.0-install-preview.1-linux-amd64.tar.gz` (40,926,764 bytes).
SHA-256: `4c130276a265c3c66249abb39e3c1cf02b8603efc00a06985d91385bd8112fff`.
`SHA256SUMS.txt` is the second release attachment.
The archive contains native `tht` and its sibling workspace/document validator,
the release manifest, Compose files, initialization scripts/SQL and IT/EN guides.
There is no application checkout, user workspace, environment credential file,
example database or embedded compiler dependency on the consumer host.
## Immutable image references
All references use `docker.io/` and SHA-256 platform manifests:
| Role | Repository | Digest |
| --- | --- | --- |
| Core, Catalog migration, workspace maintenance | `tylconsulting/thothii-core` | `7ac0b3362c93837c02d9f8d3153d3ab3441cc43594ee7786dafc845a69d5c956` |
| Frontend | `tylconsulting/thothii-frontend` | `2f2b5426a96687702c1f2574c547ea1d1c339419dae05382e83f3706eec6a582` |
| Catalog | `library/postgres` | `45cd22f8d32e189d245403954882f88e7a8714301fda80dab6da90f1265b25a3` |
| Qdrant | `qdrant/qdrant` | `da65a06bc75e42702f80c992b99c5144b0fbd675ae7a96d2991de0bf957b7071` |
| Embedding and model initialization | `ollama/ollama` | `67366844c1f0ed498888b8ee804f629d47ff22a4b559d76154154249bff0dd44` |
## Verification
- Backend: 111 test files passed; 1,422 tests passed, 41 skipped. Typecheck passed.
- Producer: seven tests passed, covering real-source packaging, interrupted
preparation, immutable published retries, registry digest/platform verification,
redirect credential isolation, conflicting Git tags and subprocess timeouts.
- Strict MkDocs build passed with 22 allowed public pages.
- Both images built from the detached source commit and pushed successfully.
- All five image roles pulled by digest using an empty Docker client configuration.
- Network-isolated core checks: embedded Pi version, workflow CLI, migration and
workspace-maintenance assets. Frontend configuration smoke passed.
- Packaged Compose rendered without a source checkout or installation credentials.
- Gitea attachment bytes matched local checksums before and after publication;
the public download checks used no authentication. Git tag matched source SHA.
- Re-running the identical publication command after completion succeeded through
the existing-release path, verifying images and public attachments without
rebuilding, uploading replacement files or republishing the release.
- In a network-isolated Linux amd64 PostgreSQL container, the downloaded-format
bundle reported the correct release/commit and successfully performed
`workspace prepare`, `workspace validate` and `installation prepare`. Those
commands used the two bundled executables mounted read-only; no application
checkout, Node, Bun or Python was mounted into the consumer container.
## Remaining acceptance
This is an image and tooling prerelease. It includes document preparation,
validation, preflight and planning delivered by #43–45. It does not yet implement
the full non-interactive execution, binding import, workspace readiness or recovery
increments. Example databases remain deferred independently.
The publisher ran on macOS with Linux amd64 container execution. This is not the
manual Windows/WSL2 installation gate. That gate follows integration of the
remaining installer tickets and requires a newly published integrated release,
real DWH/model endpoints, one human-reviewed question and persistence checks.
Omarchy and macOS acceptance follow Windows in separate steps.
+112
View File
@@ -0,0 +1,112 @@
# First installation acceptance fixture: Chinook without Evidence
Decision agreed on 2026-09-28: the first installer acceptance may use one ad hoc
workspace and a downloadable local database without Evidence. The three curated
example databases remain a separate deferred subproject.
Use [Chinook v1.4.5](https://github.com/lerocha/chinook-database/releases/tag/v1.4.5),
the sample digital music store. The upstream PostgreSQL SQL asset contains both
schema and data: 11 related tables for artists, albums, tracks, customers, employees,
invoices and playlists. The source is licensed under
[MIT](https://github.com/lerocha/chinook-database/blob/master/LICENSE.md).
This fixture does not supply Evidence or claim that SQL schema information is Evidence.
It uses native PostgreSQL DDL/data, so SQLite type conversion is not involved.
## Prepare the independent test database
Run in Ubuntu WSL2 with Docker Desktop integration, or in a Linux/macOS Bash
terminal for a preliminary check. Docker, curl and OpenSSL must be available.
The first formal host acceptance remains Windows/WSL2.
The helper below is in the ThothII repository for maintainers/testers; it is not
yet included in the downloadable operator bundle. It provisions only the test DWH,
which is a separate container from the installation's PostgreSQL Metadata Catalog.
```bash
cd /path/to/ThothII
bash scripts/prepare-chinook-test.sh "$HOME/thothii-chinook-test"
```
Use a new directory outside any workspace repository. The helper pins the upstream
SQL version and checksum, creates private random passwords, starts PostgreSQL,
imports schema/data, and creates `thoth_reader` with SELECT privileges. Passwords
remain in the private directory, not in a workspace YAML or this repository.
An existing directory or container is refused; the helper never resets it.
An interrupted preparation leaves its private logs/container available for diagnosis.
Do not rerun the upstream import manually against another database: its opening
statements drop and recreate `chinook`.
Default container: `thothii-test-chinook`. Host endpoint: `127.0.0.1:55432`.
Override names/port before the command if needed:
```bash
CHINOOK_TEST_CONTAINER=my-chinook CHINOOK_TEST_PORT=55433 \
bash scripts/prepare-chinook-test.sh "$HOME/my-chinook-test"
```
Expected import counts: 11 tables, 3,503 tracks, 412 invoices and 2,240 invoice lines.
The SQL download is 600,200 bytes. Its SHA-256 is
`e3fde5c1a5b51a2a91429a702c9ca6e69ba56e6c7f5e112724d70c3d03db695e`.
Stop/start retains the database:
```bash
docker stop thothii-test-chinook
docker start thothii-test-chinook
```
Only when deliberately discarding this test database, `docker rm -f -v
thothii-test-chinook` removes the container and its anonymous data volume. Private
files in the preparation directory are separate and remain until removed explicitly.
## Prepare the workspace documents
Using the native bundle, keep `tht` beside `tht-workspace-documents` and run:
```bash
/path/to/bundle/bin/tht workspace prepare \
--directory "$HOME/thothii-workspaces-test" \
--id chinook-test --name "Chinook installation test" --language it
/path/to/bundle/bin/tht workspace validate \
--directory "$HOME/thothii-workspaces-test"
```
The generated workspace has Evidence absent. Keep that configuration; no fake
Evidence document or credential should be added merely to satisfy installation.
The later installation-local binding must select PostgreSQL, database `chinook`,
schema `public`, user `thoth_reader`, and reference the private `reader-password`
file. Do not use the PostgreSQL administrator as the ThothII data source account.
The host endpoint above is for host-side tools: `127.0.0.1` inside ThothII core
would refer to core itself. At integration, configure and verify connectivity from
both the preflight process and the core container; do not copy the host endpoint
unchanged into a runtime binding. That integration belongs to the remaining
installer/binding tickets and is not established by successful import here.
## Acceptance scope
After the remaining installer increments are available, verify prepared documents,
non-interactive setup using published images, database connection, schema sync,
required preprocessing/readiness and a real human-reviewed question. Then verify
stop/start preserves application state. These checks do not validate Evidence
ingestion, retrieval or interpretation; record those as not exercised for this fixture.
Suggested practice questions, without target SQL:
- Which five artists have the most tracks in the catalogue?
- Which countries have the largest total invoice amounts?
- Which customers bought tracks from more than three genres?
These are practice prompts, not benchmark scores or a substitute for human review.
Windows/WSL2 acceptance is followed by Omarchy and macOS in separate steps.
## Preliminary verification, 2026-09-28
The helper imported the pinned SQL into a fresh Linux amd64 PostgreSQL container
on the macOS development host. Counts matched the values above. A real TCP
connection using the generated `thoth_reader` password read the data;
`default_transaction_read_only` was `on`, and an UPDATE without matching rows
was still rejected with SQLSTATE `42501` even inside `BEGIN READ WRITE`.
Native workspace preparation and JSON validation reported `ok: true` and
`evidence: absent`, explicitly deferring Catalog binding, connectivity and runtime
preprocessing. These are fixture checks, not Windows or full-installer acceptance.
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Disposable acceptance fixture, separate from the ThothII Metadata Catalog.
set -euo pipefail
umask 077
if [[ $# -ne 1 || "$1" != /* || -e "$1" ]]; then
echo 'Usage: bash scripts/prepare-chinook-test.sh /absolute/NEW-private-directory' >&2
exit 2
fi
test_dir="$1"
container="${CHINOOK_TEST_CONTAINER:-thothii-test-chinook}"
port="${CHINOOK_TEST_PORT:-55432}"
[[ "$container" =~ ^[a-zA-Z0-9][a-zA-Z0-9_.-]+$ ]] || exit 2
[[ "$port" =~ ^[1-9][0-9]{0,4}$ ]] && (( port <= 65535 )) || exit 2
for executable in docker curl openssl; do command -v "$executable" >/dev/null; done
docker info >/dev/null
if docker container inspect "$container" >/dev/null 2>&1; then
echo "Container $container already exists; this command never resets an existing database." >&2
exit 2
fi
mkdir "$test_dir"
test_dir="$(cd "$test_dir" && pwd -P)"
sql="$test_dir/Chinook_PostgreSql.sql"
curl --fail --location --proto '=https' --tlsv1.2 --max-time 120 \
'https://github.com/lerocha/chinook-database/releases/download/v1.4.5/Chinook_PostgreSql.sql' \
--output "$sql"
expected=e3fde5c1a5b51a2a91429a702c9ca6e69ba56e6c7f5e112724d70c3d03db695e
actual="$(openssl dgst -sha256 "$sql")"
[[ "${actual##* }" == "$expected" ]] || { echo 'Chinook checksum mismatch.' >&2; exit 1; }
openssl rand -hex 24 > "$test_dir/reader-password"
printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)" > "$test_dir/postgres.env"
printf '%s\n' "$container" > "$test_dir/container-name"
# Use the same PostgreSQL linux/amd64 image as the initial installation prerelease.
# PostgreSQL gets its own anonymous data volume; stop/start preserves it.
docker run --detach --name "$container" --platform linux/amd64 \
--publish "127.0.0.1:${port}:5432" \
--env-file "$test_dir/postgres.env" \
docker.io/library/postgres@sha256:45cd22f8d32e189d245403954882f88e7a8714301fda80dab6da90f1265b25a3 >/dev/null
ready=false
for ((attempt = 0; attempt < 90; attempt++)); do
# The entrypoint's temporary bootstrap server has only a Unix socket.
if docker exec "$container" pg_isready -h 127.0.0.1 -U postgres -d postgres >/dev/null 2>&1; then
ready=true
break
fi
sleep 1
done
[[ "$ready" == true ]] || { echo "PostgreSQL did not start. Inspect docker logs $container." >&2; exit 1; }
# The upstream script drops/recreates chinook: it is used only in this NEW container.
docker exec -i "$container" psql -X -U postgres -d postgres -v ON_ERROR_STOP=1 < "$sql" > "$test_dir/import.log" 2>&1
{
printf "CREATE ROLE thoth_reader LOGIN PASSWORD '%s';\n" "$(cat "$test_dir/reader-password")"
cat <<'SQL'
GRANT CONNECT ON DATABASE chinook TO thoth_reader;
GRANT USAGE ON SCHEMA public TO thoth_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO thoth_reader;
ALTER ROLE thoth_reader SET default_transaction_read_only = on;
SQL
} | docker exec -i "$container" psql -X -U postgres -d chinook -v ON_ERROR_STOP=1 > "$test_dir/reader-setup.log" 2>&1
docker exec "$container" psql -X -U postgres -d chinook -v ON_ERROR_STOP=1 -c \
"SELECT (SELECT count(*) FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE') AS tables, (SELECT count(*) FROM track) AS tracks, (SELECT count(*) FROM invoice) AS invoices, (SELECT count(*) FROM invoice_line) AS invoice_lines;"
printf '\nReady: container=%s, host=127.0.0.1, port=%s, database=chinook, schema=public, user=thoth_reader\n' "$container" "$port"
printf 'Protected password file: %s/reader-password\n' "$test_dir"
printf 'Use this read-only account for ThothII. Evidence is absent. No ThothII stack was started.\n'