chore(ci): unblock the CVE gate, finish Sonnet 5, parallelize, harden the supply chain (#1223)

Unblocks docker-image-scan (red 5 runs straight on GHSA-f88m-g3jw-g9cj: next's nested sharp@0.34.5, deduped via an override).

Finishes the #1218 Sonnet 5 rollout: compliance-pr and compliance-swarm were falling through to compliancemaxx's sonnet-4-6 default; swedish-compliance-review.mjs budgeted max_tokens as if thinking were off (it is adaptive-by-default on Sonnet 5) and never checked stop_reason; pr-agent's token budgets were sized for 4.6's tokenizer and its hidden default OpenAI fallback list is now emptied explicitly.

Core build 7m43s -> 2m51s measured (parallel checks/build/test, unit suite sharded 4 ways). Docker publish moves off QEMU to native ARM runners with a digest-merge job, so tags apply only on success and latest never moves on failure.

40 actions pinned to immutable SHAs; adds zizmor (0 high after fixing persist-credentials on 7 checkouts and permissions on test-pg-real) and CodeQL (0 findings on first run).

Full details in the PR body.
This commit is contained in:
Jakob Wennberg
2026-07-27 12:01:03 +02:00
committed by GitHub
parent bcbe9b0903
commit 5369349e9e
18 changed files with 650 additions and 592 deletions
+7
View File
@@ -575,3 +575,10 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-07-27] Sonnet 5 no-thinking output ceiling kept separate (MAX_TOKENS_NO_THINKING 5400): max_tokens now caps thinking and reply together, so one shared ceiling would have quadrupled what a non-thinking intent may emit; 5400 is the old 4096 scaled for the new tokenizer.
[2026-07-27] Assistant panel docks via a --agent-dock-w CSS custom property rather than restructuring the frame: the dashboard layout is a server component, so a client-owned class on <main> would have meant lifting it to a client boundary for a margin.
[2026-07-27] Agent status is a reducer in a React-free module with an unused 'detached' state: durable background runs must publish to the same channel later (plan seam 8.6), and this repo's unit project is node-only so the state machine has to be testable without a component harness.
[2026-07-27] Compliance review script raises max_tokens to 16000 but does NOT send an explicit thinking parameter: on Sonnet 5 an omitted parameter already means adaptive, so sending it would add request surface on the pinned legacy Bedrock SDK 0.29.1 for zero behavioral change, and the workflow_run trigger checks out the base repo so no change to this script is testable before merge.
[2026-07-27] Core-build PR jobs restore the npm cache but never save it, with the save half in a separate main-only workflow (ci-cache.yml): a cache written from a pull_request run is scoped to that PR's ref and unreadable by anything else, which is how fourteen dead 284 MB copies once ate 40% of the repo's cache quota; only default-branch entries are restorable from every PR.
[2026-07-27] Deliberately did NOT cache .next/cache alongside the npm cache: keeping it useful needs a fresh entry per main push, and at a few hundred MB each that recreates the same quota churn, so the ~60s it would save off the build stage is deferred to its own change.
[2026-07-27] zizmor installed from PyPI at a pinned version rather than via zizmorcore/zizmor-action: a workflow whose job is auditing the supply chain should not widen it by adding another third-party action.
[2026-07-27] zizmor gates only on high-severity high-confidence findings while reporting everything to the Security tab: the first run surfaced 56 findings, and a scanner that blocks every merge on day one gets disabled rather than triaged.
[2026-07-27] dangerous-triggers suppressed for swedish-compliance-review.yml and docker-image-scan.yml in .github/zizmor.yml rather than left unresolved: both are workflow_run, but the first is the base-repo-only pattern GitHub recommends INSTEAD of pull_request_target and the second checks out no source at all, so leaving two permanent unexplained errors in the Security tab would just train reviewers to ignore it.
[2026-07-27] Docker layer cache tag is now per-architecture (buildcache-amd64 / buildcache-arm64): with native runners each job builds one platform, so a shared tag would leave the two racing to overwrite a cache manifest describing layers the other cannot use.