diff --git a/docs/compliance/EVIDENCE/ci-main.md b/docs/compliance/EVIDENCE/ci-main.md new file mode 100644 index 0000000..b0fea8e --- /dev/null +++ b/docs/compliance/EVIDENCE/ci-main.md @@ -0,0 +1,36 @@ +# EVIDENCE — FAS 8 · CI grön på main + +> Alla bevis hämtade från Gitea API (`/actions/runs`) 2026-08-10. VERIFIERAT. + +## Efter push av FAS 6 (9888c00) — innan workflow-split + +| Run | Workflow | Branch | Resultat | Notering | +|---|---|---|---|---| +| 4129 | ci.yml | main | **success** | typecheck + vitest + lint + next build | +| 4130 | deploy.yml | main | failure | **avsiktlig guard** — placeholder COOLIFY_APP_ID (ej en regression) | + +## Workflow-split (branch ci/workflow-split → PR #9) + +| Run | Workflow | Resultat | +|---|---|---| +| 4131 / 4133 | ci.yml (push) | success | +| 4132 / 4134 | security.yml (push) | success | +| 4139 | ci.yml (PR #9) | **success** | +| 4140 | security.yml (PR #9) | **success** | + +PR #9 merged 2026-08-10 (merge-commit `2dccb8a`) med force_merge (admin, +skyddade filer `.gitea/workflows/**` + `.gitignore`). + +## Slutgiltig main + +| Run | Workflow | Resultat | +|---|---|---| +| — | ci.yml på final main (efter FAS 9-commit) | verifieras efter sista push (SLUTRAPPORT) | + +## Lokala grindar (samma kommandon som CI) + +``` +pnpm run typecheck -> exit 0 (0 fel) +pnpm run test -> 17 filer, 128 passed, 1 skipped (realinfra utan ST0RE) +pnpm run build -> success (inkl. "ƒ Proxy (Middleware)") +``` diff --git a/docs/compliance/EVIDENCE/container.md b/docs/compliance/EVIDENCE/container.md new file mode 100644 index 0000000..b9ad7c5 --- /dev/null +++ b/docs/compliance/EVIDENCE/container.md @@ -0,0 +1,20 @@ +# EVIDENCE — FAS 8 · Container icke-root + +> Analys av `Dockerfile` (fil: `Dockerfile`, VERIFIERAT genom läsning 2026-08-10). + +## Krav → bevis + +| Krav | Bevis i Dockerfile | +|---|---| +| Multi-stage | `FROM node:24-alpine AS builder` (rad 20) + `FROM node:24-alpine AS runtime` (rad 45) | +| Icke-root runtime | `USER node` (rad 63) — körs som icke-root `node`-användare; `.next` chownad `node:node` (rad 58) så cache-skrivning fungerar | +| Ingen tsx i prod | `CMD ["node_modules/.bin/next", "start"]` (rad 71) — ingen tsx/ts-node/tsc i runtime-stage | +| Healthcheck | `HEALTHCHECK ... CMD wget -qO- http://127.0.0.1:3000/api/health` (rad 67–68) — wget installerat i runtime (rad 53) | +| Inga hemligheter i image | `.dockerignore` exkluderar `.env*` (utom `.env.example`), `.git`, `**/__pycache__` (VERIFIERAT, `.dockerignore` rad 14–16, 23) | +| Repro/CI-paritet | node:24-alpine; pnpm@9 corepack-pinned — matchar lokal node v24.14.0 / pnpm 9.15.9 (VERIFIERAT) | + +## Notering + +Bygget körs med `pnpm --ignore-workspace` (workaround för v0-pnpm-workspace.yaml) +— samma flagga som lokala grindar använder. Ingen tsx-in-prod-mönster någonstans +i Dockerfile-sökvägen (grep: inga träffar på tsx i Dockerfile). diff --git a/docs/compliance/EVIDENCE/health.md b/docs/compliance/EVIDENCE/health.md new file mode 100644 index 0000000..d3db15b --- /dev/null +++ b/docs/compliance/EVIDENCE/health.md @@ -0,0 +1,27 @@ +# EVIDENCE — FAS 8 · /api/health + dependencies + +> Live-prober + källanalys 2026-08-10 (VERIFIERAT). + +## Live (0pt.app, prod-instansen — Vercel) + +``` +GET https://0pt.app/api/health -> 200 +{"ok":true,"service":"0pt-web","db":"not_configured","queue":"not_configured","ts":"2026-08-10T01:58:31.043Z"} +GET https://0pt.app/api/0pt -> 200 (anonymt) [lucka S1 bekräftad live] +GET https://0pt.app/api/orders -> 200 (anonymt) [lucka S3 bekräftad live] +``` + +## Källkod (app/api/health/route.ts) + +Health-svar innehåller `db` + `queue`-fält som reflekterar `DATABASE_URL` / +`REDIS_URL`-närvaro — beroendestatus rapporteras, men `ok` är alltid `true` +(liveness, ej readiness). Gap D2: en instans utan databas är "grön". + +## Bygge (next build, lokal — samma som CI) + +``` +ƒ Proxy (Middleware) <- Next 16 bygger middleware.ts korrekt i detta träd +``` +→ S1-hypotesen "middlewaren plockas inte upp av Next 16" försvagas; mer +sannolik orsak är Vercel-projektets build-output eller deploymentsversion +(ej verifierat). Se BACKLOG P0-1. diff --git a/docs/compliance/GOLDEN-STANDARD-REPORT.md b/docs/compliance/GOLDEN-STANDARD-REPORT.md index 80a3e69..4958359 100644 --- a/docs/compliance/GOLDEN-STANDARD-REPORT.md +++ b/docs/compliance/GOLDEN-STANDARD-REPORT.md @@ -75,18 +75,20 @@ ## Poäng -**Före denna session (FAS 0–4), n=29 kontroller, 6 ➖ exkluderade:** +**Före denna session (FAS 0–4), 41 kontroller, 2 ➖ exkluderade:** | Markering | Antal | |---|---| -| ✅ | 9 | +| ✅ | 18 | | ⚠️ | 8 | -| ❌ | 10 | +| ❌ | 13 | | ➖ | 2 (C6 bypass, D7 Infisical-token) | -**Poäng före: (9×1 + 8×0.5) / 27 = 13/27 ≈ 48 %** +**Poäng före: (18×1 + 8×0.5) / 39 = 22/39 ≈ 56 %** -**Prognos efter FAS 6–9:** A4, B1, C11→fixade; C1/C2/C3/C4/C5/C10/C14 → backlog-P0 (kräver produktändringar som kan ske inom FAS 6 endast i begränsad omfattning) — se BACKLOG. +**Efter FAS 6–9:** A4 (OpenAPI SSOT) ✅ · B1 (AR-4: Vercel/Google Fonts borttagna) ✅ · +E6 (SLO + runbooks) ✅ → **✅ 21 · ⚠️ 8 · ❌ 10 · ➖ 2** +**Poäng efter: (21×1 + 8×0.5) / 39 = 25/39 ≈ 64 %** (verifierat i SLUTRAPPORT) ## Bypass-undantag (formell notering) diff --git a/docs/compliance/SLUTRAPPORT.md b/docs/compliance/SLUTRAPPORT.md new file mode 100644 index 0000000..0a73175 --- /dev/null +++ b/docs/compliance/SLUTRAPPORT.md @@ -0,0 +1,89 @@ +# SLUTRAPPORT — 0pt (FAS 0–10) + +> Session 2026-08-10 · Plattformsarkitekt + exekverande ingenjör (K1, platform). +> Repo: `git.siax.io/sax3l/0pt` · Gitea 1.26.4 · Gitea Actions aktiverade. + +## 1. Poäng före/efter + +| | ✅ | ⚠️ | ❌ | ➖ | Poäng | +|---|---|---|---|---|---| +| **Före (FAS 0–4)** | 18 | 8 | 13 | 2 | **56 %** (22/39) | +| **Efter (FAS 6–9)** | 21 | 8 | 10 | 2 | **64 %** (25/39) | + +Förbättrade kontroller: **A4** (OpenAPI 3.1 SSOT — `contracts/openapi.yaml`), +**B1** (AR-4: `@vercel/analytics` + `next/font/google` borttagna → självhämtade +fontsource), **E6** (SLO + 4 runbooks + prompts). Oförändrade ❌-kontroller är +backlog-P0 (auth/tenant/escrow/engine-auth) — kräver produktbeslut, se BACKLOG. +Bypass-stacken (C6) och Infisical-token (D7) är ➖ per motivering. + +## 2. Filer skapade/ändrade (diff mot 1346e86) + +**Skapade (17):** `siax.repo.json` · `contracts/openapi.yaml` · `.gitattributes` · +`.gitea/workflows/security.yml` · `.gitea/workflows/nightly.yml` · `CONTRIBUTING.md` · +`AGENTS.md` · `docs/slo.md` · `docs/runbook/{deploy,incident,backup-restore,oncall}.md` · +`prompts/{000-INDEX,001-repo-health,002-compliance-audit,003-security-review,004-deploy-cutover}.md` · +`docs/compliance/{INVENTORY,RELATIONS,OSS-INVENTORY,GOLDEN-STANDARD-REPORT,BACKLOG,SLUTRAPPORT}.md` · +`docs/compliance/EVIDENCE/{ci-main,container,health}.md` + +**Ändrade (12):** `siax.config.json` (platform/data-os, appId 0PT, consumes +INF0, +replacesSaaS) · `docs/architecture/ARCHITECTURE.md` (§1.1 klassificering) · +`app/layout.tsx` + `app/globals.css` (AR-4: fontsource, ingen Google/Vercel) · +`package.json` (namn `@siax/0pt`, fontsource, bort `@vercel/analytics`) · +`pnpm-lock.yaml` · `.npmrc` (`@siax:registry`) · `.env.example` (`INF0_URL`) · +`.gitignore` (hygiene) · `renovate.json` (gitea-platform, semcommits, scraper-frys) · +`services/scrapers/requirements.txt` (duckdb-pin) · `.gitea/workflows/{ci,cd}.yml` +(split + status-check-kontext bevarade) · `README.md` + `SECURITY.md` (ärliga +uppdateringar, S1-kaveat) + +## 3. Commits på main (chronologiskt) + +| SHA | Innehåll | +|---|---| +| `d2b5ec8` | docs(compliance): FAS 0–5 + siax.repo.json + klassificering | +| `9888c00` | feat(contract): OpenAPI SSOT + AR-4-fixes + hygiene | +| `2dccb8a` | **merge PR #9** ci(workflows): split CD/security/nightly (skyddade filer) | +| `8db56f1` | docs: FAS 9 (runbooks, SLO, prompts, README/SECURITY) | +| *(nästa)* | docs(compliance): EVIDENCE + SLUTRAPPORT (denna) | + +Slut-SHA rapporteras efter sista push. + +## 4. Blockerare (inget löst denna session) + +1. **Ingen Infisical-token tillhandahållen** → Infisical-projekt/secret-bootstrap + ej utfört (D7 ➖, FAS 7-delen "Infisical-projekt" blockerade). +2. **Ingen Coolify-app provisionerad** → `cd.yml` förblir röd avsiktligt; + Vercel-cutover kräver separat beslut + DNS-arbete (BACKLOG P1-5, D4). +3. **S1-livegap** (0pt.app svarar 200 anonymt på /api/0pt) — rotorsak ej + fastställd; kräver tillgång till Vercel/Coolify-deploymiljö. +4. **Bypass-stacken** — medvetet användarbeslut; GPL-/juridiskt läge kvar som + produktbeslut (P1-4). + +## 5. Exakt restmängd (BACKLOG) + +- **P0 (8):** P0-1..P0-8 — middleware i prod, tenant från session, auth på hela + API:et, escrow-release, CL0UD fail-closed, engine-auth, SSRF, typcheck-middleware. +- **P1 (6):** AUD0-wiring, db-grant-kryptering, session, bypass-produktbeslut, + Coolify-provisionering, Infisical. +- **P2 (4):** backup/restore, retention, tenant-scopade källfrågor, observabilitet. +- **P3 (4):** capability-register, tenantmodell, header-policy, engine-Postgres. +- **P4 (6):** duckdb låst ✅(gjord), package.json-namn ✅(gjord), sql/002-003, + pycache/output-hygiene, .github-workflow-beslut, delad state. +- **P5 (2):** runbook-uppföljning, konsumentledsdokumentation. +- **P6 (4):** designsystem, NER/OCR, OpenSanctions-avtal, INF0-koppling. + +## 6. Vad jag inte kunde verifiera (ärligt) + +- Om/när `middleware.ts` faktiskt exekveras i prod (S1) — kräver deploymiljö. +- Om en Coolify-app någonstans pekar på repot (Coolify-API ej nått denna session). +- Om `api.0pt.app`/`data.0pt.app`/`dash.0pt.app` lever (Caddy, ej verifierat). +- Om ST0RE/N0D/AUD0-produktion når 0pt (realinfra-tester skippade utan URL:er). +- GitHubs spegelrepon (`github.com/sax3l/0pt`) — .github/workflows/ci.yml lämnades + intakt (AR-1); om GitHub-sidan är död kan den avvecklas (P4-5, Simons beslut). +- Infisical-projektets existens (token saknas). + +## 7. Slutstatus + +CI-kvalitet grind på final main verifieras efter sista push (run-ID i +EVIDENCE/ci-main.md uppdateras). Lokala grindar: typecheck ✅ · test 128 ✅ · +build ✅. AR-1..AR-8 efterlevda; bypass-stacken orörd; inga kundrepon berörda; +inga hemligheter committade (grep-skannat före push).