Fresh clone restore drill of the canonical Gitea repo (1.8s) and the fleet nightly backup record. This is repo/config restore evidence; it does not claim a database restore.
Remote code execution in next/og ImageResponse, fixed in 16.3.6.
Same minor line; the exact pin in package.json moves too and the
lockfile follows (next, @next/env, @next/swc-* platform binaries,
sharp optional range ^0.35.4).
Not fixed here (need a direct-dependency major bump or have no fix):
- nodemailer 9.1.1: GHSA-prgh-xp8r-p3m5 / GHSA-v53p-9fqp-m79j fixed only in 10.0.5/10.0.6 (major)
- xlsx 0.20.3: GHSA-4r6h-8v6p-xvw6 / GHSA-5pgg-2g8v-p4x9 have no published fix
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lockfile-level update of the packages trivy flags on main, all within
their current major:
- next 16.3.1 -> 16.3.3 (CVE-2026-75604, CRITICAL)
- js-yaml 4.3.1 -> 4.3.2 (CVE-2026-84375)
- nodemailer 9.0.5 -> 9.1.1 (GHSA-2x7j-588g-ccc2, GHSA-8m3c-c648-2xjj)
- sharp 0.35.3 -> 0.35.5 (GHSA-rgj7-g3m4-5g8c)
- undici 6.28.0 -> 6.29.0 (CVE-2026-19534)
- brace-expansion -> 1.1.21 / 2.1.7 (CVE-2026-102276, CVE-2026-102278, dev)
- minimatch 9.0.5 -> 9.0.9 (CVE-2026-26996/27903/27904, dev)
next, js-yaml and nodemailer were exact-pinned, so their pins move too.
PINNED_DEPS in the antipattern guard follows nodemailer to 9.1.1; without
it the pinned-dep guard fails.
Remaining: nodemailer GHSA-v53p-9fqp-m79j is only fixed in 10.x (major
bump of a direct dependency, left for a separate reviewed change).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
accounted: ny sonar-job i .gitea/workflows/ci.yml (endast push mot main)
plus sonar-project.properties. SONAR_TOKEN-secreten sätts INTE av denna
commit -- kräver manuell körning, se PR-beskrivningen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fleet-wide CI-speed pass: masterplan-lock.yml had no job-level
timeout-minutes (a hung runner could block indefinitely) and triggers
on both push (branches: ["**"]) and pull_request, which runs the same
check twice per PR commit. Add a 10-minute timeout for this cheap
single-check job and a concurrency group (matching the pattern already
used in admin/serv0, admin/s0cial, admin/ppl0, admin/pers0n) to cancel
the superseded duplicate run without changing what triggers CI.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tekniska fält härledda ur checkouten (runtime, gitHost/canonicalRemote,
neutrala persistence/observability/reliability — aldrig påstådda).
POLICY-FÄLT (tier/category/appId) är neutral-baseline MED appIdJustification
som säger att ägaren ska sätta dem (D4) — förgranska och korrigera.
* feat(dashboard): dismissible system notice banner for every signed-in user
Operator-set banner ("high load right now, some pages may respond slowly
or fail") rendered under the dashboard chrome for every signed-in user
while NEXT_PUBLIC_SYSTEM_NOTICE_UNTIL (ISO timestamp with offset) is in
the future. Closing it stores the deadline in localStorage, so each
browser sees it once; the banner hides itself at the deadline in open
tabs and is not rendered at all after it.
Why the problem occurred: there was no way to tell every user something
about the system itself. The existing banners are all per-company state
(sandbox, seat grace), so an operator notice had no home.
What was removed or simplified instead: no notices table, no migration,
no admin UI. One public env var carries both the on/off switch and the
expiry, and the same value is the dismiss key, so a later notice re-shows
once without any code change. No DB read, which matters because the
first use is a DB restart window.
Why this over the proposed shape: the request was a banner "until 23:00
tonight". Hardcoding that in code would need a second PR to switch off
or reuse; a DB-backed notice would read the database that is about to
go down. The env var expires on its own, and unset means gone.
Fixes#2463
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fs9PfHL7KpdidvUdxVkHXF
* fix(dashboard): system notice survives long deadlines, blocked storage, and every layout shell
Skeptic findings on 839a255f3:
- setTimeout clamps delays above 2^31-1 ms to ~1 ms, so a deadline more
than 24.8 days out hid the banner instantly. Wait in bounded steps and
re-check the clock.
- window.localStorage is a throwing property access when a browser blocks
site data; read it behind a try so the dashboard never crashes over a
notice.
- The close button was a hand-rolled 22px icon button; design.md requires
the shadcn icon Button (40px target).
- The byrå-consultant shell and the stale-cookie shell rendered no banner,
so "every signed-in user" was not true. The banner is now computed once,
before the shell branches, and mounted in all three.
Refs #2463
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fs9PfHL7KpdidvUdxVkHXF
* fix(dashboard): system notice deadline requires a UTC offset
A date-time without Z or a numeric offset parses as local time, which is
UTC on Vercel and the operator's zone locally, so the same value would
mean different instants. Reject it instead (CodeRabbit on #2464).
Declined: scoping the dismissal key by user id. The notice is about the
system, not the account; per-browser dismissal is the sandbox banner's
semantics and keeps identity out of layout chrome.
Refs #2463
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fs9PfHL7KpdidvUdxVkHXF
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* feat(import): keep the source system's #BTRANS/#RTRANS correction history at SIE import
A verifikat migrated from Fortnox/Visma lost the trail of what had been
corrected in the source system: the parser skipped #BTRANS (struck lines)
and #RTRANS (lines added by a rättelse) and nothing else read them. The
final state is still built from #TRANS only, exactly as SIE 4B prescribes
(#RTRANS is always twinned by an identical #TRANS, so summing all three
double-counts, #63). The two history record types now ride along the
voucher as `corrections` and land, inside the same atomic import
transaction, as one journal_entry_rattelse_log row per corrected voucher
with source='sie_import', the file's sie_import_id and the SIE `sign`
(who corrected in the source system; SIE carries who, never when).
Why the problem occurred: the March fix for double-counting chose "skip"
over "keep aside" because nowhere existed to keep the history. The inline
rättelse log (July) created that place, and every reader of it (verifikat
page, "Rättad" marker, behandlingshistorik, full archive) already renders
struck/added snapshots, so the history now flows through one table.
What was removed or simplified instead: no new table, no per-import
toggle, no fifth RPC parameter (sie_import_id travels inside each payload
entry so the (uuid,uuid,uuid,jsonb) signature, grants and
statement_timeout stay put and PostgREST sees no overload). The parser's
three identical TRANS/RTRANS/BTRANS field parsers collapsed into one
helper; the TRANS-only ledger path is byte-for-byte the same.
Why this over the proposed shape: the reporter suggested an own table or
column. A separate store would need its own readers, RLS, archive
classification and behandlingshistorik wiring; the rättelselogg already
has all four. Storing history in sie_imports.migration_documentation was
rejected as aggregate JSON that no per-verifikat surface reads.
Import-sourced log rows survive undo/replace like every other log row
(no FK on purpose); a re-import writes fresh rows against fresh entry ids.
Parser also warns when an #RTRANS is not followed by its identical #TRANS
twin (a spec violation that would silently drop a line from the final
state) and the record-type comments now match the spec wording.
Migration 20260909132618: three nullable/defaulted columns + CHECKs on
journal_entry_rattelse_log, sie_correction_snapshots() helper,
import_sie_journal_entries body verbatim plus the history insert. No
backfill; existing imports and log rows untouched.
Fixes#2427
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W2FcXNv8qRp4GaXCtzEdyn
* fix(import): verify the SIE import id before it becomes provenance, keep per-line signatures
Review findings on PR #2458, one pass:
- Superagent P2: import_sie_journal_entries stored the caller-supplied
sieImportId as WORM audit provenance without checking it. The RPC now
requires the id to be one of the importing company's own sie_imports
rows and fails closed (42501, whole import rolled back) on a foreign
or fabricated id. pg-real test added.
- Compliance review: the voucher-level external_signature collapsed
distinct correctors per line. Each struck/added snapshot now carries
its own SIE sign (importer + sie_correction_snapshots), the summary
column stays as the first one.
- Compliance review: created_at on imported rows is the import moment.
Behandlingshistoriken now says so in the event details instead of
leaving it implicit (the verifikat page already avoided a date).
Migration file is unshipped (not on main); staging re-applied under the
same version.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W2FcXNv8qRp4GaXCtzEdyn
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>