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/v1and 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.jsonandchecksums.jsonfiles; - writes immutable releases atomically beneath
releases/<artifact-build-id>/; - 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.
npm install
npm test
npm run lint
npm run dev
Create a production bundle with:
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 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; andchecksums.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. Repository inventory is explicitly read-only: its mutation and content-scan APIs return
409 E_SOURCE_MANAGEMENT_NOT_WIRED, and the UI disables those actions until inventory feedsBuildInputLoader; see ADR 0001. - 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.
See docs/OPERATIONS.md for snapshot, release, promotion, failure, and rollback procedures.