106 Commits
Author SHA1 Message Date
admin 446b9aa299 fix(portal): one idempotency key per selected file
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (push) Successful in 6s
masterplan-lock / check (pull_request) Successful in 6s
CI (SIAX Cloud) / security (pull_request) Successful in 17s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 34s
CI (SIAX Cloud) / quality (pull_request) Successful in 10m37s
CI (SIAX Cloud) / integration (pull_request) Successful in 10m40s
A double click or a retry after a network error generated a new key each time
and therefore a duplicate document. The key is now stable until the file
selection changes, so the same upload returns the same verified receipt.
2026-11-03 00:51:42 +01:00
admin 4ea55c74bb fix(credits): import the trial-credit helper in the balance route
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (push) Successful in 3s
masterplan-lock / check (pull_request) Successful in 6s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 46s
CI (SIAX Cloud) / security (pull_request) Successful in 46s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m17s
CI (SIAX Cloud) / integration (pull_request) Successful in 9m47s
The call was added without its import, so GET /api/0pt/credits/balance
returned CREDITS_UNAVAILABLE (readTrialCredits is not defined). Caught live
right after enabling trial credits.
2026-11-02 22:27:19 +01:00
admin dade37ee05 feat(credits): one-time trial grant so the ledger runs in production
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 4s
masterplan-lock / check (push) Successful in 5s
CI (SIAX Cloud) / security (pull_request) Successful in 16s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / integration (pull_request) Successful in 9m58s
CI (SIAX Cloud) / quality (pull_request) Successful in 10m25s
- Ledger accepts kind='grant' (a server-owned balance grant, not a payment).
- OPT_TRIAL_CREDITS=N grants N credits once per tenant (idempotent key
  trial:<tenant>) on balance/structure, so reserve -> settle is exercised
  before any customer purchase.
- sql/020 extends the kind constraint (re-runnable).
- Tests for the grant helper; full suite 1345 passed.
2026-11-02 22:05:06 +01:00
admin a0dd6b7653 fix(live): refuse billing in pilot mode and explain unparsed documents
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 3s
masterplan-lock / check (push) Successful in 14s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 18s
CI (SIAX Cloud) / security (pull_request) Successful in 23s
CI (SIAX Cloud) / quality (pull_request) Successful in 54s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m2s
- Checkout returns 503 CREDITS_DISABLED while OPT_CREDITS_MODE=off, so a
  customer can never pay for credits that the pipeline will not consume.
- Packs expose purchases_enabled; the portal hides Buy and says billing is off.
- Structuring an unparsed document (e.g. a scanned PDF with no text layer) now
  answers 422 DOCUMENT_NOT_PARSED instead of a generic INVALID_REQUEST.
2026-11-02 20:14:12 +01:00
admin c01deca048 ci: optimize delivery pipelines and add a production smoke gate
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (push) Successful in 5s
masterplan-lock / check (pull_request) Successful in 10s
CI (SIAX Cloud) / security (pull_request) Successful in 19s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 21s
CI (SIAX Cloud) / integration (pull_request) Successful in 40s
CI (SIAX Cloud) / quality (pull_request) Successful in 2m13s
- One run per ref (concurrency) for CI, security, nightly and release; branch
  pushes no longer duplicate pull_request runs (push is main-only).
- Deploys keep their own concurrency group so two runs never race Coolify.
- pnpm store cache on every Node job.
- New /api/version returns the deployed commit (no secrets).
- New scheduled prod-smoke workflow: readiness, db/stripe health, running
  commit == main, and the document/credit routes exist (401/405, never 5xx).
2026-11-02 18:24:45 +01:00
admin 9e9de93715 fix(credits): amount_minor is öre, divide before formatSEK
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (push) Successful in 4s
masterplan-lock / check (pull_request) Successful in 7s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / security (pull_request) Successful in 17s
Security Scan (SIAX Cloud) / security (push) Successful in 23s
CI (SIAX Cloud) / security (push) Successful in 24s
CI (SIAX Cloud) / integration (pull_request) Successful in 29s
CI (SIAX Cloud) / quality (pull_request) Successful in 46s
CI (SIAX Cloud) / quality (push) Successful in 52s
The pack list showed 9 900 kr for a 99 kr pack. formatSEK takes kronor; every
other öre amount in the app is divided by 100 first.
2026-11-02 16:51:50 +01:00
admin 48dff2078e fix(admission): zero maximumCredits means pilot mode, not a missing reservation
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 5s
CI (SIAX Cloud) / security (push) Successful in 17s
Security Scan (SIAX Cloud) / security (push) Successful in 17s
CI (SIAX Cloud) / quality (push) Successful in 46s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 5s
CI (SIAX Cloud) / security (pull_request) Successful in 23s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 25s
CI (SIAX Cloud) / integration (pull_request) Successful in 45s
CI (SIAX Cloud) / quality (pull_request) Successful in 59s
The structure route ran the model with maximumCredits=1 and no reservation when
credits were off, so admission returned reservation_required and the route
answered 502. Admission now requires a reservation only when maximumCredits>0.

