# 0pt — capability status (Master-DoD §56 status honesty) > Classification scale (Master-DoD §2, exactly one per capability): > `MISSING → DOCUMENTED_ONLY → SKELETON → MOCK_ONLY → IMPLEMENTED → INTEGRATION_TESTED → LIVE_VERIFIED → PRODUCTION_READY`. > Only `PRODUCTION_READY` may be called DONE. Docs ≠ implementation. > Last full audit + re-classification: **2026-08-31** (SIAX Platforms P0 wave 2). ## How to read this - **INTEGRATION_TESTED** here means: verified against a REAL dependency (live OpenSearch/ClickHouse container, or a recorded wire-contract double pinned to the sibling repo's real handler code on its `main`) in CI. - **LIVE_VERIFIED** requires a verification against the actual SIAX fleet deployment. No new capability in this wave claims it. - The unit/contract/integration suites are in `tests/` and run in `.gitea/workflows/ci.yml` (jobs `quality` + `integration`). ## Cross-product clients (Master-DoD §10 "Cross-product clients") | Capability | Status | Evidence | Honest gaps | |---|---|---|---| | CL0UD client (policy evaluate, `POST /api/policy/evaluate`) | **INTEGRATION_TESTED** (contract) | `src/clients/cl0ud-client.ts`; `tests/contracts/cl0ud-client.contract.test.ts` pins the real camelCase `{data}` envelope; fail-closed (missing decision ⇒ deny) | Not yet exercised against a live CL0UD deployment (no reachable CL0UD URL this session ⇒ not LIVE_VERIFIED) | | CL0UD capability discovery (`GET /api/capabilities`) | **INTEGRATION_TESTED** (contract) | same suite | 0pt's own capabilities are not yet registered in CL0UD's registry (§3 gap) | | ST0RE client (artifact register, camelCase `/v1/st0re/artifacts/register`) | **INTEGRATION_TESTED** (contract) | `src/clients/st0re-client.ts`; `tests/contracts/st0re-client.contract.test.ts` | Raw-bytes upload still goes via LocalBlobStore interim (pre-existing, unchanged); presign upload path not consumed yet | | N0D client (create/get job, get result) | **INTEGRATION_TESTED** (contract) | `src/clients/n0d-client.ts`; `tests/contracts/n0d-client.contract.test.ts` pins `required_role`/`resource_requirements`/body `idempotency_key` | CloudEvents completion callback receiving endpoint not built in 0pt (poll path works) | | AUD0 client (events + OpenLineage ingest) | **INTEGRATION_TESTED** (contract) | `src/clients/aud0-client.ts`; `tests/contracts/aud0-client.contract.test.ts`; legacy lineage shape converts to real OpenLineage | No durable local outbox for AUD0 outages (§70 "durable local/outbox path" — emission failure is surfaced, not queued) | | **No production mock fallback (§3/§10)** | **INTEGRATION_TESTED** | `src/platform/dependency-mode.ts`; `tests/contracts/dependency-mode.contract.test.ts` drives NODE_ENV=production for all four factories ⇒ hard `DEPENDENCY_UNAVAILABLE` | — | **Correction of prior state (2026-08-31):** the pre-existing clients' HTTP paths were verified against the sibling repos' actual `main` branches and THREE of four were wrong: cl0ud (`/v1/cl0ud/policies/evaluate` — never existed), st0re (snake_case body — would 400), aud0 lineage (`/v1/aud0/lineage/events` — never existed). All fixed and pinned by contract tests. The earlier MOCK_ONLY classification in the README was accurate. ## Data-OS capabilities (Master-DoD §10) | Capability | Status | Evidence | Honest gaps | |---|---|---|---| | Source Registry — register/query/describe/health, rights/license/purpose, freshness, provenance | **IMPLEMENTED** | `src/services/source-registry-service.ts`, `src/types/source-registry.ts`; `tests/p0/source-registry.test.ts` (fail-closed purpose gate, cross-tenant NOT_FOUND) | In-memory persistence (per-process); no Postgres store yet — production boot must therefore configure one before this counts further. No API route surface yet | | Source rate-policy | **IMPLEMENTED** (pre-existing) | `src/services/source-rate-policy-service.ts` | unchanged this wave | | Search — OpenSearch adapter, index defs, bulk, tenant + purpose/rights filter, rebuild, generation switch | **INTEGRATION_TESTED** | `src/search/*`; unit `tests/p0/search-service.test.ts`; **real OpenSearch 2.11** `tests/integration/search-opensearch.integration.test.ts` incl. projection-disaster rebuild (§68-style) — runs in CI service container | Hybrid (vector) query not built; no metrics emission; index definitions in-memory | | Quality — versioned rules, runs, results, issues, score, trend, GE interchange | **IMPLEMENTED** (local engine) / **SKELETON** (GE delegation) | `src/quality/*`; `tests/p0/quality-service.test.ts`, `tests/p0/expectation-engine` cases | Local engine covers 7 GE core expectation types; everything else delegates via N0D job `0pt.quality.ge_run` whose EXECUTOR (0pt-motor GE runner) does not exist yet — delegated runs stay "delegated" until it does. Never fabricates results | | Dataset — create (pre-existing) + version/query/export with `st0re:artifact:` refs | **IMPLEMENTED** | `src/services/dataset-version-service.ts`; `tests/p0/dataset-version-service.test.ts` (idempotency §53, canonical refs §5) | Export assumes bytes already written by a job; no route surface; in-memory persistence | | Lineage — OpenLineage emission to AUD0's real ingest | **INTEGRATION_TESTED** (contract) | `src/lineage/*`; aud0 contract suite; emitted from dataset version/export, quality runs, search rebuilds | Emission is best-effort (never-throw); no outbox. AUD0-side ingestion verified against contract double, not live AUD0 | | Metadata — OpenMetadata projection (never canonical) | **IMPLEMENTED** | `src/metadata/openmetadata-adapter.ts`; `tests/contracts/metadata-features.contract.test.ts`; `projectAll` rebuild path | No live OpenMetadata exercised (no local container this pass); lineage/glossary/ownership projection not built — only dataset entities | | Analytics — ClickHouse, tenant-isolated, query limits, retention | **INTEGRATION_TESTED** | `src/analytics/clickhouse-analytics.ts`; **real ClickHouse 24.8** `tests/integration/analytics-clickhouse.integration.test.ts` (tenant isolation, closed DSL, TTL schema) — runs in CI service container | Closed metric-DSL only (no ad-hoc queries by design); no quota integration with CL0UD | | Features — registry + Feast adapter | **IMPLEMENTED** (online path, registry) / **SKELETON** (materialize/get-historical) | `src/features/feast-adapter.ts`; contract suite pins Feast's `get-online-features` wire shape | No live Feast server exercised; offline/materialization are N0D delegation contracts whose executor (0pt-motor) does not exist yet; point-in-time correctness therefore NOT yet proven | | Entity Resolution — candidate API, blocking, explanation, hard-rule hook, review handoff | **IMPLEMENTED** | `src/er/entity-resolution-service.ts`; `tests/p0/entity-resolution.test.ts` (hard rules override both directions, review band, blocking refusals) | Generic reference scorer (Jaccard+Levenshtein), NOT Splink probabilistic linkage — that is the `0pt.er.batch_resolution` N0D contract, executor pending in 0pt-motor. No persistence of review queues | | Graph (§10 Graph) | **MISSING** | — | Not started this wave (explicitly out of the delivered P0 subset; next in line per §10) | ## Canonical platform plumbing | Capability | Status | Evidence | |---|---|---| | SiaxRequestContext + propagation headers (mirror of cl0ud `@siax/contract`) | **INTEGRATION_TESTED** (contract-pinned) | `src/platform/siax-context.ts`; `tests/contracts/siax-context.contract.test.ts` | | Canonical 12-code error model + typed `SiaxError` (§6) | **INTEGRATION_TESTED** (contract-pinned) | `src/platform/errors.ts`; same suite | | Canonical resource refs (§5) | **IMPLEMENTED** | `src/platform/resource-ref.ts`; `tests/p0/dataset-version-service.test.ts` | ## Pre-existing capabilities (unchanged this wave — prior classifications stand) | Capability | Status | Note | |---|---|---| | Iceberg write boundary via ST0RE lakehouse | LIVE_VERIFIED (2026-07-13) | `docs/ICEBERG_WRITE_BOUNDARY.md`; untouched | | Document capture/extraction | IMPLEMENTED | LocalBlobStore interim persists bytes; ST0RE raw upload still pending | | Edge order/payment app (Next.js) | see `docs/architecture/ARCHITECTURE.md` | outside this wave's scope | | FastAPI engine (`services/api`) | IMPLEMENTED | outside this wave's scope | | `services/scrapers/*` (WAF-bypass stack) | **quarantined, pending deletion PR** | `feature/0pt-remove-noncompliant-scrapers` — NOT touched by this wave; nothing new wires it | ## Global gaps blocking PRODUCTION_READY (§3, tracked, not hidden) 1. Persistent stores REMAINING: quality runs/rules and feature views are still per-process in-memory (`resolveStoreMode` guarantees production boot FAILS rather than serving Maps). CLOSED since the last revision: dataset registry (`opt_datasets`) + immutable versions (`opt_dataset_versions`, monotonic under transaction lock, idempotency with payload-drift detection, cross-tenant ⇒ NOT_FOUND) and versioned search index definitions (`opt_search_index_definitions`, sequential schema versions, replay-idempotent, same-version-different-schema ⇒ CONFLICT; OpenSearch remains a rebuildable projection, never canonical truth) are Postgres-canonical with real-Postgres tests. 2. Capability registration in CL0UD + API0 discovery for the new capabilities (§3 "Capability är registrerad i CL0UD Capability Registry") — PARTIALLY CLOSED: the collaboration/meeting domain was canonicalized in CL0UD's registry (cl0ud #73/#74); 0pt's own capability set still needs the same registration. 3. CLOSED: AUD0 outbox for evidence durability under AUD0 outage (§70) — durable Postgres outbox + dispatcher (at-least-once, bounded batch, backoff, dead-letter, SKIP LOCKED leasing, tenant binding, idempotency) + real-Postgres tests; dispatcher uses explicit `durable:false` so it never re-enqueues its own delivery evidence. 4. CLOSED for datasets/versions/search/ER: `app/api/0pt/datasets*`, `app/api/0pt/search/definitions` + tenant-safed query route, and `app/api/0pt/er/{candidates,batch}` (+ internal ER route) are live; clients cannot raise `rights_tag` via request body (fail-closed to `internal`). Quality routes exist (`bridge-run/issues/rules/runs`). 5. 0pt-motor executors for the delegated jobs (`0pt.quality.ge_run`, `0pt.features.*`, `0pt.er.batch_resolution`). 6. Observability: no metrics/traces emitted by the new services (§36). --- ## P060-P068 ingestion plane (added 2026-09-04) Classification scale unchanged. Every row below states what was actually verified, and by which command. | Requirement | BEFORE this pass | Status now | Evidence | |---|---|---|---| | **P060** Source Registry: durable canonical registry; restart preserves sources; an unclassified source cannot be activated | **PARTIAL / BROKEN.** The registry existed with Postgres persistence (`sql/002_source_registry.sql`, `src/repositories/postgres-source-registry-repository.ts`) and carried source_id/tenant/project/type/status/license/purpose/rights. It had NO authorization, NO schedule, NO checkpoint, NO schema, and no `owner` distinct from `created_by`. The activation DoD was inverted: `postgres-source-repository.ts:70` wrote `${input.status ?? "active"}`, so a source with no rights, no provenance and no authorization was ACTIVE the instant it was registered, and no activation operation existed at all | **INTEGRATION_TESTED** | `sql/007_ingestion_plane.sql` (authorization/schedule/schemas/checkpoints + `ALTER … SET DEFAULT 'pending'` + `owner_id`); `SourceRegistryService.classifySource`/`activateSource`; `tests/p0/source-activation-gate.test.ts` (11); `tests/api/0pt-p060-routes.test.ts` (9); `tests/p0/ingestion-plane-postgres.realinfra.test.ts` against a live Postgres 16 | | **P061** Connector contract: discover/validate/connect/checkpoint/read/resume/backfill/health/disconnect; two heterogeneous connectors pass one conformance suite | **MISSING.** `services/api/sources/connectors.py` had per-source `fetch_*()` functions only — no lifecycle, no cursor, no resume, no health, no disconnect, no conformance suite | **INTEGRATION_TESTED** | `src/connectors/connector.ts` (all nine operations); `src/connectors/conformance.ts` (15 checks); `HttpJsonConnector` (real node:http server, opaque cursor) and `JsonlFileConnector` (real file, line-offset cursor, CDC deletes) both pass the identical suite — `tests/p0/connector-conformance.test.ts`, which also proves the suite FAILS a fail-open connector | | **P062** CDC/batch/stream normalized to one envelope; restart resumes from a durable checkpoint without silent gaps | **MISSING**, and documented as such: `services/api/tests/test_known_gaps.py:10-19` skipped the CDC case because no CDC pipeline existed anywhere, and `workers/pipeline.py` had no persistence at all | **INTEGRATION_TESTED** | `src/types/ingestion.ts` (one envelope for all three modes); `src/ingestion/ingestion-runner.ts`; `tests/p0/ingestion-runner.test.ts` kills a run inside the sink and proves the resumed run covers all 10 records exactly once; same proof against real Postgres across fresh processes | | **P063** Schema versioning + compatibility policy; a breaking schema is detected before consumer corruption | **MISSING.** `schema_version` existed as a free-form string on datasets/Iceberg writes; there was no comparison, no policy, no versioned source schema | **INTEGRATION_TESTED** | `src/schema/compatibility.ts`, `src/schema/schema-registry.ts`; `tests/p0/schema-evolution.test.ts` (12); the runner's schema gate runs before the first read — `tests/p0/ingestion-runner.test.ts` asserts `sinkCalls === 0` on a break | | **P064** Quality rules behind the SIAX abstraction; failures block or quarantine per declared policy | **PARTIAL.** `src/quality/*` had rules, runs, results, issues, scores and a GE-compatible engine, but a failing rule only opened an ISSUE — the data flowed on regardless. `grep -ri quarantin src/` found one unrelated hit | **INTEGRATION_TESTED** | `src/quality/quality-policy.ts` composes the EXISTING `ExpectationEngine` (not a second engine) and adds the consequence; block / quarantine / warn each proved in `tests/p0/ingestion-runner.test.ts`; quarantine durability proved against real Postgres | | **P065** Normalization/ER: only the canonical highway; no second simplified production engine | **CLOSED.** `services/api/workers/resolve.py` is now a thin adapter: Python no longer scores identity — it POSTs opaque records to `/api/0pt/internal/er/candidates` and applies ONLY explicit hard-rule `match` decisions (score/fuzzy can never merge records, even from a compromised bridge); canonical engine unreachable ⇒ records return UNMERGED, never fallback-scored. Company semantics `stable-identifiers.v3`: LEI global; org_nr hard identity only within the same registration_country; punctuation normalized; negative stable identity dominates every positive; fuzzy alone ⇒ human review, never auto-merge. Cluster-wide hard-negative constraints: A≈B ∧ B≈C never forces A≈C when canonical identity says A≠C | **INTEGRATION_TESTED** | `tests/p0/entity-resolution.test.ts` (v3 semantics incl. hard-negative transitivity), `tests/p0/entity-resolution-http.test.ts` (internal route fails closed: empty/wrong token ⇒ 401), `services/api/tests/test_resolve_determinism.py` (adapter contract: canonical edges only), shared request validation (`src/er/request-validation.ts`, records 2..5000), blocking pytest gate (`.gitea/workflows/python-engine.yml`) | | **P066** Iceberg | out of scope — ST0RE is owned by another workflow | **NOT TOUCHED** | Contract read only (`src/services/iceberg-write-service.ts`, `src/clients/st0re-lakehouse-client.ts`) | | **P067** Lineage: OpenLineage/AUD0 events; source → output lineage is queryable | **PARTIAL.** `src/lineage/lineage-emitter.ts` emitted OpenLineage to AUD0, but nothing in this repo could ANSWER a lineage question — no store, no query, no route | **INTEGRATION_TESTED** | `src/lineage/lineage-edge.ts`, `src/lineage/lineage-store.ts` (local queryable projection; AUD0 stays the system of record), `GET /api/0pt/lineage`; `tests/p0/ingestion-runner.test.ts` queries both directions and proves tenant scoping | | **P068** Durable bounded backfill/replay; repeated backfill is idempotent | **MISSING**, documented as such: `services/api/tests/test_known_gaps.py:44-52` skipped it because "no delivery-store persistence layer exists to dedupe a backfill against" | **INTEGRATION_TESTED** | `opt_ingestion_ledger` + `IngestionRunner.backfill`; `tests/p0/ingestion-runner.test.ts` (repeat emits 0, live checkpoint untouched, a real content change still re-emits); same against real Postgres | ### What was actually run (not "should pass") - `pnpm run typecheck` — clean. - `pnpm run test` — **365 passed, 25 skipped** (was 311/18 before this pass). - `pnpm run build` — clean; the four new routes appear in the route table. - `pnpm run lint` — 12 errors / 5 warnings, **all pre-existing** (identical count on the base commit; advisory in CI). This pass adds none. - Real Postgres 16: `tests/p0/ingestion-plane-postgres.realinfra.test.ts` with `INGESTION_TEST_DATABASE_URL` — 7 passed. - **Real container restart**, run manually against that same database: `docker restart` the Postgres container, then re-read through the real repositories. Before and after were identical — 2 sources (one `active` with its owner, one `pending`), 1 checkpoint (cursor 6, 6 committed), 6 ledger rows, 1 lineage edge, 4 quarantined records, 1 schema version. That is P060's "a restart preserves all sources", measured rather than asserted. ### A real bug this pass wrote and then caught The first draft of `IngestionRepository` combined the idempotency check and its recording into one atomic call, made BEFORE the sink. The crash/resume test then delivered **7 of 10 records**: the page in flight when the sink died had already been marked delivered, so the resumed run skipped it as a duplicate — permanent, silent data loss. The fix is the `peekDeliveries` / `commitDeliveries` split, with both the ledger commit and the checkpoint commit after the sink resolves. Recorded here because the failure mode is the interesting artifact, not the fix. ### Honest gaps in the new plane (not hidden) 1. **Delivery is AT-LEAST-ONCE, not exactly-once.** Two concurrent runs on the same (source, partition) can both peek "new" and both emit. `envelope_id` is deterministic so a dedup-capable sink survives it. There is no per-(source, partition) run lock. Do not describe this plane as exactly-once. 2. **No CDC *source* exists.** The envelope, the operations and the runner handle change events, and `JsonlFileConnector` emits real deletes from an `_op` field — but this repo still has no Debezium/WAL/replication-slot consumer. P062's contract is met; a CDC connector is still MISSING. 3. **0pt does not schedule itself.** `opt_source_schedule` is a declaration ACT0 would read; there is no cron daemon here. 4. **The sink is caller-supplied.** The runner stops at the sink; the lakehouse write boundary is ST0RE's (P066, another workflow's repo). 5. **Nothing here is deployed.** See the deployment note below. 6. **`QualityService`'s own rule/run/issue registry is still in-process Maps** (`src/quality/quality-service.ts:47-50`). The new *enforcement* path is durable; the older rule registry is not. Unchanged by this pass. 7. **Python tests still run nowhere.** `grep -rn "pytest" .gitea/workflows .github/workflows` finds nothing — `services/api/tests/*` (9 files) has never been executed by CI. Flagged, not fixed (it needs a workflow change and a Python toolchain decision). ### Deployment reality, measured 2026-09-04 `https://0pt.app/api/health` answers **200** from **Vercel** with `{"db":"not_configured"}`, and `https://0pt.app/api/0pt/sources` answers **404** — the deployed build predates the entire `app/api/0pt/*` capability layer. `https://api.0pt.app/health` answers **404** (the FastAPI engine is not reachable), and `.gitea/workflows/cd.yml` still guards on `COOLIFY_APP_ID = TODO-no-coolify-app-provisioned-yet`. So: none of the capability layer — neither this pass's work nor P010/P014's — is running in production, and P060's durability guarantee cannot be exercised there, because production has no database configured and does not serve the routes. Verified with `curl`; not inferred. ### P065 — closure record (2026-09-07) The removal plan below was executed in full and is verified in CI: 1. ✅ Canonical ER exposed as `POST /api/0pt/er/candidates` (public, tenant-safed) AND `POST /api/0pt/internal/er/candidates` (service-token, fails closed without `X-Internal-Token`). 2. ✅ Python CI job: `.gitea/workflows/python-engine.yml` runs `services/api/tests` as a BLOCKING pytest gate. 3. ✅ `workers/resolve.py` rewritten as the HTTP adapter — fail-closed to UNMERGED records when the bridge is unreachable; no fallback scorer remains. Cluster-wide hard-negative constraints prevent transitive matches from overriding canonical identity decisions. 4. ✅ `services/api/tests/test_resolve_determinism.py` asserts the adapter contract: canonical match edges merge; review/non-match edges do not; hard negatives are respected transitively. Residual honesty: the PYTHON-side tests run in CI, but the full adapter→Next.js route chain has not been exercised against a live deployed edge in this branch (the route's own fail-closed behavior is unit-proven). That keeps P065 at INTEGRATION_TESTED, not LIVE_VERIFIED. --- ## SLUTPRODUKTIONS-VERIFIERING 2026-09-22 (live-mätt, ej påstått) **Prod: `https://0pt.app` på flottan (server6, Coolify-app `shxd6lepxuxfsjsp0ath3z1g`), container-image på exakt merge-SHA `df6ab70` via den signerade release-kedjan (cosign-attestation verifierad före redeploy). DNS A → 65.109.19.146, NS chris/maxine.ns.cloudflare.com — Vercel är borta.** ### Live-matris, mätt med curl (2026-09-22 04:09 UTC) | Yta | Resultat | |---|---| | Front `/` + 10 nyckelsidor (bestall, katalog, kallor, tjanster, portal, admin, order) | 200 ×11 | | `/api/health` | 200 `{ok:true, db:"ok", engine:"ok"}` | | `/api/ready` | 200 (fail-closed-grinden: var 503 före DB-provisioneringen) | | `/api/0pt/*` (9 rutter) anonymt | **401 ×9** — S1-luckan (2026-08-07: anonym 200) är STÄNGD | | `/api/orders`, `/api/admin/metrics` anonymt | 401 | | `/api/subscriptions` | 200 `[]` (var 500: migration 014, se nedan) | | `POST /api/estimates` | 200 (edge räknar + engine-wire) | | `GET /api/catalog`, `/api/sources` | 200 (publika läsvyter, avsiktligt) | | `GET /api/vehicles` utan param | 400 (kräver reg-nr — korrekt) | | Security headers | HSTS(63072000+preload) · CSP · XFO DENY · nosniff · ingen X-Powered-By | ### Denna pass fixat (3 PR, alla mergerade + deployade live) 1. **PR #80** — G17 hook-pin re-bump `7725498 → a401880` (re-review: 0 diff under `ci/v2/reference-hooks/`). Release chain + gated deploy gröna igen. 2. **PR #81 (fix för issue #53)**: 7 legacy money-routes (orders, orders/[id], subscriptions, payments/deposit, payments/release, webhooks/stripe, admin/metrics) mappar nu `SiaxError(DEPENDENCY_UNAVAILABLE, 503, retryable)` via `app/api/siax-error-mapping.ts` i stället för att läcka Next opaka 500. Stripe-webhooken svarar 503 `received:false reason:store_unavailable` på store-outage — aldrig tyst `received:true` för ett betalt event som inte processats. 3 nya tester pinar kontraktet. 3. **PR #86**: `sql/014_subscriptions_created_at.sql` — `lib/subscriptions-store.ts` SELECT:ade `created_at` som `001_init.sql` aldrig definierat (42703 mätt live: GET /api/subscriptions har ALWAYS varit 500 mot Postgres). Kolonnen ADD:ad idempotent LIVE på 0pt-edge-postgres; route svarar nu 200 `[]`. 4. **PR #87**: cd-gatens not-ready-regex — cosign 3.1.3 säger `no matching attestations:` (utan `found`); en transient not-ready misstolkades som hårt verify-fel. Fail-closed för riktiga attestfel oförändrad. 5. **CI-infra reparerad**: repo-secrets `SIAX_CI_TOKEN` + `REGISTRY_TOKEN` var döda efter token-svepet (2026-09-22 eng0-introspect-rotation revoade 107+ tokens; fällan: 0pt:s repo-secret överrider org-secreten — org-PUT räcker inte). Nya siax-ci-tokens (`write:package,read:package` + all) mintade och satta via secrets-API (PUT 204, verifierade via lyckad release-kedja). ### 0pt-motor (engine, satellite) - 6 containers Up på server6 (`motor-provisional`), core `/health` ok+pg+redis, delivery `/version` = fb67870, core revision = 6cfd433 — båda IN main. - CI grön på main (runs 55985/55987/56004) — healer-issue #38 (run 40562, 2026-09-20) stängd som transient runner-flake (apt-GPG under last). - Bara `main` kvar i 0pt och 0pt-motor (8 + 6 stale grenar raderade — alla bevisade redan mergerade via `git merge-base --is-ancestor`). - motor/-executor-koden (signals/NER/normalization, 3507 rader nya sedan 6cfd433) konsumeras av `Dockerfile.motor`-imaget som ännu inte har ett driftsatt runtime i stacken (core/ingest/resolve/delivery importerar ej motor/ — verifierat import-graf). Byggs enligt `scripts/build-images.sh` + `verify-image.sh`-gaten när executor-ytan aktiveras — dokumenterat i `docs/runbook/deploy.md`. ### Kvarstår (ärligt, ej gömt) 1. **Stripe-creds** (Simon): live-keys → edge-envs `STRIPE_SECRET_KEY`/`STRIPE_WEBHOOK_SECRET`. Innan dess förblir payments 501 och issue #67:s staging-triage kan ej köras. 2. **queue: not_configured** — ingen Redis i edge-stacken (ärligt rapporterat). 3. **`0pt.siax.io`/`motor.siax.io`**: medvetet ej återupprättade (0pt.app + lokala 127.0.0.1-portar är kanoniska ytor; issues #70/#35 stängda/avgjorda därefter). 4. **motor.siax.io**: motor:s publika yta kräver Simon-beslut (traefik-labels + DNS).