5 Commits
Author SHA1 Message Date
adminandClaude Opus 5 db868f4bdf fix(prod): close legacy storage fallbacks in orders/subscriptions/blobs
CI (SIAX Cloud) / security (push) Successful in 14s
Security Scan (SIAX Cloud) / security (push) Successful in 21s
CI (SIAX Cloud) / security (pull_request) Successful in 15s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 15s
CI (SIAX Cloud) / quality (push) Successful in 44s
CI (SIAX Cloud) / integration (push) Successful in 45s
CI (SIAX Cloud) / integration (pull_request) Successful in 27s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m45s
The `resolveStoreMode` kill switch (Master-DoD §3/§10) covered the newer
`src/repositories/*` stores but not two older paths, both of which are
live production execution paths today.

1. LEGACY NEXT.JS STORES. `lib/orders-store.ts` and
   `lib/subscriptions-store.ts` predate `src/platform/dependency-mode.ts`
   and called `getSql()` directly, silently falling back to module-global
   `Map`s when no database is configured. For orders, payments and
   subscriptions that is not a degraded mode, it is invisible loss of
   money-bearing state: the API returns 201 and the row evaporates on the
   next restart or on any other replica. The live 0pt deployment
   (Coolify app 54) runs NODE_ENV=production with DATABASE_URL,
   POSTGRES_URL and POSTGRES_PRISMA_URL all unset — so this is the
   behavior in production right now, across 7 API routes.

   These now go through `getSqlForDurableStore()`, which reuses the SAME
   `resolveStoreMode` decision every `src/repositories/*` store already
   uses rather than re-implementing a second production check. The reuse
   is load-bearing: `isProductionRuntime` deliberately exempts
   `NEXT_PHASE=phase-production-build`, because `next build` runs
   page-data collection under NODE_ENV=production while serving nothing.
   A naive `process.env.NODE_ENV === "production"` test here would have
   failed the BUILD instead of protecting a request path.

2. LOCALBLOBSTORE. It writes document bytes to a container-local disk
   while `document-capture-service` registers an artifact pointer
   claiming the bytes are stored — durable object storage silently
   swapped for ephemeral disk. It is the default blob store for both the
   capture and extraction services. In production it now raises
   DEPENDENCY_UNAVAILABLE (capability blocked: no ST0RE bytes path
   exists yet) instead of fabricating success. Asserted per-operation,
   not in the constructor, so merely wiring the services is not fatal —
   only actually persisting or reading bytes is.

Evidence: full suite 956 passed / 184 skipped, typecheck clean,
dependency-cruiser 0 errors, lint identical to main's pre-existing
baseline (17 problems, none in changed files). Both guards asserted in
both directions and mutation-tested: bypassing resolveStoreMode -> 2
failed; dropping the write assert -> 2 failed; dropping the read assert
-> 1 failed; all restored -> 8 passed. 7 non-test call sites.

