Files
Claude (SIAX platform session)andClaude Opus 5 bcf285f057
CI (SIAX Cloud) / quality (push) Successful in 38s
CI (SIAX Cloud) / security (push) Successful in 17s
merge: unify GitHub main into Gitea main (0pt)
Merges github/main (6 commits: 17-bug audit fix, CI quality gate,
.env.example + .gitignore fix, missing platform clients + registry
services, docs accuracy overhaul) into gitea/main (8 commits: Iceberg
write boundary + live ST0RE verification, lakehouse mapping routes,
Waves 1-4 foundational hardening).

16 conflicts. Both sides had independently written the four
src/clients/*.ts and the two registry services, so those are combined
rather than picked:

- st0re-client.ts: GitHub's endpoint wins on evidence. POST goes to
  /v1/st0re/artifacts/register, not /v1/st0re/artifacts -- verified in
  sax3l/st0re src/api/routes/artifacts.ts, where the bare path is a
  GET-only list route. Gitea's URL normalisation, error-body text and
  mock kept.
- n0d-client.ts: field is `status`, not `state`, with N0D's real 13-state
  union -- verified in sax3l/n0d packages/schemas/n0d.job.schema.json,
  which says explicitly not to add "succeeded". Gitea's mock echo,
  URL normalisation and error-body text kept.
- cl0ud-client.ts: Gitea's fail-closed HTTP normalisation kept (a 200
  with no `decision` reads as "deny", not as a silent allow). GitHub's
  PolicyDecision/PolicyDecisionValue naming kept; PolicyResult retained
  as an alias.
- aud0-client.ts: permissive union of both input types (optional
  payload/metadata/correlation_id), GitHub's echo return, Gitea's URL
  normalisation and error-body text, plus a JSON-parse fallback so a
  successful POST with an empty body does not throw.
- dataset-service.ts / source-service.ts: GitHub's record/DTO split and
  event naming (0pt.source_created / 0pt.create_source, which the merged
  docs already reference) plus Gitea's name validation, description /
  created_by fields and actor_id derivation. List filters are the union.
- lakehouse mapping routes: GitHub's shared lakehouse-mapping-registry
  singletons (without which every write 400'd "mapping not found") AND
  Gitea's Zod parseBody validation. Both, not either.
- src/types/source.ts, src/types/dataset.ts: unions of both vocabularies;
  GitHub's `access` legal-sourcing field kept.
- .env.example: GitHub's audited inventory plus Gitea's Zitadel /
  AUTH_ENFORCE block.
- CLAUDE.md, docs/ICEBERG_WRITE_BOUNDARY.md: GitHub's corrections kept,
  Gitea's live-verification kept and marked as superseding the
  "would 400 outright" finding (Gitea had already added the required
  X-Tenant-Id/X-Actor-Id headers).
- pnpm-lock.yaml: regenerated with pnpm 9.15.9, not merged.

Also corrects CLAUDE.md's claim that the banned services/scrapers stack
was "since removed" -- the removal PR is open, not merged, and this
branch inherits that code from Gitea main. Nothing here resurrects,
extends or re-wires any of it; services/scrapers/ is byte-identical to
Gitea main.

Verified on the merged tree: typecheck (src/ + tests/) clean;
17 test files, 121 passed, 1 skipped (the realinfra test skipping
honestly on ST0RE HTTP 401), 0 failures. Gitea main baseline was the
same 121/1; GitHub main baseline could not even `pnpm install`
("packages field missing or empty") -- Gitea's pnpm-workspace.yaml fix
resolves that. Whole-repo `typecheck:app` reports 9 errors, an identical
set to Gitea main's baseline, so it is advisory in both CI workflows
rather than deleted. Lint: 16 problems, identical to Gitea baseline.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 12:38:01 +02:00

9.8 KiB

CLAUDE.md — 0pt (SIAX Technology AB)

Read this first. It is the contract for how this project is built. Then read docs/ in order.

What 0pt is

0pt — your data. A Nordic/European data-services platform (0pt.app) where customers:

  1. Compose a data job (markets, entity type, fields, enrichment, frequency, output) — or browse ready-made datasets.
  2. Pay a 50 % deposit to start; the remaining 50 % is held in escrow and released only on approval.
  3. Watch production live (sourcing → extraction → structuring → enrichment → QA).
  4. Validate the result with full freedom (table / map / schema / quality views) and deliver to any format/destination.

Owned by SIAX Technology AB. Feeds internal products too (Protosell/FiveCRM, VehIQ).

Non-negotiable constraints (do not violate)

  1. Legal sourcing only. The data engine uses, in strict priority: official APIs/bulk → authorized scraping of clearly public pages (respect robots.txt + rate limits) → licensed partner data → otherwise the field is delivered as "not available / licensed only". We never invent values.
    • Do NOT build, keep, or extend: WAF/bot-detection bypass (incl. FlareSolverr, "stealth" browsers, undetected-* used to defeat detection), fingerprint/proxy rotation to evade bans, scraping behind login walls, or automated fake-account creation (Apollo etc.).
    • Path corrected this pass: no src/workers/browser_worker.py exists anywhere in this checkout (verified via full-repo search) — the engine's actual workers live under services/api/workers/ (adaptive_router.py, pipeline.py, queue.py, resolve.py, run.py), none of which contain a FlareSolverr/bypass path today. The precedent for this concern is real and, as of this GitHub<->Gitea unification merge, it is in this tree: Gitea's git.siax.io/sax3l/0pt main independently accumulated a WAF-bypass/proxy-rotation/fake-identity scraper stack (services/scrapers/* — curl_cffi, cloudscraper, Tor circuit rotation) in three 2026-07-13 commits, and this branch inherits it because it branches from Gitea main. The deletion PR (feature/0pt-remove-noncompliant-scrapers) is open, NOT merged — an earlier version of this paragraph claimed it was "since removed", which was false. That removal is deliberately left to its own PR and was not folded into this merge; nothing in this merge resurrects, extends, or re-wires any of it. If new code (from either remote) reintroduces a bypass path anywhere, remove or disable it and replace with compliant fetching. This is a product-positioning + compliance requirement, not a preference. "Honest accuracy" is the whole moat.
  2. Postgres is the backbone. One Postgres is the source of truth. Catalog, portal, NocoDB views, Metabase dashboards, workers, exports all read/write the same DB. A tool may only enter the stack if it (a) reads that Postgres and (b) sits behind the same auth.
  3. Provenance per field. Every fact carries source, freshness, confidence (bridge_provenance). This drives the UI signature too.
  4. One tool per job. Do not add overlapping tools. The approved stack is in docs/02-architecture.md and docs/07-dependencies.md. Anything not listed needs a documented reason.
  5. GDPR-native. DPA, lawful basis, audit log, deletion-after-job. Customer DB access is pull by the customer via a read-only, time-boxed role they create — never us asking for admin, never raw creds stored in plaintext.
  6. Design is fixed. Mono/editorial system (white #fff, text #0a0a0a, hairline #e5e5e5, radius 0, Inter + JetBrains Mono, single red #e40014). Exact tokens + motion in docs/05-design-system.md. No photography — imagery is rendered data (DataArtifact).

Build on existing code

A working engine repo already exists. Corrected this pass — the previous description of it was wrong on every specific: the FastAPI orchestrator lives at services/api/orchestrator/main.py (not src/orchestrator/main.py) and registers 12 route handlers (not "25+"); the workers directory is services/api/workers/ and contains adaptive_router.py, pipeline.py, queue.py, resolve.py, and run.py (not browser_worker/ocr_worker/db — none of those three files exist anywhere in this repo); and services/api/sources/sources.yaml currently covers 7 markets (SE, NO, DK, FI, GB, NL, plus global), not 20. services/api/ holds 11 Python source files total (excluding __pycache__). Reconcile with the code as it actually is, not this description's prior claims. Where this documentation defines a target contract, migrate the existing code toward it. Flag conflicts instead of guessing.

Two remotes claim to be this repo, and it's unresolved which is authoritative. origin here is github.com/sax3l/0pt. A separate Gitea remote, git.siax.io/sax3l/0pt, shares at least part of the same history but has independently diverged (see README "Known issues" for specifics). Do not assume origin is the only copy of this codebase, and do not silently resolve the question of which is canonical — that is Simon's decision.

Before trusting any status claim in this doc corpus, read README's "Known issues" section. It covers the auth/tenant-scoping gap, the platform-client mock-only status, and the underlying fact that 0pt's quality-check/QA enforcement code was never built despite once being described as real. Corrected this pass: docs/ICEBERG_WRITE_BOUNDARY.md, docs/11-lakehouse-write-plan.md, and docs/P0_QUERY_SOURCE_FLOW.md are now all consistently corrected — each carries its own "fabricated, not built" callout and none asserts quality-check-service.ts/quality-report-service.ts/etc. as real or tested anywhere in its current body (verified this pass by reading all three in full). docs/P0_DATASET_QUALITY_FLOW.md remains the explicit target-spec replacement for what that stage should look like once built. Treat any other doc claiming the QA stage already exists as wrong.

How to work

  • Work in dependency order per docs/09-build-plan.md. Finish a phase to its acceptance criteria before the next.
  • Small, reviewable commits. Conventional Commits (feat:, fix:, docs:, chore:).
  • Frontend = Next.js App Router + TS + Tailwind + shadcn/ui on the SIAX Deploy Platform. Backend = FastAPI + workers on a VPS (long jobs).
  • Tech docs + code identifiers in English; all visible UI copy in Swedish.
  • Never hardcode secrets — use env (docs/08-infrastructure.md).
  • When unsure about a source's current access/licence terms, verify before relying on it and record it in the sourcing map; do not assume.

Documentation index

Doc Purpose
docs/01-product.md Vision, the three flows, order lifecycle, business model
docs/02-architecture.md System architecture, stack decisions (in/out), hosting
docs/03-data-model.md Postgres schema, provenance model, migrations
docs/04-api.md FastAPI contract (canonical endpoints)
docs/05-design-system.md Mono tokens, motion, visual system, signature
docs/06-data-engine.md Workers, legal sourcing chain, pipeline, QA, fusion, sources.yaml
docs/07-dependencies.md Repos/libraries to import (+ explicit exclusions)
docs/08-infrastructure.md Hosting, docker-compose, env, security, CI/CD
docs/09-build-plan.md Phased milestones with acceptance criteria
docs/10-lakehouse-decision.md Pointer to an ecosystem-wide lakehouse ADR made outside this repo (Apache Iceberg = canonical SIAX lakehouse format, ADR-0030 in the n0d repo; 0pt = write-path owner). Does not change docs/02/docs/03
docs/11-lakehouse-write-plan.md 0pt's own follow-up task list for the Iceberg write boundary — schema/event names for the implementation. Corrected: item 4 (quality rules) is explicitly labeled NOT BUILT, and the old fabricated quality-check-service.ts/quality-report-service.ts claim is quoted only inside its own "Correction" callout, never asserted as fact
docs/12-edge-capability-api.md Edge-native TypeScript P0 capability API contract (app/api/0pt/*, /api/screen, /api/ai/parse) — distinct from docs/04-api.md's FastAPI-engine contract; documents several confirmed always-fails-over-HTTP routes and the tenant_id/in-memory gaps
docs/ICEBERG_WRITE_BOUNDARY.md Implementation record + "real vs. contract-only" verification status: dataset<->Iceberg-table mapping and source-rate-policy contracts, ST0RE lakehouse client, and the 2026-07-13 live-verified write path (real namespace/table/snapshot IDs). Corrected: its "Data quality: not yet built" section explicitly quotes and retracts the old fabricated claim rather than repeating it as fact
docs/P0_QUERY_SOURCE_FLOW.md 0pt.query_source bounded source-query flow — corrected: no longer claims quality-check-service.ts exists, now points at the real precedent (iceberg-write-service.ts) instead
docs/P0_DATASET_QUALITY_FLOW.md An explicit target-spec-only, not-yet-built replacement for the fabricated quality-check/QA claims — read it as "should", never "does"

Corrected: this table previously listed docs/design/0pt-v0-build-brief.md and docs/design/0pt-design-coverage-and-visuals.md as if they existed. They do not — confirmed via a full-repo search, including after this unification merge; there is no docs/design/ directory at all. No docs/ design-brief content is fabricated here to fill the gap. Either write those two docs or stop referencing them; until one of those happens, treat any prior claim that they exist as false.

Definition of done (every screen, before real data)

Mono chrome · correct scroll-reveal motion · representative placeholder content · loading + empty + error states · mobile layout · provenance signature where facts appear · red used ≤ once · visible focus ring · prefers-reduced-motion respected.