# Labyricorn Website Engine Control Plane A React control plane and Express backend for resolving Git-owned site inputs and producing deterministic, immutable static website releases. ## Engine capabilities The build engine now: - resolves the site definition and theme to exact 40-character Git commits; - materializes detached snapshots before reading configuration, projects, templates, or assets; - validates the closed `labyricorn-theme/v1` and project schemas without executing repository code; - renders explicit template keys through LiquidJS in strict mode with engine-owned safe-content filters; - copies only declared assets, verified fonts, and configuration-authorized standalone files; - emits deterministic provenance-rich `build-manifest.json` and `checksums.json` files; - writes immutable releases atomically beneath `releases//`; - stages and promotes the same checksum-verified release through atomic pointers; and - serves only a selected release through the preview endpoint, with no synthesized fallback. ## Development Requires Node.js 22 or later. npm is the canonical package manager. CI uses `npm ci` and `package-lock.json`; other lockfiles are intentionally unsupported. ```bash npm install npm test npm run lint npm run dev ``` Create a production bundle with: ```bash npm run build npm start ``` The development server listens on port `3000` by default. In the current production deployment, the Node service listens privately on `127.0.0.1:3001`; Nginx exposes the control plane on port 80 and the active rendered release on port 3000. Gitea discovery is disabled until `GITEA_BASE_URL`, `GITEA_ALLOWED_ORIGINS`, and a read-only `GITEA_TOKEN` are configured. Discovery uses authenticated HTTPS requests with an abort deadline and per-client rate limiting. Git connectivity endpoints accept only configured hosts or local repositories under `GIT_ALLOWED_LOCAL_ROOTS`; they invoke Git without a shell. The deterministic renderer has no AI SDK dependency and does not accept model output as a release input. ## Operations See [Website Engine Operations](docs/OPERATIONS.md) for the verified private-network topology, deployment procedure, service checks, key fingerprints, credential-handling rules, and recovery guidance. The operations document intentionally contains no passwords, tokens, or private-key material. ## Build artifacts By default, releases are written to the platform temporary directory under `labyricorn-builds/`. Set `LABYRICORN_BUILD_ROOT` to use a persistent release directory in production. Each successful release contains: - theme-rendered route directories with `index.html`; - declared static assets and standalone publications; - `404.html`; - `build-manifest.json`; and - `checksums.json`. Validation failures produce a failed build record but never publish a partial release directory. Configuration and theme state are Git-owned and read-only in control-plane v1. `PUT /api/site-config` returns `405 E_CONFIG_READ_ONLY`. ## Current boundaries - Theme packages are presentation data only; Node, shell, WASM, package-manager scripts, custom Liquid tags, and custom filters are not executed. - The reference loader resolves the configured site-definition repository and supports separately pinned source snapshots through the typed boundary; source-management UX remains follow-up work governed by [ADR 0001](.pandaos/adrs/0001-git-source-management-boundary.md). - Remote rsync deployment is not implemented. Push and connection-test endpoints fail closed with HTTP 501, and no configuration field can enable execution; see [ADR 0002](.pandaos/adrs/0002-remote-publication-not-implemented.md). See [docs/OPERATIONS.md](docs/OPERATIONS.md) for snapshot, release, promotion, failure, and rollback procedures.