DEPLOYMENT NOTE: merging changes no runtime (no Gitea webhook exists on
any repo; deploys are manual). Deploying this build REQUIRES
provisioning DATABASE_URL for 0pt first, or the order/subscription
routes will correctly return DEPENDENCY_UNAVAILABLE instead of silently
accepting orders into memory. That provisioning is a Simon action.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 17:38:51 +02:00
admin 2d34cb1629 feat(P-001, P-002): 0pt→N0D quality delegation + internal OpenAPI
CI (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / security (push) Successful in 16s
Security Scan (SIAX Cloud) / security (push) Successful in 17s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 23s
CI (SIAX Cloud) / integration (push) Failing after 27s
CI (SIAX Cloud) / integration (pull_request) Failing after 31s
CI (SIAX Cloud) / quality (pull_request) Successful in 42s
CI (SIAX Cloud) / quality (push) Successful in 42s
2026-09-08 22:38:47 +02:00
Simon AxelssonandClaude Fable 5 c47e3b468e test(integration)+ci+docs: live OpenSearch/ClickHouse suites, CI service containers, STATUS.md (§56)
CI (SIAX Cloud) / integration (push) Failing after 22s
CI (SIAX Cloud) / security (push) Successful in 22s
Security Scan (SIAX Cloud) / security (push) Successful in 21s
CI (SIAX Cloud) / quality (push) Successful in 43s
CI (SIAX Cloud) / integration (pull_request) Failing after 3s
CI (SIAX Cloud) / security (pull_request) Successful in 17s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / quality (pull_request) Successful in 43s
- tests/integration/: 10 tests against REAL OpenSearch 2.11 (tenant
  isolation, purpose/rights filters, generation rebuild/rollback,
  projection-disaster rebuild §68) + REAL ClickHouse 24.8 (tenant-isolated
  metric DSL, TTL schema, injection-surface refusals). Honest skip without
  env - and CI fails hard if the suites skip instead of running.
- .gitea/workflows/ci.yml: new blocking 'integration' job with
  self-identifying service containers (st0re ci.yml's measured
  alias-collision discipline: run-unique cluster.name / credentials,
  getent-enumerated IP selection, no-match = hard fail).
- STATUS.md: full 8-level Master-DoD classification per capability incl.
  the honest gaps blocking PRODUCTION_READY.
- dependency-mode: NEXT_PHASE=phase-production-build is not a serving
  runtime (next build page-data collection must compile; guard re-arms at
  boot) - pinned by contract test.
- docs/02-architecture.md: superseded the accurate-but-now-fixed 'every
  client runs against its mock' paragraph; .env.example: client URLs now
  actually read from env + new P0 backend vars.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 16:56:33 +02:00
Simon AxelssonandClaude Fable 5 b46807da75 feat(data-os): P0 capability layer — source registry, search, quality, dataset versions, metadata, analytics, features, ER
- Source Registry (§10): rights/license/purpose metadata, provenance,
  freshness SLA, health checks, describe/query; purpose gate FAILS CLOSED
  (no rights record => deny); cross-tenant probes => NOT_FOUND.
- Search (§10/§42): OpenSearch REST adapter (no SDK) + SearchService with
  MANDATORY tenant + purpose/rights filtering, versioned index definitions,
  bulk, generation-per-rebuild (opt-{name}--g{n}) with atomic alias cutover,
  rollback, failed-rebuild generation discard. OpenSearch never canonical.
- Quality (§10): versioned rule registry (GE-JSON interchange), local
  engine for the GE core subset (never silently passes unsupported types),
  runs/results/issues/score/trend, whole-run delegation to the GE backend
  via N0D (0pt.quality.ge_run) - never fabricated results.
- Dataset (§10/§5/§53): immutable numbered versions holding canonical
  st0re:artifact refs only, idempotent createVersion, export registers the
  ST0RE artifact + AUD0 evidence + OpenLineage.
- Metadata (§10): OpenMetadata PUT /api/v1/tables projection adapter +
  projectAll rebuild path; projection never canonical.
- Analytics (§10): ClickHouse HTTP adapter, closed metric-query DSL with
  FORCED tenant predicate + readonly/max_execution_time/max_result_rows,
  TTL retention. Zero connection to b0ts/quarantined pipelines.
- Features (§10): versioned feature-view registry, real Feast
  get-online-features adapter, materialize/get-historical as N0D delegation.
- ER (§10): generic candidate API with deterministic blocking + transparent
  scoring + per-field explanations, product hard-rule hook (force both
  directions), review-band handoff, Splink batch via N0D contract.

93 new unit/contract tests; suite 248 passed / 1 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 16:49:32 +02:00
Simon AxelssonandClaude Fable 5 da58176735 test(contracts): per-client wire-contract suites + §3 production-guard tests
38 tests: recording provider double answers with the sibling services' real
response shapes; each suite asserts the exact request wire shape (path,
method, tenant/actor/idempotency headers, camelCase vs snake_case body) so a
regression to the pre-rewrite invented shapes fails loudly. Includes the
fail-closed policy cases (missing decision => deny, CL0UD down => typed
error, never implicit allow) and the production factory guard for all four
clients.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 16:37:57 +02:00