Commit Graph

4 Commits (265136fc42c49fe17273616332b4f297a24b098b)

Author SHA1 Message Date
boban a6176341e2 fix(security): keep internal IPs out of shipped code and docs/ out of the public image
Audit leak-hygiene findings:
- The operator's real internal dev-VM/WireGuard IPs (10.10.90.136/.162/.165) were shipped in
  vite.config.js (hmr.host), lang hint/placeholder strings, a code comment and the CHANGELOG.
  vite HMR host is now env-driven (VITE_HMR_HOST, dev .env only); all other occurrences are replaced
  with RFC5737 documentation addresses (203.0.113.x). Tests updated in lockstep.
- docs/ is export-ignored from the git tree and named in promote.sh's refuse-to-publish list, but was
  never .dockerignore'd, so `COPY . .` baked the private docs (with private host/URL refs) into the
  public image, which the git-tree leak-guard never inspects. Added docs/ (and art/) to .dockerignore.
- /update.log (new repo-root update transcript) gitignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 10:25:10 +02:00
boban 10486672a5 ci: build+push prod images, gated auto-promote to public
Backbone sub-project #1, CI half (verified with actionlint; the runtime proof is
the first rc/stable tag push — these jobs cannot run locally).

- ci-staging.yml:
  - new `images` job (needs: test): buildx builds clusev-app (Dockerfile) +
    clusev-terminal (docker/terminal/Dockerfile) → private GHCR, tagged by
    version; then a framework smoke-boot (`php artisan route:list`) so a class
    stripped by export-ignore that is still reachable on boot fails before promote.
  - `deploy-staging` widened to any tag; pulls the CI-built private image
    (CLUSEV_IMAGE/CLUSEV_TERMINAL_IMAGE + CLUSEV_PULL=1) instead of building.
  - new gated `promote` job (needs: [test, images], if success + stable vX.Y.Z,
    no -rc): copy the exact image digests to the public GHCR, run promote.sh
    (leak-guard + export-ignore tree), write release-images.lock, push code+tag.
- promote-public.yml: repurposed as a guarded manual fallback mirroring the auto
  promote (image copy + lock + guard). Dropped the "beta channel" naming.
- promote-stable.yml: removed (no beta→stable step in a single-channel model).

Deploy inputs are GitHub vars/secrets (GHCR_OWNER, PUBLIC_GHCR_OWNER,
PUBLIC_REPO_SLUG, STAGING_*, GHCR_TOKEN, PUBLIC_REPO_TOKEN, PROMOTE_FORBIDDEN) —
never hardcoded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 20:34:00 +02:00
boban 176b132da9 chore(release): remove every 'gitea' reference from the public tree (comments, test fake-host, redundant ignore)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 19:54:20 +02:00
boban 53f7309c0b feat: scaffold — Dockerized Laravel 13 + Livewire 3 + Tailwind 4 + Reverb
Working dev stack on :80 (Freigabe step 5: app boots, page renders, Vite HMR runs):
- Multi-stage Dockerfile (php8.3-fpm + nginx + supervisor + node). Dev runs
  php-fpm + nginx + vite in ONE app container; prod target bakes vendor + assets.
- docker-compose.yml (dev, bind-mount) + docker-compose.prod.yml (GHCR image).
  Env-driven ports/UID (APP_PORT, VITE_PORT, REVERB_HOST_PORT, DB_PORT,
  HOST_UID/HOST_GID) — nothing hardcoded. MariaDB only on 127.0.0.1:3306.
- Laravel 13, Livewire 3.8 (class-based, no Volt), wire-elements/modal 2,
  phpseclib 3, laravel/reverb 1. composer platform pinned to php 8.3.
- Tailwind v4 @theme tokens ("Tactical Terminal") in app.css; Vite remote HMR
  (host 0.0.0.0, hmr.host 10.10.90.136).
- Dashboard as a full-page Livewire route (/) in layouts/app; §5 folder skeleton.
- Docs: rules.md R1-R11 (incl. R11 UUID-in-URLs) + CLAUDE.md updated for
  Laravel 13, clusev/ root, port 80, vite-in-app, env-driven config.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 00:31:50 +02:00