## Summary Closes #818. Sets up the prevention layer so newly-published advisories are caught on a branch we own, not on a contributor's PR. **What changed:** - `renovate.json` — migrated 2 deprecated keys (`matchPackagePatterns` → `matchPackageNames`, `matchPaths` → `matchFileNames`); added `osvVulnerabilityAlerts`, `dependencyDashboard`, `vulnerabilityAlerts` (labels: security + P1-high), weekly routine `schedule`, and `lockFileMaintenance` (no automerge) - `.gitea/workflows/renovate.yml` — **new** daily cron runner (`0 3 * * *`), pinned to `renovatebot/github-action@8217b3fc` (v46.1.15) with `renovate-version: "46.1.15"`, `RENOVATE_TOKEN` secret, Gitea platform/endpoint env vars - `.gitea/workflows/nightly.yml` — added `npm-audit` job (parallel to `deploy-staging`, independent signal): shell self-test, `set +e` audit capture, jq-built deduped issue open/update, `NIGHTLY_AUDIT_TOKEN` via step env only, heartbeat on clean path - `docs/adr/041-renovate-runner-setup.md` — **new** negative-space ADR (no auto GITEA_TOKEN, two-token rationale, OSV-vs-platform, digest-pin threat model, schedule-batches-routine-only, l2-containers omission) - `docs/infrastructure/ci-gitea.md` — two-token model, PAT rotation cadence, OSV-vs-platform, nightly/PR-gate divergence table, runbook for nightly-opened issues - `docs/infrastructure/self-hosted-catalogue.md` — fixed Renovate snippet (daily cron, digest pin, `RENOVATE_TOKEN`, fixed version, no root `automerge: true`) **No `l2-containers.puml` entry** — Renovate is a scheduled CI job, not a long-lived container. Stated here as a decision, not an oversight (ADR-041). ## Manual steps required before the runner is live (not automated) 1. Create a dedicated bot account (e.g. `renovate-bot`) on the Gitea instance 2. Mint `RENOVATE_TOKEN` PAT (scopes: `contents` + `pull_request` + `issues`) → add as Gitea secret 3. Mint `NIGHTLY_AUDIT_TOKEN` PAT (scope: `issues` only) → add as Gitea secret 4. Configure `main` branch protection to forbid the bot pushing directly ## Acceptance criteria status - [x] `renovate.json` deprecated keys migrated; vuln surfacing config enabled - [x] `.gitea/workflows/renovate.yml` exists (digest-pinned, daily cron, fixed version) - [x] `self-hosted-catalogue.md` snippet corrected (4 items) - [x] `nightly.yml` npm-audit job: survives non-zero exit, deduped tracking issue, jq payload, NIGHTLY_AUDIT_TOKEN via env only, heartbeat on clean - [x] ADR-041 records all negative-space decisions - [x] `ci-gitea.md` documents two-token model + runbook - [ ] Phase 0 manual gates: bot account creation, Renovate onboarding PR evidence, Dependency Dashboard screenshot — **requires manual provisioning** - [ ] Dedupe AC verified via `workflow_dispatch` — **requires NIGHTLY_AUDIT_TOKEN secret to be provisioned first** - [ ] `$GITHUB_STEP_SUMMARY` availability on this runner — **verify in first live run** Co-authored-by: Marcel <marcel@familienarchiv> Reviewed-on: #821
docs/
Project documentation organised into four categories: architecture decision records (ADRs), system architecture diagrams, infrastructure runbooks, and detailed UI/UX specifications.
Folder structure
docs/
├── adr/ # Architecture Decision Records
├── architecture/ # C4 model diagrams and system architecture docs
├── infrastructure/ # Deployment, CI/CD, and ops guides
├── specs/ # UI/UX feature specifications (HTML)
├── ARCHITECTURE.md # Human-readable architecture overview (DOC-2)
├── DEPLOYMENT.md # Day-1 checklist and operational reference (DOC-5)
├── GLOSSARY.md # Domain terminology (DOC-3)
├── security-guide.md # Security policies and hardening guide
└── STYLEGUIDE.md # Coding and design style guide
ADR (adr/)
Architecture Decision Records capture major technical decisions and their rationale.
| ADR | Title | Status |
|---|---|---|
001-ocr-python-microservice.md |
OCR as a separate Python container | Accepted |
002-polygon-jsonb-storage.md |
Polygon coordinates in JSONB columns | Accepted |
003-chronik-unified-activity-feed.md |
Unified activity feed (Chronik) | Accepted |
When making a significant architectural change (new service, data model change, technology swap), write a new ADR:
- Status (Proposed / Accepted / Deprecated / Superseded)
- Context (forces at play)
- Decision (what we decided)
- Consequences (trade-offs)
- Alternatives Considered (table format)
ADRs are sequential (NNN-descriptive-name.md). Do not reuse numbers.
Architecture (architecture/)
Contains C4 model diagrams describing the system at different zoom levels:
- Context diagram — How Familienarchiv fits into the user and system ecosystem
- Container diagram — The high-level technology choices (Spring Boot, SvelteKit, PostgreSQL, MinIO, OCR service)
- Component diagram — Major structural components within the backend
Written in Markdown with embedded Mermaid diagrams (c4-diagrams.md). Gitea renders these automatically.
For the human-readable architecture narrative, see docs/ARCHITECTURE.md.
Infrastructure (infrastructure/)
Operational documentation for running Familienarchiv in production and CI.
| Document | Purpose |
|---|---|
ci-gitea.md |
Gitea CI/CD pipeline configuration |
production-compose.md |
Production Docker Compose setup and VPS provisioning |
s3-migration.md |
Migrating documents between S3 buckets |
self-hosted-catalogue.md |
Self-hosted software catalogue |
For the day-1 deployment checklist, see docs/DEPLOYMENT.md.
Specs (specs/)
High-fidelity UI/UX specifications written as standalone HTML files. These are design documents describing exact layout, interactions, and responsive behavior before implementation.
Each spec typically includes:
- Visual mockups with CSS-in-HTML styling
- Interaction flows and state transitions
- Responsive breakpoint behavior
- Accessibility requirements
Before implementing a feature, check specs/ for an existing specification.
Style Guide
docs/STYLEGUIDE.md covers:
- Code formatting and linting rules
- Component naming conventions
- Color palette and typography
- Accessibility standards (WCAG 2.1 AA)