No description
  • Go 82%
  • templ 7.4%
  • Shell 4.7%
  • TypeScript 4%
  • JavaScript 0.9%
  • Other 0.9%
Find a file
Colja Vendel 16cde87c05
All checks were successful
ci / gates (push) Successful in 13m4s
deploy / build-push-deploy (push) Successful in 4m54s
docs(quick-261002-jch): plan, summary, state
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 14:01:42 +02:00
.bridge chore(bridge): add peer trip (forgeadmin/trip#1) per agent-bridge request #15 c2643 2026-09-30 09:32:55 +02:00
.forgejo/workflows feat(261001-2qd): streak step reads its ConfigMap before and after every branch 2026-10-01 02:13:33 +02:00
.planning docs(quick-261002-jch): plan, summary, state 2026-10-02 14:01:42 +02:00
.toolchain chore(261002-jch): project-local kubeseal 0.40.0 + controller public cert 2026-10-02 13:56:54 +02:00
assets fix(11): stop Tailwind scanning the whole project, incl. untracked planning docs 2026-08-17 12:31:58 +02:00
cmd fix(14): WR-04 stop a non-positive StaleAfter from disabling the staleness check 2026-09-16 02:13:54 +02:00
compliance docs(compliance): compile counsel handoff package for v1.0 launch 2026-07-17 02:45:32 +02:00
db/queries docs(13.1-09): the operator's two verdicts, and §1 stops claiming a signature 2026-09-08 17:14:37 +02:00
deploy feat(261002-jch): seal xi2ix-secrets from the live Secret (GREEN); not applied 2026-10-02 14:00:35 +02:00
e2e feat(260930-i1s): assert-executed.mjs — a farm run is green only if it executed 2026-09-30 13:01:38 +02:00
internal test(261001-ke8): pin model-proposed date + one-word + short-number deflections as accepted trade-off 2026-10-02 01:14:12 +02:00
migrations feat(13.1-02): migration 00013 — testness as a column, backfilled by a conjunction 2026-09-07 11:45:07 +02:00
scripts fix(260929-i0r): reword test message the secrets-scan read as a populated TOKEN assignment 2026-09-29 15:52:17 +02:00
.dockerignore feat(07-04): multi-stage distroless Dockerfile + .dockerignore 2026-06-26 15:34:57 +02:00
.env.example chore(bridge): cut over to agent-bridge -- delete both bash scripts, retire output 2 2026-09-17 10:04:04 +02:00
.gitignore feat(14-02): implement internal/buildinfo link-time identity 2026-09-15 14:30:59 +02:00
CLAUDE.md chore(bridge): cut over to agent-bridge -- delete both bash scripts, retire output 2 2026-09-17 10:04:04 +02:00
docker-compose.yml feat(01-01): scaffold Go module, tooling, bootstrap SQL, and Docker guard 2026-06-19 14:10:27 +02:00
Dockerfile feat(14-02): stamp build identity in the image and pass CI build args 2026-09-15 14:32:49 +02:00
go.mod feat(12-04): GREEN — counselpdf.Render over an embedded IBM Plex Sans TTF 2026-08-19 15:43:00 +02:00
go.sum feat(12-04): GREEN — counselpdf.Render over an embedded IBM Plex Sans TTF 2026-08-19 15:43:00 +02:00
Makefile test(14-07): Playwright acceptance for the admin identity line, local stamped apps 2026-09-15 17:27:15 +02:00
migrations.go feat(01-02): migrations, pgxpool, goose bridge, testcontainers helper 2026-06-19 14:19:02 +02:00
README.md docs(quick-260818-ose): correct the false chi claim — supersede in CLAUDE.md, fix outright in README.md 2026-08-18 18:02:05 +02:00
sqlc.yaml feat(01-01): scaffold Go module, tooling, bootstrap SQL, and Docker guard 2026-06-19 14:10:27 +02:00

xi2ix.com

The corporate website for xi2ix d.o.o., a Croatia-based consultancy founded by Colja Vendel. The site is trilingual — English (primary), German, Croatian — and is engineered first and foremost to radiate unconditional, immediate trust: a "digital business card" built to withstand KYC/due-diligence scrutiny from Croatian banks, authorities, and partners. Its design register is Hanseatic Minimalist — deep blues, slate, generous whitespace, quiet confidence — deliberately free of startup hype or buzzword bingo. The site's centerpiece is Ix, a self-hosted, fact-grounded AI conversational assistant. Ix is not a generic chatbot: it draws out who a visitor is and what they need, is guardrailed to never fabricate company facts, and closes by proposing a warm, pre-drafted handoff to the founder.

Live at xi2ix.com, xi2ix.de, xi2ix.at, and xi2ix.ch (apex + www on each), all served from the same deployment with per-domain locale defaults and valid Let's Encrypt certificates.

Tech stack

  • Go (module xi2ix.com/website, go 1.26) + templ + htmx/SSE — server-rendered, minimal-JS frontend
  • stdlib net/http ServeMux — HTTP routing via Go 1.22+ method-aware patterns and r.PathValue; no third-party router or framework
  • PostgreSQL + pgvector — relational data and AI-grounding retrieval (existing k3s cluster in production; a local Podman container in dev)
  • Ollama, self-hosted — runs the Ix LLM; no external AI API (data sovereignty)
  • go-i18n/v2 — EN/DE/HR translation catalogs
  • Playwright — GUI acceptance tests

See CLAUDE.md for the full stack rationale, version pins, and engineering conventions.

Dev quickstart

Go is installed project-locally — there is no system-wide Go on this project.

# One-time (fresh clone only): download + SHA256-verify the pinned Go toolchain
./.toolchain/install.sh

# Every shell session: activate the project-local toolchain
source .toolchain/env.sh

Containers run on rootless Podman (no Docker daemon). One-time host setup:

systemctl --user enable --now podman.socket

Copy the environment template and fill in the values your local run needs (at minimum OLLAMA_HOST, FORM_SECRET, POSTGRES_PASSWORD, XI2IX_APP_DB_PASSWORD — see the comments in the file for the rest):

cp .env.example .env

Bring up the dev environment and start the server:

make dev-up          # starts Postgres+pgvector, waits for it, bootstraps the
                      # DB role/extension, builds frontend assets (templ + CSS)
go run ./cmd/server   # applies goose migrations at boot, then serves

make dev-up followed by go run ./cmd/server is the documented first-run sequence — make migrate is not part of normal dev flow (the server migrates itself at boot).

Run the tests:

make test              # fast unit tests, no containers required
make test-integration  # full suite, including testcontainers (needs the Podman socket)
make e2e                # Playwright acceptance tests

Repo layout

Path What's there
assets/ Fonts, CSS, and JS — including vendored htmx + htmx-ext-sse and ix.js
cmd/server The main binary: boots, runs migrations, serves the site
cmd/ingest Read-only corpus provenance/validation CLI (no DB/network access)
compliance/ GDPR/DSA/EAA scope memos, breach runbook, retention schedule, DSAR procedure
db/queries Hand-written SQL used to generate type-safe query code (sqlc)
deploy/ Helm chart (deploy/chart), cluster manifests (deploy/cluster), and the deploy/handoff docs (see Deployment below)
e2e/ Playwright TypeScript project — specs, fixtures, playwright.config.ts
internal/ The Go application itself: admin, antispam, brandterms, config, contact, corpus, db, email, i18n, ix (the Ix assistant — conversation, guardrails, SSE handler, handoff), ollama (the Ollama client), pages, repo, routes, server, testsupport, views (templ components)
migrations/ Goose SQL migrations
scripts/ bootstrap.sql, restore-drill.sh, secrets-scan.sh, xss-ssti-scan.sh

Deployment

Deployment is documented separately from this README, with clear ownership boundaries between this project and the surrounding infrastructure ("Umgebungsmanagement"). Start with deploy/RUNBOOK-deploy.md for the deploy procedure itself, and deploy/ENVIRONMENT-HANDOFF.md for the checklist of what a third-party environment owner needs to supply (kubeconfig, DSN, certificate) versus what this project never needs to know (cluster identity, cert/key location, DB topology).

Further reading

  • CLAUDE.md — full engineering conventions, stack rationale, and the AI-assistant-facing workflow rules for this repo.
  • .planning/ — GSD project history and planning artifacts: .planning/STATE.md (current status), .planning/PROJECT.md (requirements/context), .planning/ROADMAP.md (phase roadmap), plus .planning/phases/ and .planning/quick/ for the underlying planning documents.