Verified against the live stack: DOC0 segments -> LiteLLM/Ollama
(inf0-valuation) -> evidence validation -> needs_review (no export).
2026-11-02 16:42:01 +01:00
admin 581a20acd1 chore(workbench): log the structure failure reason and source segment count
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (push) Successful in 6s
masterplan-lock / check (pull_request) Successful in 8s
CI (SIAX Cloud) / security (pull_request) Successful in 26s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 26s
CI (SIAX Cloud) / security (push) Successful in 38s
Security Scan (SIAX Cloud) / security (push) Successful in 53s
CI (SIAX Cloud) / quality (push) Successful in 55s
CI (SIAX Cloud) / integration (pull_request) Successful in 58s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m4s
Cloudflare replaces an origin 502 body with its own error page, so the JSON
message never reached the client. Log the reason server-side (codes/messages
only, never source text).
2026-11-02 16:32:55 +01:00
admin e93db5fc1f fix(doc0): call DOC0 as the granted service actor
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (pull_request) Successful in 3s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 15s
CI (SIAX Cloud) / security (pull_request) Successful in 1m2s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m11s
masterplan-lock / check (push) Successful in 1m38s
CI (SIAX Cloud) / quality (push) Successful in 1m49s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m50s
DOC0 denies an x-actor-id that the service identity has no actor_grant for, so
every upload/structure call from 0pt failed with DOC0_ACCESS_DENIED and became
outcome_unknown. The journal and project authorization keep the verified
end-user actor; only the DOC0 request acts as the service (DOC0_SERVICE_ACTOR_ID).
2026-11-02 16:17:29 +01:00
admin 35937933b3 chore(auth): log the OIDC failure code (no tokens or claims)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 5s
masterplan-lock / check (push) Successful in 8s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / security (push) Successful in 23s
Security Scan (SIAX Cloud) / security (push) Successful in 23s
CI (SIAX Cloud) / integration (pull_request) Successful in 28s
CI (SIAX Cloud) / quality (pull_request) Successful in 46s
CI (SIAX Cloud) / quality (push) Successful in 54s
2026-11-02 15:58:52 +01:00
admin 71391db132 fix(auth): fall back to the verified access token for the tenant claim
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 4s
masterplan-lock / check (pull_request) Successful in 4s
Security Scan (SIAX Cloud) / security (push) Successful in 14s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / quality (push) Successful in 1m8s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / security (pull_request) Successful in 14s
CI (SIAX Cloud) / integration (pull_request) Successful in 27s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m3s
Zitadel does not always copy urn:zitadel:iam:org:id into the id_token; the
access token always carries it. Verify that token (issuer) before trusting its
tenant.
2026-11-02 15:48:51 +01:00
admin 023406c9b6 feat(auth): Zitadel OIDC login for the portal
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 3s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 5s
Security Scan (SIAX Cloud) / security (push) Successful in 14s
CI (SIAX Cloud) / security (push) Successful in 21s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / security (pull_request) Successful in 23s
CI (SIAX Cloud) / integration (pull_request) Successful in 28s
CI (SIAX Cloud) / quality (push) Successful in 48s
CI (SIAX Cloud) / quality (pull_request) Successful in 45s
The portal had no way to obtain a verified principal: /api/0pt/* requires a
Bearer token, but the browser only had the dev-only HMAC cookie.

- GET /api/auth/login: Authorization Code + PKCE against Zitadel.
- GET /api/auth/callback: code exchange, id_token verification (issuer,
  audience, nonce) and a signed session cookie with sub + tenant.
- middleware accepts the signed session as a verified principal; Bearer wins.
- dev login POST is refused in production.
- Sign-in link in the portal shell.
2026-11-02 15:48:02 +01:00
admin d12b8fa55f feat(workbench): explicit pilot mode without a credit wallet
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / security (push) Successful in 16s
Security Scan (SIAX Cloud) / security (push) Successful in 16s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 20s
masterplan-lock / check (pull_request) Successful in 23s
CI (SIAX Cloud) / security (pull_request) Successful in 24s
CI (SIAX Cloud) / quality (push) Successful in 48s
CI (SIAX Cloud) / integration (pull_request) Successful in 54s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m12s
OPT_CREDITS_MODE=off skips reserve/settle and reports credits:null, so the
document flow can be piloted before prices are decided. It is never a silent
fallback and purchases remain disabled.
2026-11-02 15:31:52 +01:00
admin f928ac1c78 chore(portal): retire the dead metadata-only upload page
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (pull_request) Successful in 4s
masterplan-lock / check (push) Successful in 12s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 21s
CI (SIAX Cloud) / security (push) Successful in 30s
CI (SIAX Cloud) / quality (push) Successful in 1m23s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / security (pull_request) Successful in 14s
CI (SIAX Cloud) / integration (pull_request) Successful in 46s
CI (SIAX Cloud) / quality (pull_request) Successful in 57s
/portal/files only sent name/mime/size and always hit the 501 storage stub.
Redirect it to /portal/dokument (real bytes) and remove it from both navs.
2026-11-02 15:16:10 +01:00
admin ed8b64e921 fix(portal): explicit, server-listed data class for document structuring
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (pull_request) Successful in 4s
masterplan-lock / check (push) Successful in 4s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
CI (SIAX Cloud) / security (push) Successful in 26s
CI (SIAX Cloud) / security (pull_request) Successful in 37s
CI (SIAX Cloud) / integration (pull_request) Successful in 43s
CI (SIAX Cloud) / quality (push) Successful in 1m7s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m8s
Never assume 'low'; the UI offers only the server-approved data classes and
the route refuses external models for high/restricted data.
2026-11-02 15:04:33 +01:00
admin e3c4bc28c3 feat(workbench): live LiteLLM gateway adapter + explicit project grants
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 6s
masterplan-lock / check (push) Successful in 6s
CI (SIAX Cloud) / security (push) Successful in 14s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / security (pull_request) Successful in 21s
Security Scan (SIAX Cloud) / security (push) Successful in 25s
CI (SIAX Cloud) / integration (pull_request) Successful in 29s
CI (SIAX Cloud) / quality (pull_request) Successful in 51s
CI (SIAX Cloud) / quality (push) Successful in 1m29s
- createInf0Gateway prefers the live OpenAI-compatible LiteLLM gateway and
  falls back to the native INF0 surface; admission stays local and fail-closed.
- Project authorization: OpenFGA when configured, otherwise a validated
  server-owned OPT_PROJECT_GRANTS list (deny by default).
- Tests for the gateway adapter, the factory and grants.
2026-11-02 14:50:50 +01:00
admin b3239487b7 feat(document-workbench): wire customer upload, structuring, credits and readiness
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 10s
CI (SIAX Cloud) / sonar (pull_request) Skipped
Security Scan (SIAX Cloud) / security (push) Successful in 13s
masterplan-lock / check (pull_request) Successful in 7s
CI (SIAX Cloud) / security (push) Successful in 26s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / quality (push) Successful in 1m9s
CI (SIAX Cloud) / quality (pull_request) Successful in 2m26s
CI (SIAX Cloud) / integration (pull_request) Successful in 2m33s
- POST /api/0pt/documents/upload: real multipart bytes into DOC0 through the
  durable attempt journal and the existing coordinator; verified tenant/actor
  only, project authorization fail-closed.
- POST /api/0pt/documents/structure: DOC0 segments -> INF0 -> evidence-bound
  validation -> optional JSON/CSV export, with credit reserve/settle.
- Credits: balance, server-owned price book, Stripe Checkout and idempotent
  webhook reconciliation via a Stripe re-read of session + payment intent.
- /portal/dokument and /portal/krediter: SIAX-styled workspace.
- @siax/access: universal, framework-neutral OpenFGA project relationship
  primitive reusable by DOC0/N0D/other products.
- Readiness: real Redis PING probe instead of presence-only; queue is now a
  live dependency when configured.
- Dockerfile: copy every workspace manifest so --frozen-lockfile works.
- Format/build hygiene: .prettierignore, .worktrees ignored, valid manifest YAML.
2026-11-02 14:46:10 +01:00
admin 5137bf87a1 fix: distinguish failed sources from empty results
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / security (push) Successful in 15s
masterplan-lock / check (pull_request) Successful in 7s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / security (pull_request) Successful in 20s
CI (SIAX Cloud) / integration (pull_request) Successful in 35s
CI (SIAX Cloud) / quality (pull_request) Successful in 39s
CI (SIAX Cloud) / quality (push) Successful in 48s
2026-11-02 06:58:15 +01:00
admin bd1c20edb2 feat: add guarded document workbench foundations
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 5s
Security Scan (SIAX Cloud) / security (push) Successful in 15s
CI (SIAX Cloud) / security (push) Successful in 16s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 7s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 21s
CI (SIAX Cloud) / security (pull_request) Successful in 25s
CI (SIAX Cloud) / quality (push) Successful in 1m17s
CI (SIAX Cloud) / integration (pull_request) Successful in 54s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m7s
2026-11-02 01:26:36 +01:00
admin 1c87b82e70 feat(import): ImportDispatchPolicy (DES1GN ADR D3 §31) — ett objekt, en sanning
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 6s
masterplan-lock / check (pull_request) Successful in 7s
CI (SIAX Cloud) / security (push) Failing after 27s
Security Scan (SIAX Cloud) / security (push) Failing after 1m27s
CI (SIAX Cloud) / quality (push) Successful in 1m28s
CI (SIAX Cloud) / quality (pull_request) Successful in 2m29s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m15s
CI (SIAX Cloud) / security (pull_request) Failing after 16s
CI (SIAX Cloud) / sonar (pull_request) Skipped
Security Scan (SIAX Cloud) / security (pull_request) Failing after 17s
- lib/import-dispatch-policy.ts: maxInlineRows=500 (inline-tak, oförändrat
  kontrakt), maxRows=5000 (N0D-dispatch-signal), maxBytes=1_000_000 (bytes,
  UTF-8), format-allowlist ['csv']; ren evaluateImportDispatch() med
  deterministisk precedens format > bytes > rows
- route: taken härstammar från policyn; bytes-koll (ersätter chars); rows >
  maxRows -> 413 n0d_dispatch_required med hint {capability_id:
  0pt.import_execute, job_type: 0pt.import_execute_job, status: UNVERIFIED}
  (descriptor-gate stängd: aldrig tyst trunkering, aldrig tyst dispatch)
- tester: 9 nya (verdict per kombination inkl. gränsvärden 500/501/5000/5001,
  bytes-gräns, allowlist, precedens; route-koppling 200/413/413) — 21/21 gröna
  i sviten; full N0D-worker-integration markeras UNVERIFIED
2026-09-30 21:48:16 +02:00
admin 04813c34b0 feat(collab): order-anteckningar — @siax/collaboration-kernelns första produktkonsument (spår C)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 7s
Security Scan (SIAX Cloud) / security (push) Successful in 16s
CI (SIAX Cloud) / security (push) Successful in 18s
masterplan-lock / check (pull_request) Successful in 8s
CI (SIAX Cloud) / quality (push) Failing after 33s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 22s
CI (SIAX Cloud) / integration (pull_request) Successful in 31s
CI (SIAX Cloud) / security (pull_request) Successful in 23s
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / quality (pull_request) Failing after 21s
Kernel 0.3.0 används som capability, inte som paket-dekor:
- lib/order-notes-store.ts: varje note ÄR en CollaborationOperation;
  nextLamportClock för nya klockor, mergeOperationLog/compareOperations
  för deterministisk listning; optimistisk version -> 409 vid stale skrivning.
- lib/order-notes-client.ts: kernel-CollaborationTransport över host-API;
  offline = medvetet no-op + varning (ingen tyst förlust), 409 -> ConflictError.
- app/api/admin/order-notes: requireRouteAuth (fail-closed 401),
  server-authoritative tenant-guard (403), AUD0-audit via hostens klient.
- app/admin/notes: admin-yta med offline-växel, konflikt-banner + reload.
- sql/016_order_notes.sql: persistens (DB-tabell, version + Lamport-klocka).

Tester: API (happy/conflict 409/empty/400/401/403/404), klient-adapter
(offline no-op utan fetch, 409-mappning, presence), SSR-render. 18 nya test.
2026-09-30 17:07:21 +02:00
admin c1648c04a7 feat(orders): CSV-import admin-yta — första riktiga ImportWizard-värden (C8)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / security (push) Successful in 22s
Security Scan (SIAX Cloud) / security (push) Successful in 22s
masterplan-lock / check (push) Successful in 31s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 6s
CI (SIAX Cloud) / security (pull_request) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 20s
CI (SIAX Cloud) / quality (push) Successful in 1m1s
CI (SIAX Cloud) / integration (pull_request) Successful in 30s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m56s
Symmetrisk mot våg 3.4 CSV-export: POST /api/orders/import (validate |
dry_run | execute) + /admin/import som renderar @siax/ui ImportWizard
(0.14.0) över @siax/import-export runtime (0.2.0).

- Servern är enda auktoritet: RFC4180-parse (ingen eval), omvalidering
  via frysta @siax/contracts-kerneln (validateRows) + hostregler,
  exekvering genom BEFINTLIG orderlogik (createOrder, tenant-guardad).
- Fail-closed: 401 utan principal, 400 okänd header, 413 vid radtak
  (500), per-rad-atomsäkra inserts — felrad kan aldrig skada OK-rader.
- Partiell import: OK-rader skapas, felrader rapporteras per rad
  (row/field/code). AUD0-audit via 0pts enda producer-boundary
  (durable outbox under DATABASE_URL).
- Reload-persistens: efter execute läses /api/orders om och de nya
  raderna listas på sidan.
- Tester: 12 route-test (happy, partial, auth fail-closed, tak,
  no-write validate, header, quoting, rad-fel mitt i batch) + 3
  SSR-render-test av ImportWizard över runtime-storen.
- Deps: @siax/ui ^0.14.0, @siax/charts ^0.5.0, @siax/import-export
  ^0.2.0; pnpm-overrides till contracts 0.10.0 / import-export 0.2.0
  (ui 0.14.0 deklarerar 0.11.0/0.2.1 som ännu ej publicerats).
2026-09-30 15:36:02 +02:00
admin c3582838aa feat(orders): kanonisk statusmaskin + guardad DB-constraint (ADR-0002, C3)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 1m3s
CI (SIAX Cloud) / security (push) Successful in 1m4s
Security Scan (SIAX Cloud) / security (push) Successful in 1m7s
CI (SIAX Cloud) / quality (push) Successful in 1m52s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 6s
CI (SIAX Cloud) / security (pull_request) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m20s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m58s
2026-09-29 21:15:35 +02:00
admin bc76ebc5e5 feat(orders): CSV-export-endpoint — export-kernelns första adoption (våg 3.4)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 14s
CI (SIAX Cloud) / security (push) Failing after 16s
CI (SIAX Cloud) / quality (push) Successful in 52s
Security Scan (SIAX Cloud) / security (push) Successful in 58s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 5s
CI (SIAX Cloud) / security (pull_request) Successful in 15s
CI (SIAX Cloud) / quality (pull_request) Successful in 37s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 45s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m35s
CI (SIAX Cloud) / security (push) Trivy vulndb 404 (mirror.gcr.io) - infra-flake; re-run pa identisk sha gron
2026-09-29 17:01:13 +02:00
admin a2377215e7 feat(admin): InboxList — orderkön som universal inkorg (våg 3.3-adoption)
CI (SIAX Cloud) / sonar (pull_request) Skipped
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (pull_request) Successful in 7s
masterplan-lock / check (push) Successful in 8s
CI (SIAX Cloud) / security (pull_request) Successful in 19s
Security Scan (SIAX Cloud) / security (push) Successful in 20s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 23s
CI (SIAX Cloud) / security (push) Successful in 24s
CI (SIAX Cloud) / integration (pull_request) Successful in 31s
CI (SIAX Cloud) / quality (push) Successful in 44s
CI (SIAX Cloud) / quality (pull_request) Successful in 2m13s
Servern projicerar öppna ordrar (draft/quoted/in_production/review) på
universal-inbox-konvolverna via createInboxItem (buildOrderInboxItem i
lib/order-flow, ADR-0001-mönstret: policy/resolution i serverlagret).
Admin renderar InboxList (@siax/ui 0.11.1) ovanpå orderkön — resolve-
aktionen gateras genom advance_action-state (available krävs). Terminala
statusar ger ingen post. tests/order-flow 6/6; full svit 1144/1144; build ✓.
2026-09-29 16:10:10 +02:00
admin a49bc148fc feat(admin): authz-pilot — server-renderad advance-resolution + ActionGate (ADR-0001)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 7s
masterplan-lock / check (push) Successful in 8s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
CI (SIAX Cloud) / security (pull_request) Successful in 20s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 19s
CI (SIAX Cloud) / quality (push) Failing after 1m31s
CI (SIAX Cloud) / quality (pull_request) Failing after 1m33s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m34s
GET /api/orders returnerar per order frozen advance_action (resolveAction ur
lib/order-flow); admin renderar via ActionGate — policy i serverlagret,
presentation i klienten (DoD §21). Terminala/okända statusar → read_only med
varför-text i stället för missvisande 'klar'. tests/order-flow.test.ts 3/3;
full svit 1138 godkända; typecheck grön.
2026-09-29 12:21:02 +02:00
admin d3afc40ef4 feat(katalog): filter + sök + flikval i URL:en (kernel URL-state-konventionen)
CI (SIAX Cloud) / integration (push) Skipped
CI (SIAX Cloud) / sonar (push) Skipped
masterplan-lock / check (push) Successful in 6s
CI (SIAX Cloud) / sonar (pull_request) Skipped
masterplan-lock / check (pull_request) Successful in 8s
CI (SIAX Cloud) / security (pull_request) Successful in 34s
CI (SIAX Cloud) / quality (push) Successful in 53s
CI (SIAX Cloud) / quality (pull_request) Successful in 56s
CI (SIAX Cloud) / integration (pull_request) Successful in 58s
Security Scan (SIAX Cloud) / security (push) Successful in 1m10s
CI (SIAX Cloud) / security (push) Successful in 1m12s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 1m4s
Live-auditen 2026-09-28 fann tre bryt: filter+sök försvann vid 'Tillbaka' från
detaljsida, flikval saknade URL-state, brödsmulan ledde till startsida.

- /katalog: q och filter kanoniskt i searchParams (debounce 250 ms på skrivtick,
  router.replace scroll:false) — Tillbaka återställer exakt vy, delad länk öppnar
  samma filtrering. Suspense-wrapper krävs av useSearchParams vid prerender.
- /katalog/[id]: flikval i ?tab= (overview = parametern frånvarande — kanonisk
  URL), piltangentsnavigering oförändrad.
- Brödsmulan länkar /katalog (inte /#katalog → startsida).

Verifierat: blocking-gate typecheck med SAMMA 2 förbefintliga fel som main
(noll nya), typecheck:app noll katalog-fel.
2026-09-28 15:54:11 +02:00
SimonandClaude Opus 5 e3930aa633 fix(a11y): ta bort alfa-tonad textfärg — 82 kontrastöverträdelser (UI-09)
CI (SIAX Cloud) / integration (push) Skipped
masterplan-lock / check (push) Successful in 7s
Security Scan (SIAX Cloud) / security (push) Successful in 20s
CI (SIAX Cloud) / security (push) Successful in 47s
masterplan-lock / check (pull_request) Successful in 10s
CI (SIAX Cloud) / quality (push) Successful in 1m11s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 32s
CI (SIAX Cloud) / security (pull_request) Successful in 42s
CI (SIAX Cloud) / integration (pull_request) Successful in 56s
CI (SIAX Cloud) / quality (pull_request) Successful in 59s
axe-core 4.10.2 mot 0pt.app 2026-09-26: en enda regel, color-contrast,
impact=serious, 82 noder. Estatets största enskilda a11y-defekt. Alla 82
har samma form: en Tailwind-alfamodifierare på en textfärg.

Uppmätt WCAG 2.2-kontrast mot bägge temabakgrunderna i styles/globals.css:

  text-muted-foreground        4.73:1 ljust   7.63:1 mörkt   GODKÄNT
  text-muted-foreground/70     2.71:1         4.20:1         faller
  text-muted-foreground/60     2.29:1         3.37:1         faller
  text-muted-foreground/50     1.96:1         2.67:1         faller
  text-muted-foreground/40     1.69:1         2.11:1         faller
  text-foreground/20           1.57:1         1.74:1         faller

Den omodifierade token klarar AA i bägge teman, så åtgärden är helt enkelt
att aldrig tona den. Elva textställen bytte till text-muted-foreground.
Kopieringsknappen i app/portal går från 1.57:1 till 4.73:1 i viloläge och
19.79:1 vid hover — den föll även 1.4.11 för icke-textkomponenter.
Toastens stängknapp klarade redan 1.4.11 (3.71:1) men blir 4.73:1.

Kvar med alfa är endast den dekorativa masthead-siffran i app/bestall, som
redan bär aria-hidden + select-none + pointer-events-none. Den är undantagen
både av WCAG och av axe, och guarden nedan tillåter den på just den grunden.

scripts/ci/check-text-contrast.mjs är en blockerande källkodsgrind i
quality-jobbet. Den är avsiktligt inte en axe-körning: den fullständiga
axe-jobb som UI-09 också begär kräver build + serve i CI och spåras separat.
Tills det finns stoppar den här grinden regressionen vid den form som
orsakade defekten.

Refs: UI-09
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-27 01:27:28 +02:00
Claude 0062edbec3 fix(readiness): /api/ready svarade 200 med en död motor i produktion
CI (SIAX Cloud) / integration (push) Skipped
masterplan-lock / check (push) Successful in 6s
CI (SIAX Cloud) / security (push) Successful in 15s
masterplan-lock / check (pull_request) Successful in 4s
Security Scan (SIAX Cloud) / security (push) Successful in 27s
CI (SIAX Cloud) / security (pull_request) Successful in 23s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 24s
CI (SIAX Cloud) / quality (push) Successful in 45s
CI (SIAX Cloud) / integration (pull_request) Successful in 31s
CI (SIAX Cloud) / quality (pull_request) Successful in 40s
Mätt live 2026-09-25 mot produktionsdeployen (0pt.app / api.0pt.app,
container shxd6lepxuxfsjsp0ath3z1g-172514162615 på server6, uppe 17,9 h,
Docker-status "healthy" hela tiden):

    GET /api/health -> HTTP/1.1 200 OK
      {"ok":false,"service":"0pt-web","db":"ok","queue":"not_configured",
       "engine":"error","stripe":"not_configured",
       "detail":{"engine":"This operation was aborted"}}

    GET /api/ready  -> HTTP/1.1 200 OK
      {"ready":true,"service":"0pt-web","db":"ok","engine":"error",...}

ENGINE_URL pekade på http://0pt-engine:8000. Mätt inifrån containern:
`getent hosts 0pt-engine` ger ingen post, och det finns ingen sådan
container på någon av server5-11. Ett direktanrop mot motorn misslyckas
efter ~5 s (DNS). Datamotorn — 0pt:s hela produkt — var alltså BORTA, och
samtliga signaler ovanför den var gröna: Docker healthy, /api/health 200,
/api/ready 200.

`ok:false` i en 200-kropp är ingen signal. Ingenting i kedjan läser
kroppar; allt läser statuskoder och exitkoder.

isReady skilde tidigare bara på "db ok". Den skillnad som saknades är inte
konfigurerad-vs-ej-konfigurerad utan FRÅNVARANDE-vs-TRASIG:

  * not_configured / not_integrated -> fortsatt ready. 0pt är byggt för att
    kunna köra utan motor, Stripe och kö (se .env.example).
  * error -> INTE ready. Statusen "error" betyder att någon medvetet
    konfigurerade beroendet och att en riktig round trip mot det just
    misslyckades. Det är inte längre en valfri integration.

Ändrar ingenting i driften i dag: container-HEALTHCHECK pekar på
/api/health (liveness) och Dockerfilen säger uttryckligen att en
readiness-probe inte ska peka dit. Den här ändringen gör bara att den
ärliga ytan faktiskt blir ärlig, så en yttre övervakning kan använda den.

Regressionstest tillagt; verifierat att det FALLER mot den gamla isReady
(1 failed | 18 passed) och passerar mot den nya (24 passed över
health-checks/ready/health).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-25 13:34:42 +02:00
Claude Code fc1a62bb81 feat: decision-plane wiring — ER-pair decision.match tie-break (@siax/0pt-decision)
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (push) Successful in 15s
masterplan-lock / check (pull_request) Successful in 11s
CI (SIAX Cloud) / security (pull_request) Successful in 14s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / integration (pull_request) Successful in 25s
CI (SIAX Cloud) / quality (push) Failing after 32s
CI (SIAX Cloud) / quality (pull_request) Failing after 33s
CI (SIAX Cloud) / integration (push) Has been skipped
- packages/decision: erMatchDecision (0pt.er.pair_match mot siax-decision :4600)
- comparePair async + borderline-band (±0.05 av review_threshold) → decision.match
  (D1 advisory) — deterministisk status GÄLLER om decision abstainar
- OPT_DECISION_ER_ENABLED=1-gate (off tills kalibrering)
- tests async-anpassade (await generateCandidates/rejects.toThrowError)
- typecheck: 13 fel = pre-existing extraction-route (main-paritet), 0 nya fel
- tester: 1108 passed | 184 skipped
2026-09-23 00:15:27 +02:00
admin 21d51194b7 feat(seo): robots.txt + sitemap.xml — crawler-kontraktet saknades helt (404 mätt live)
CI (SIAX Cloud) / integration (push) Has been skipped
masterplan-lock / check (push) Successful in 5s
masterplan-lock / check (pull_request) Successful in 5s
CI (SIAX Cloud) / security (push) Successful in 13s
Security Scan (SIAX Cloud) / security (push) Successful in 14s
CI (SIAX Cloud) / security (pull_request) Successful in 14s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 15s
CI (SIAX Cloud) / quality (push) Successful in 53s
CI (SIAX Cloud) / integration (pull_request) Successful in 1m1s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m10s
Publik marknadsföringssajt utan robots/sitemap = crawlers rattningslös.
- robots.ts: allow /, disallow portal/admin/order/api (inloggnings-ytor)
- sitemap.ts: 7 publika ytor, weekly
2026-09-22 09:57:15 +02:00
admin c7fd9d45a2 fix(prod): map SiaxError in the 7 legacy money routes — DEPENDENCY_UNAVAILABLE/503 instead of opaque 500 (0pt#53)
CI (SIAX Cloud) / integration (push) Has been skipped
masterplan-lock / check (pull_request) Successful in 3s
masterplan-lock / check (push) Successful in 3s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (push) Successful in 14s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 18s
CI (SIAX Cloud) / quality (pull_request) Successful in 31s
CI (SIAX Cloud) / quality (push) Successful in 40s
CI (SIAX Cloud) / security (pull_request) Successful in 42s
CI (SIAX Cloud) / integration (pull_request) Successful in 45s
getSqlForDurableStore throws SiaxError(DEPENDENCY_UNAVAILABLE, httpStatus 503,
retryable) when a money-bearing store would fall back to an in-memory Map in a
production runtime (the durable-store guard). The /api/0pt/* surface already
maps it via src/http/siax-error-response.ts; the seven legacy routes outside
the middleware matcher did not — the documented 503 leaked as Next's opaque
500 with no body.

- app/api/siax-error-mapping.ts: shared isSiaxError + siaxErrorResponseForLegacy
- orders (POST/GET), orders/[id] (GET/PATCH), subscriptions (GET/POST),
  payments/deposit, payments/release, admin/metrics: try/catch -> mapper,
  each route's own typed error contract preserved (idempotency conflict 409 etc.)
- webhooks/stripe: store outage -> 503 received:false reason:store_unavailable
  so Stripe's delivery retry path stays open (never a silent received:true)
- tests/api/legacy-routes-siax-error-mapping.test.ts: pins the 503 + body
2026-09-22 04:33:57 +02:00
admin a1557b2a7d feat(payments): bind orders to verified tenant and buyer
CI (SIAX Cloud) / integration (push) Has been skipped
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / security (push) Successful in 14s
masterplan-lock / check (pull_request) Successful in 4s
CI (SIAX Cloud) / security (pull_request) Successful in 14s
Security Scan (SIAX Cloud) / security (push) Successful in 30s
CI (SIAX Cloud) / quality (push) Successful in 35s
CI (SIAX Cloud) / integration (pull_request) Successful in 25s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 54s
CI (SIAX Cloud) / quality (pull_request) Successful in 1m31s
2026-09-15 19:53:58 +02:00
admin cecc2bc637 fix(payments): authenticate order detail and deposit checkout
masterplan-lock / check (push) Successful in 4s
masterplan-lock / check (pull_request) Successful in 4s
Security Scan (SIAX Cloud) / security (push) Successful in 17s
CI (SIAX Cloud) / security (pull_request) Successful in 17s
CI (SIAX Cloud) / quality (pull_request) Successful in 36s
CI (SIAX Cloud) / security (push) Successful in 1m14s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 1m12s
CI (SIAX Cloud) / quality (push) Successful in 1m22s
CI (SIAX Cloud) / integration (push) Failing after 1m22s
CI (SIAX Cloud) / integration (pull_request) Failing after 1m22s
2026-09-15 19:09:53 +02:00
admin 7ce92827c0 fix: close demo payment bypass and guard order transitions
masterplan-lock / check (pull_request) Successful in 4s
CI (SIAX Cloud) / security (push) Successful in 14s
CI (SIAX Cloud) / security (pull_request) Successful in 15s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / integration (pull_request) Successful in 26s
masterplan-lock / check (push) Successful in 35s
CI (SIAX Cloud) / quality (pull_request) Successful in 37s
Security Scan (SIAX Cloud) / security (push) Successful in 1m4s
CI (SIAX Cloud) / integration (push) Successful in 1m14s
CI (SIAX Cloud) / quality (push) Successful in 2m12s
2026-09-15 18:52:23 +02:00
admin ae190fa60d fix: advance orders only after matching paid Stripe events
masterplan-lock / check (pull_request) Successful in 5s
masterplan-lock / check (push) Successful in 8s
CI (SIAX Cloud) / security (push) Successful in 18s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
Security Scan (SIAX Cloud) / security (push) Successful in 18s
CI (SIAX Cloud) / security (pull_request) Successful in 18s
CI (SIAX Cloud) / integration (push) Successful in 28s
CI (SIAX Cloud) / quality (push) Successful in 36s
CI (SIAX Cloud) / integration (pull_request) Successful in 48s
CI (SIAX Cloud) / quality (pull_request) Successful in 56s
2026-09-15 18:15:42 +02:00
admin 8911709931 fix: do not acknowledge unverified Stripe webhooks
masterplan-lock / check (push) Successful in 10s
Security Scan (SIAX Cloud) / security (push) Successful in 14s
CI (SIAX Cloud) / integration (pull_request) Successful in 27s
CI (SIAX Cloud) / quality (push) Successful in 39s
CI (SIAX Cloud) / quality (pull_request) Successful in 32s
CI (SIAX Cloud) / security (push) Successful in 43s
masterplan-lock / check (pull_request) Successful in 41s
CI (SIAX Cloud) / security (pull_request) Successful in 1m12s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 1m14s
CI (SIAX Cloud) / integration (push) Successful in 1m36s
2026-09-15 18:08:13 +02:00
siax-ci fcfd6bca1e M0: DES1GN-distribution — @siax/ui 0.4.1 + @siax/config + kanonisk import-kedja
masterplan-lock / check (push) Successful in 4s
CI (SIAX Cloud) / quality (push) Failing after 8s
CI (SIAX Cloud) / integration (push) Failing after 8s
CI (SIAX Cloud) / security (push) Successful in 15s
Security Scan (SIAX Cloud) / security (push) Successful in 31s
masterplan-lock / check (pull_request) Successful in 4s
CI (SIAX Cloud) / quality (pull_request) Failing after 8s
CI (SIAX Cloud) / integration (pull_request) Failing after 9s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 13s
CI (SIAX Cloud) / security (pull_request) Successful in 31s
Token-VÄRDEN ägs av @siax/ui; token→Tailwind-mappningen ägs av @siax/config.
Ingen in-repo token-kopia (M0-kontraktet). Bygg-CSS verifierad: SIAX-purple
(#5326cc = oklch 0.45) + Inter + text-accent utility genererad.
2026-09-15 12:51:47 +02:00
admin d0cba02ee0 feat: expose idempotent N0D-backed batch ER submission 2026-09-07 18:18:23 +02:00
admin 7d11ea895c feat: expose generic tenant-safe ER candidate API 2026-09-07 18:18:12 +02:00
admin 9782eaf42c refactor: share ER request validation across HTTP surfaces 2026-09-07 18:17:00 +02:00
admin 84945a2ff7 feat: expose tenant and purpose constrained search query route 2026-09-07 18:11:58 +02:00
admin e400afc882 feat: expose governed durable search definitions 2026-09-07 18:11:44 +02:00
admin e13d550837 fix(er): country-qualify company registration identifiers 2026-09-07 18:09:12 +02:00
admin 04d861b920 fix(er): require human review for score-only company matches 2026-09-07 18:07:56 +02:00
admin ccda286022 feat: expose tenant-safe dataset version describe route 2026-09-07 18:07:09 +02:00
admin e70acc8981 feat: expose durable dataset version create and query routes 2026-09-07 18:07:01 +02:00
admin b5ffdbc091 feat: expose tenant-safe dataset describe route 2026-09-07 18:06:46 +02:00
admin 102e1e1616 feat: expose tenant-safe dataset registry HTTP surface 2026-09-07 18:06:36 +02:00
admin 5338975eea fix: make conflicting company identifiers dominate ER matches 2026-09-07 17:57:23 +02:00