Skip to content

chore(deps): collect the open Dependabot updates - #3034

Closed
oscharko wants to merge 20 commits into
devfrom
deps/dependabot-collector
Closed

chore(deps): collect the open Dependabot updates#3034
oscharko wants to merge 20 commits into
devfrom
deps/dependabot-collector

Conversation

@oscharko

@oscharko oscharko commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Collects all seven open Dependabot pull requests into one branch so they are gated and integrated
as a single unit instead of seven separate ~30-minute CI cycles. Every update is a development-only
dependency or a CI action pin; no production dependency and no product source file changed.

Collected updates, in ascending PR number order (each merged with git merge --no-ff from the
Dependabot head, so authorship is preserved):

PR Package From To Kind
#3003 jsdom 29.1.1 30.0.1 devDependency
#3004 postcss 8.5.23 8.5.25 devDependency
#3005 github/codeql-action/init 4.37.1 4.37.4 GitHub action pin
#3006 github/codeql-action/analyze 4.37.1 4.37.4 GitHub action pin
#3014 @playwright/test 1.62.0 1.62.1 devDependency
#3015 vite 8.1.4 8.2.0 devDependency
#3016 @vitejs/plugin-react 6.0.3 6.0.5 devDependency

The original seven PRs are intentionally left open and unmodified; they close when this lands.

Conflict resolution and two corrections Dependabot could not make

Four of the seven merges needed manual resolution. The lockfile was never regenerated from scratch
in any of them: the dev-side lockfile was taken and only the bumped subtree was moved with
npm install --package-lock-only, then verified entry by entry.

  1. overrides.postcss was advanced 8.5.23 → 8.5.25 (root package.json). PR deps(deps-dev): bump postcss from 8.5.23 to 8.5.25 #3004 raised
    keiko-ui's declared range to ^8.5.25 and the lock entry to 8.5.25, but left the root
    single-version overrides pin at 8.5.23. Those two contradict: the override wins at install
    time, so the bump would have been inert and the declared range a dead letter. Advancing the
    override in lockstep is the established pattern on this exact line — collector PRs [codex] Roll up Dependabot dependency updates #1708, chore(deps): combine dependabot updates #2648,
    chore(deps): consolidate compatible Dependabot updates #2677 and chore(deps): consolidate Dependabot updates #2964 each did the same. The resulting lock entry carries byte-identical
    resolved/integrity values to Dependabot's own.
  2. Three lockfile workspace mirrors were resynced to their own package.json. Dependabot's
    generated lockfiles recorded caret ranges (^30.0.1 for jsdom, ^8.2.0 for vite) while the
    very same PRs wrote exact pins (30.0.1, 8.2.0) into the workspace package.json files. The
    mirrors were corrected to match the declarations. No resolved version changed.

Content conflicts in packages/keiko-ui/package.json and packages/keiko-editor/package.json were
adjacent-line collisions only (jsdom next to postcss; @vitejs/plugin-react next to jsdom) — both
sides' bumps were kept.

Reviewer notes on the two diffs that look larger than a version bump

  • package-lock.json nets −314 lines on the vite merge. This is a dedupe, not a removal of
    functionality. keiko-ui previously pinned vite exactly at 8.1.4 while the hoisted copy sat at a
    different version, forcing a full nested packages/keiko-ui/node_modules/ tree of vite plus every
    platform-specific @rolldown/binding-*. At 8.2.0 the specs agree, npm hoists, and that duplicate
    tree collapses. Exactly one package entry disappears from the graph:
    @rolldown/binding-wasm32-wasi, an optional WASI fallback binding. Total audited packages go
    878 → 874. The merge result is byte-identical to PR deps(deps-dev): bump vite from 8.1.4 to 8.2.0 #3015's own diff.
  • @vitejs/plugin-react moves in four places — root package.json plus the keiko-ui and
    keiko-editor workspaces, and the single hoisted lock entry — because all three declare it.

Scope

  • In scope: the seven collected Dependabot updates; the overrides.postcss advance they require;
    lockfile mirror resync.
  • Out of scope: any product source change; any production dependency; regenerating the lockfile;
    the pre-existing editor-release-evidence drift described under Risk Notes.

Reuse And No-Duplication

  • Existing Keiko functionality was inspected before implementation.
  • This PR reuses, extends, generalizes, or consolidates existing functionality where practical.
  • Any new implementation is limited to a documented capability gap in the linked issue.
  • This PR does not introduce a parallel workspace, graph, relationship, policy, evidence, memory, connector, workflow, or UI subsystem where an existing subsystem can be extended.
  • Refactoring or consolidation was considered when existing functionality was close but not shaped for this change.

No new code was written. The one judgement call — advancing overrides.postcss — followed the
precedent set by four prior collector PRs on that same line rather than inventing a new mechanism.

Delivery Board

This is a routine dependency-collection PR with no linked issue or epic, so the board items below
do not apply. Auto-merge is deliberately not armed; the required CI run is the arbiter.

  • Linked issue is in the public Keiko Product Delivery project.
  • Linked issue has a valid Parent Epic: #<epic_number> unless this PR updates an epic container directly.
  • Linked issue is attached as a GitHub sub-issue of its parent epic so it appears in the correct board swimlane.
  • Parent epic is on the board with Classification: Epic, Status: Open Epics, and priority/order set for top-to-bottom implementation sequencing.
  • Linked task/card issue is on the board with Classification: Task, Status: In Progress while active, inherited or explicit Priority, and Human Review Required: No.
  • Project Status is In Progress while work is active, or Done only after merge and closure evidence.
  • Project Workflow State is PR Open while deterministic gates or repairs are active.
  • Owner / Agent, Branch, Pull Request, and Human Review Required are filled.
  • Issue label remains status: in progress until verified auto-merge, then becomes status: done.
  • Autonomous repair stayed on the PR branch; no direct dev push, force-push, finding dismissal, or required-gate bypass occurred.
  • Native auto-merge was armed only after the ADR-0135 direct required checks settled. — not armed.
  • If Keiko for Quality is enabled, arming followed ADR-0170 D5. — not applicable, nothing armed.

Product Impact

  • UI or user workflow
  • UI text uses the i18n API and includes English and German catalog entries.
  • CLI or developer workflow
  • Core generation engine
  • Evidence, audit, or compliance artifact
  • Security or supply chain
  • Packaging, release, or npm publication
  • Documentation or repository hygiene
  • No user-facing behavior change

Update Impact

  • Not release-impacting.
  • Release-impact catalog or issue metadata updated.
  • Release-note category: internal-only.
  • Priority: internal.
  • User-visible change: none. Every bump is a devDependency or a CI action pin; the shipped runtime
    graph is unchanged, and npm audit --omit dev reports 0 vulnerabilities before and after.
  • Release-note bullet: n/a — internal only.
  • Supported-from versions: unchanged (0.3.0).
  • Affected state stores: none.
  • User action required and remediation: none.
  • Internal-only rationale: development toolchain and CI pins only; no production dependency, no
    product source file, and no packaged surface changed. npm run check:release-impact passes
    without a catalog edit.
  • Release-owner review evidence: check:release-impact PASS (exit 0), recorded below.

Verification

Required:

  • npm run gates:sonar was run on this diff and reported no finding.
  • Required GitHub checks pass before merge. — pending this PR's run.
  • npm run check:ui-i18n passes, or no UI production source changed.
  • Local verification commands or rationale are listed below.
  • Reuse/extension/generalization evidence or gap rationale is listed below.

Local verification:

Every command below was run in this worktree on macOS (darwin/arm64), Node v24.18.0, npm 11.16.0.
Exit codes were captured from each command directly, never through a pipe.

npm install                        exit 0   no-op; `git status` clean afterwards
npm run provision:usearch          exit 0   fresh-worktree prerequisite (ADR-0164)
npm run typecheck                  exit 0   toolchain PASS; package-graph PASS
npm run lint                       exit 0   root + keiko-ui, --max-warnings=0
npm run format:check               exit 0   all matched files use Prettier style
npm test                           exit 0   1568 files passed / 7 skipped; 28660 tests passed / 20 skipped
npm run check:knip                 exit 0   no unused files, exports, dependencies, or binaries
npm audit --omit dev               exit 0   found 0 vulnerabilities
npm run gates:sonar                exit 0   PASS - no unresolved finding on the 5 changed files
npm run arch:check                 exit 0   0 violations (5357 modules, 19387 dependencies)
npm run arch:check:negative        exit 0   gate fired on all 52 fixtures as expected
npm run check:version-consistency  exit 0   every package reports 0.3.0
npm run check:editor-bundle-size   exit 0   own-code gzip 77972 B / 102400 B ceiling
npm run check:ui-i18n              exit 0   0 changed UI source files
npm run check:release-impact       exit 0   current version has reviewed update-impact metadata
npm run build:ui                   exit 0   static export builds clean

npm run check:editor-release-evidence   exit 1   PRE-EXISTING on dev — see Risk Notes

The one non-zero exit was reproduced on an unmodified origin/dev checkout in this same worktree and
produces a byte-identical fingerprint pair, so it is not caused by this PR. Details in Risk Notes.

Reuse / gap rationale:

No new code. The seven upstream branches were merged with --no-ff to preserve Dependabot
authorship rather than cherry-picking or hand-applying the bumps.

The lockfile was never regenerated. On each conflict the dev-side package-lock.json was taken with
`git checkout --ours`, then only the bumped subtree was moved via `npm install --package-lock-only`,
and the resulting entry was compared against Dependabot's own `resolved` and `integrity` values.
For @vitejs/plugin-react 6.0.5 the integrity hash was diffed directly against PR #3016's lockfile
and matches exactly.

Advancing overrides.postcss reuses the existing single-version override mechanism and follows the
precedent of collector PRs #1708, #2648, #2677 and #2964, which each advanced that same line
alongside the corresponding postcss bump. No new pinning mechanism was introduced.

Select only what applies:

  • UI behavior manually verified or covered by tests.
  • CLI behavior verified with command output or tests.
  • Core logic covered by unit, integration, property, or fixture tests.
  • Security-sensitive change reviewed for trust boundaries, secrets, external calls, and generated artifacts.
  • Supply-chain or package-surface change verified with package, license, lockfile, SBOM, or npm dry-run checks.
  • Documentation or Markdown change verified by the repository link check or a targeted local equivalent.
  • Release-impacting change verified with npm run check:release-impact or an explicit rationale.
  • Not applicable items are explained below.

Not applicable rationale:

  • No UI or CLI behavior change to verify manually: no product source file is touched, only
    devDependency versions and two CI action pins. The full vitest suite (28660 tests) covers the
    behavioral surface that the jsdom, vite and plugin-react bumps could plausibly disturb.
  • No Markdown or documentation file changed.

Risk Notes

  • check:editor-release-evidence fails locally, and it fails identically on unmodified dev.
    Committed fingerprint 4d91f10e…, locally measured 951ab458…. To establish ownership I
    detached to origin/dev in this same worktree, ran npm install and npm run build:ui, and
    re-ran the gate: it produced exactly the same pair of hashes. Two things follow. First, the
    drift pre-dates this PR and is not mine to repair inside a dependency collector. Second — and
    more useful — because my branch measures the same 951ab458… as dev, the vite 8.2.0 and
    @vitejs/plugin-react 6.0.5 bumps do not change the editor bundle output at all. The
    deterministic budget gate check:editor-bundle-size passes on this branch (exit 0). I did not
    regenerate the evidence: the committed document was measured on the pinned Linux reference
    container, and AGENTS.md §3 forbids replacing CI/Linux evidence with macOS-generated values.
    Regenerating here would have overwritten authoritative evidence with a wrong-platform
    measurement. Flagging for a separate, correctly-provisioned regeneration.
  • vite 8.1.4 → 8.2.0 is the largest functional risk in this set: it is the bundler for
    keiko-ui and keiko-editor. It is covered by a green full test suite, a green build:ui, and a
    green check:editor-bundle-size.
  • jsdom 29.1.1 → 30.0.1 is a major bump and is the test DOM for the keiko-ui and keiko-editor
    jsdom suites. The full suite passes with no new failures or skips.
  • The two CodeQL action bumps keep the required full 40-hex SHA pin plus version comment format;
    both now resolve to f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4, and no other workflow
    still references the old pin.
  • Auto-merge is not armed and the seven source PRs are untouched, per the scope of this task.

🤖 Generated with Claude Code

dependabot Bot and others added 14 commits August 7, 2026 22:51
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.23 to 8.5.25.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.23...8.5.25)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.25
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [jsdom](https://github.com/jsdom/jsdom) from 29.1.1 to 30.0.1.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](jsdom/jsdom@v29.1.1...v30.0.1)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-version: 30.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.62.0 to 1.62.1.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](microsoft/playwright@v1.62.0...v1.62.1)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.62.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.1.4 to 8.2.0.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@8.2.0/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 6.0.3 to 6.0.5.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.5/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.0.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github/codeql-action/init](https://github.com/github/codeql-action) from 4.37.1 to 4.37.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@7188fc3...f205ea1)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github/codeql-action/analyze](https://github.com/github/codeql-action) from 4.37.1 to 4.37.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@7188fc3...f205ea1)

---
updated-dependencies:
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
# Conflicts:
#	package-lock.json
#	packages/keiko-ui/package.json
# Conflicts:
#	package-lock.json
#	packages/keiko-editor/package.json
@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 09:25 — with GitHub Actions Inactive
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@oscharko, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 33 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 60268015-8df8-445d-b7ed-0513709d80aa

📥 Commits

Reviewing files that changed from the base of the PR and between 211149d and f0bd1b2.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • .github/workflows/codeql.yml
  • .github/workflows/dependency-review.yml
  • package.json
  • packages/keiko-editor/package.json
  • packages/keiko-ui/package.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​postcss@​8.5.23 ⏵ 8.5.25100 +110081 +195100
Updatednpm/​jsdom@​29.1.1 ⏵ 30.0.185100100 +195100
Updatednpm/​@​playwright/​test@​1.62.0 ⏵ 1.62.110010010099100

View full report

@socket-security

socket-security Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm jsdom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: package-lock.jsonnpm/jsdom@30.0.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/jsdom@30.0.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: npm playwright-core under ms-azure-data-studio

License: ms-azure-data-studio - The applicable license policy does not permit this license (5) (package/ThirdPartyNotices.txt)

From: package-lock.jsonnpm/@playwright/test@1.62.1npm/playwright-core@1.62.1

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/playwright-core@1.62.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
License policy violation: npm playwright under ms-azure-data-studio

License: ms-azure-data-studio - The applicable license policy does not permit this license (5) (package/ThirdPartyNotices.txt)

From: package-lock.jsonnpm/@playwright/test@1.62.1npm/playwright@1.62.1

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/playwright@1.62.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn Medium
Recently published: npm @asamuzakjp/dom-selector published 6 days ago

Location: Package overview

From: package-lock.jsonnpm/jsdom@30.0.1npm/@asamuzakjp/dom-selector@8.3.2

ℹ Read more on: This package | This alert | What are recently published artifacts?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should either be allowlisted to allow recently-published versions, or an older version should be used instead.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@asamuzakjp/dom-selector@8.3.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@keiko-for-quality

keiko-for-quality Bot commented Aug 8, 2026

Copy link
Copy Markdown

Keiko for Quality — run summary

COMPLETE · head f0bd1b2 · 2026-08-08T12:40:29Z · engine v1.8.4 · action 8aafc617614f06d9c90be6fb32fda112ccc1cf78

Metric Count
Total paths 6
Reviewable 6
Excluded 0
Mechanically clean 0
Critical pointer changes (content not reviewable) 0
Replayed from cache 6
Cache miss (path-set shape changed) 0
Freshly reviewed 0
Findings published 0
Suppressed (intra-run duplicate) 0
Suppressed (exact duplicate) 0
Suppressed (similar) 0
Suppressed (dispositioned) 0
Suppressed (outdated recurrence) 0
Rejected (sanitization) 0
Rejected (placement) 0
Read-back failures 0
API failures 0
Duration (s) 2

Budget: 150000 tokens allotted

Recent runs

  • f0bd1b2 · complete · fresh 0 · replayed 6 · 2s
  • cb2d918 · complete · fresh 6 · replayed 0 · 9s
  • 04aa6aa · complete · fresh 3 · replayed 3 · 8s
  • 6fc686a · complete · fresh 5 · replayed 0 · 8s

@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 09:26 — with GitHub Actions Inactive
The collected pdfjs/csstools updates pull two transitive packages
(@csstools/color-helpers, @csstools/css-syntax-patches-for-csstree)
published under MIT-0 — MIT without the attribution clause, strictly
more permissive than the MIT, Unlicense, and WTFPL entries already
admitted. The allowlist stays permissive-only; no per-package exception
is needed.
@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 11:29 — with GitHub Actions Inactive
@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 11:30 — with GitHub Actions Inactive
…to 6.0.5"

This reverts commit 6fc686a, reversing
changes made to 21e5e7d.
This reverts commit 21e5e7d, reversing
changes made to 2194c2f.
@oscharko

oscharko commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Scope adjustment: the vite 8.2.0 (#3015) and @vitejs/plugin-react 6.0.5 (#3016) bumps are reverted out of this collector. vite 8.2.0 raises its lightningcss range to ^1.33.0, and the version bump makes the pre-existing MPL-2.0 license of that transitive package visible to the dependency-review diff gate for the first time (dev already ships lightningcss 1.32.0 under the same license — no new exposure). The gate's allowlist is deliberately permissive-only with per-package copyleft exceptions taken as OWNER decisions (see the LGPL precedent in dependency-review.yml), so admitting MPL-2.0 — even per package — is not a call this collector should make. #3015 and #3016 stay open for that decision; everything else in the collector is license-neutral and proceeds.

@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 12:32 — with GitHub Actions Inactive
@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 12:33 — with GitHub Actions Inactive
@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 12:40 — with GitHub Actions Inactive
@oscharko
oscharko temporarily deployed to keiko-for-quality August 8, 2026 12:41 — with GitHub Actions Inactive
@oscharko
oscharko enabled auto-merge (squash) August 8, 2026 12:45
@oscharko
oscharko disabled auto-merge August 8, 2026 13:02
@sonarqubecloud

sonarqubecloud Bot commented Aug 8, 2026

Copy link
Copy Markdown

oscharko added a commit that referenced this pull request Aug 8, 2026
…integration (#3037)

* deps(deps-dev): bump postcss from 8.5.23 to 8.5.25

Bumps [postcss](https://github.com/postcss/postcss) from 8.5.23 to 8.5.25.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.23...8.5.25)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.25
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* deps(deps-dev): bump jsdom from 29.1.1 to 30.0.1

Bumps [jsdom](https://github.com/jsdom/jsdom) from 29.1.1 to 30.0.1.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Commits](https://github.com/jsdom/jsdom/compare/v29.1.1...v30.0.1)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-version: 30.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* deps(deps-dev): bump @playwright/test from 1.62.0 to 1.62.1

Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.62.0 to 1.62.1.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.62.0...v1.62.1)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.62.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* deps(deps-dev): bump vite from 8.1.4 to 8.2.0

Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.1.4 to 8.2.0.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@8.2.0/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* deps(deps-dev): bump @vitejs/plugin-react from 6.0.3 to 6.0.5

Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 6.0.3 to 6.0.5.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.5/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.0.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* feat(release): accept owner-verified issue-comment evidence for the publish approval gate (#2802)

GitHub refuses self-approval of one's own pull requests, so a solo
release owner can never mint the github-pr-review artifact the publish
gate demands — the 0.3.0 npm publish was structurally unsatisfiable.
Owner decision (2026-08-08): add a second evidence form at the same
strictness, not a bypass. github-issue-comment:<owner>/<repo>#<issue>#
<comment> verifies through the GitHub API that the comment exists on
the referenced issue in this repository, is authored by a login in
KEIKO_RELEASE_OWNER_GITHUB_LOGINS, and contains the literal
version-bound phrase "Approved-for-publish: <package>@<version>".
The pr-review form is unchanged and either satisfies the gate.

The 0.3.0 catalog entry binds to the owner's recorded approval
(issue #2802, comment 5225214175). Verified live in both directions:
the correct owner login passes, a foreign login refuses on the
comment-author branch, and the hermetic suite pins the parse and
repository boundaries (23/23).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(release): cover every issue-comment approval branch through an injected reader (#2802)

SonarCloud measured the new evidence path at 39% new-code coverage: the
GitHub API branches were hermetically unreachable. The reader is now an
injectable seam (withGithubResourceReader, swap-and-restore), and every
branch is pinned: verified owner comment accepted, wrong issue
refused, missing phrase refused with the demanded phrase named, foreign
author refused, unreadable resource fails closed.

The approval phrase also binds to the catalog ENTRY under validation
(packageName@packageVersion of the record being approved) instead of
re-reading package.json — the fixture-derives-from-producer rule
applied to the gate itself: the phrase can only ever demand the exact
package identity the gate is judging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ui): load a keiko.config.json on the gateway setup page (#2802)

Owner-directed for 0.3.0-beta.2: teams that already maintain a
model-gateway configuration file load it on the first setup page
instead of retyping every field. The parser runs entirely in the
browser, is fail-closed (any structural violation refuses the whole
file rather than applying half of it), and the parsed values land in
the exact same form state — and therefore the same validation and
one-time token test — as manual entry. Whatever the file does not
carry (typically the API token) stays manual.

The control follows the design system (component-scoped .cmp-* classes
in the dialog's CSS module, tokens only, forced-colors variant), is
fully keyboard- and SR-reachable (labelled file input, role=alert /
output status), and localized in both catalogs. The parser module is
deliberately lowercase-distinct from the component file: the two names
differed only by case, which resolved to the wrong module on
case-insensitive filesystems — measured, then renamed.

Coverage baseline extends by exactly the keiko-ui entry (418 -> 420
source files); editor bundle evidence regenerated via the documented
build:ui + editor-release-evidence flow. 145/145 modal tests, 12
parser pins including hostile-input refusals.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): name the chat-creation rejection parameter error_ (S7718)

Closes the one open SonarCloud finding (AZ-sNvyxhylc2f8zV9LK,
owner-requested in this PR): the rejection handler's parameter follows
the repository's error_ naming convention. Behavior unchanged; 42/42
widget tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): close two review findings and restore the CI-anchored bundle evidence (#3031)

- The disabled look of the upload action uses an explicit class toggle
  instead of :has(input:disabled), so it cannot depend on selector
  support the deployed browser may lack (reviewer finding, confirmed).
- file.text() rejections resolve to the same visible "invalid" outcome
  instead of escaping as an unhandled rejection (reviewer finding,
  confirmed); handler extracted to hold the function-size bar.
- docs/release/1209-bundle-evidence.json returns to the committed CI
  fingerprint: the local regeneration replaced CI-anchored evidence
  with macOS-measured values — the exact machine-class trap AGENTS
  documents — and CI proved the UI change does not move the CI
  fingerprint at all.

145/145 modal tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(deps): bump github/codeql-action/init from 4.37.1 to 4.37.4

Bumps [github/codeql-action/init](https://github.com/github/codeql-action) from 4.37.1 to 4.37.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...f205ea1c3313d32999d8d6a48b4f6530d4437b38)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* ci(deps): bump github/codeql-action/analyze from 4.37.1 to 4.37.4

Bumps [github/codeql-action/analyze](https://github.com/github/codeql-action) from 4.37.1 to 4.37.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...f205ea1c3313d32999d8d6a48b4f6530d4437b38)

---
updated-dependencies:
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(ui): close the nine review findings on the config upload (#3031)

Parser (all fail-closed, each pinned): providers that disagree on any
connection scalar refuse the whole file — one connection per upload;
top-level capability records are authoritative over inline ones,
malformed records refuse the file (same policy as providers), and ids
no imported provider carries refuse it too (an untestable id would
fail Test & Save AFTER a reported success); voice/OCR provider kinds
report their own honest "cannot represent" outcome; an explicitly
empty eligibility declaration clears the form field like manual
emptying; a supported figma.accessToken carries through.

Upload control: a superseded file selection can never overwrite a
newer one (sequence token), and read failures resolve to the visible
"invalid" state.

Server (the security finding, fixed for the whole class): in update
mode a changed gateway URL never inherits the stored token — the
refusal compares CANONICAL endpoint identities so equivalent spellings
keep working, lives server-side so no client path bypasses it, and the
voice connection's existing replace-guard is pinned as covering the
same class (a redundant second guard was measured and removed).

154/154 modal tests, 181/181 gateway-setup tests, sonar clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(release): automate the portable evaluation prerelease end to end (#2802)

Owner order after the beta.0 -> beta.1 cycle: every publishing lesson
lives in the release tooling so none is relearned by hand. One command
(release:prerelease) now dispatches the evaluation build, refuses runs
with failed or missing staging jobs, downloads exactly the four-asset
publish set (drift refuses), embeds locally computed SHA-256 checksums,
verifies the arm64 bundle the way Gatekeeper judges it on a darwin host
(codesign --verify --deep --strict, pinning beta.0's exact "damaged"
signature text) and states the skip out loud anywhere else, publishes
the prerelease with provenance (commit + run id), auto-increments the
beta tag, and prepends a superseded pointer to the predecessor.

Proven live before landing: a plan-only run against the real beta.1
workflow run reproduced the manually published checksums byte for byte
and passed the real seal verification. 13 hermetic pins cover the tag
arithmetic, argument surface, release body (GUI-only approval steps —
never a terminal command), and the encoded lessons.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(quality): except codesign's absolute path from knip unresolved-import resolution (#3032)

knip's script parser treats the absolute spawnSync path
/usr/bin/codesign as an import specifier and resolves it on disk, so
the gate passed on darwin and failed on the Linux CI runner — a
platform-dependent verdict. The narrow ignoreUnresolved entry names
exactly this path; ignoreBinaries already carried it for the wrapped
call sites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(security): give the keychain protocol tests a load-proof spawn budget

The success-path tests exercised the fixture executable under the
PRODUCTION 2-second spawn budget, which a saturated 4-core CI runner
can exceed — measured twice in a row on the same loaded run (shard
packages 3/3 on #3028), while every idle run stays green. Protocol
tests now inject a generous 30s budget; the bound itself keeps its
dedicated hang test at 250ms, which is the only place the budget IS
the assertion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): close the sixth review wave and the image-capability removal class (#3031)

Parser: a present-but-malformed inline capability refuses the file
(production-parser parity); the setup route's 100-provider ceiling is
mirrored at upload time; endpoint style / API version / output token
parameter refuse with their own honest "cannot represent" outcome
while retry tuning stays tolerated. Upload control: an in-flight file
read blocks submission (the dialog can no longer snapshot a
half-applied form), threaded via onReadPendingChange.

Server, the deepest find of the wave: image capability could NEVER be
removed once stored — the image list was additive at three layers.
Now the wire distinguishes absent (inherits) from explicitly empty
(clears), a present list routes through the verified rebuild instead
of the settings-only patch, an explicitly provided list stops
discovery from re-adding just-removed models, and the provided list is
authoritative in the capability rebuild. Pinned end to end: absent
inherits, empty clears, 182/182.

The upload feature loads as its own chunk: the setup page returned
under the static-export first-load budget (measured with the gate's
exact --require-static-export invocation) instead of raising it.

157/157 modal tests, sonar clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): the pending-read flag follows the current token on every path (#3031)

A superseding selection that failed the size check advanced the token
without starting a read, so the superseded read's stale-return could
never clear the pending flag and the dialog stayed blocked. The size
branch now owns the flag for its token. The reviewer's suggested fix
(clearing on the stale return) would have been wrong the other way —
it would unblock submission while the NEWER read is still in flight;
the flag's contract is "a read for the CURRENT token is in flight".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): report a throwing apply callback instead of leaking a rejection (#3031)

A throwing onApply is a programming error, not a user problem: it now
routes through window.reportError (the page's established channel,
never an unhandled rejection out of a void handler) and shows the
honest failed state instead of a success count.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(release): drive the prerelease orchestration hermetically through seams (#3032)

SonarCloud measured the orchestration at 26% new-code coverage: every
gh-, codesign- and platform-bound path was untestable. The script now
carries three swap-and-restore seams (process runner, host platform,
and a throwing fail() with the CLI shim owning the exit), and a
scripted gh double drives the complete flow end to end: the happy
publish with checksums, provenance and the supersede pointer; the
failed-staging refusal; the drifting-asset-set refusal; the beta.0
damaged-signature refusal; and the stated (never silent) non-darwin
seal skip. The real path stayed byte-identical: the live plan-only
rehearsal against the beta.1 run reproduces the published checksums.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(gateway): import voice sections from uploaded configs and close the wave-7 findings (#3031)

The parser refused the exact persisted keiko.config.json this feature was
built for: voice providers tripped the unsupported-setting refusal. Voice
providers now map onto the dedicated voice setup fields (STT/TTS/realtime
roles from stored capability flags, one voice connection per submit); a
realtime provider on a different connection than the speech pair is
skipped with a visible message instead of silently or refusing the file.

Wave-7 review repairs:
- P1: preserve-mode rebuilds classify inherited/resubmitted deployments
  by their STORED capability kinds before the name heuristic — a stored
  embedding provider with a non-heuristic id no longer vanishes when an
  unrelated update (image clear, credential rotation) rebuilds the config.
- Upload parser: reject present-but-malformed scalars and capability
  flags instead of coercing, reject mixed stated/omitted connection
  scalars, mirror the route's model-id constraints, and derive the
  image/workflow flag lists from chat capabilities only.

* fix(ui): harden the config upload against parser regressions and unbounded payloads (#3031)

Wave-8 review repairs: the parser enforces its own size ceiling ahead of
JSON.parse (the upload control's file.size check is no longer the only
guard), and a parser throw — impossible today, pinned via a mocked
regression — reports through the page error channel and shows the honest
invalid state instead of crashing the component.

* chore(release): bump static-export file count for the split upload chunk (#3031)

The dynamic() split of GatewayConfigUpload adds one file to the static
export; the CI-anchored measurement fingerprint and every editor byte
field are untouched — the Linux run confirmed only fileCount drifted.

* fix(gateway): close the wave-9 findings — voice fidelity on import, stored OCR survival (#3031)

- P1 (server): a preserve-mode verified rebuild silently dropped stored
  ocr-vision providers — the rebuild only re-derives chat and embedding.
  Stored OCR ids now leave the candidate set (never chat-probed) and the
  providers are restored verbatim from the current configuration, exactly
  like voice; pinned with a probe spy plus both fix halves sabotage-proven.
- P1 (import): a speech-output provider with voice profiles now carries an
  output voice into the form (uniform profiles losslessly, several voices
  reduce to the neutral persona WITH a visible message) — without it every
  fresh Test & Save failed 400 on a file that carried the information.
- Multi-role realtime providers fill unclaimed speech roles (the route
  merges roles per model id); a skipped realtime claims nothing.
- Voice locality imports uniformly or refuses; inline capability ids must
  match their provider; malformed figma/circuitBreaker/voiceProfiles
  blocks refuse; a tuned circuit breaker is honestly unsupportedSetting;
  voice-only files refuse instead of loading an unsubmittable form.

* perf(ui): load the gateway setup dialog lazily from the settings panel (#3031)

The settings panel's static import pulled the whole dialog into the
first-load chunk — the voice-import surface pushed it 273 B over the
340992 B ceiling. The dialog is gesture-only there (ADR-0042 D3.6),
exactly like the shell's own modals, so it now loads behind the same
next/dynamic boundary; the static-export file count advances to 335.

* test(release): prove every refusal path of the prerelease orchestration hermetically (#3032)

Sonar held the new script to the 85% new-code bar and was right: the
dispatch/poll path, the run seams' failure modes, tag collisions,
cancelled runs, first-beta and already-superseded predecessors, nested
artifacts, incomplete staging sets, a corrupted copy step, and the
non-damaged codesign failure were all unproven. A withSleeper seam makes
the polling paths hermetic (no wall-clock waits); the CLI shim is pinned
end-to-end via a real subprocess. 32 tests, script coverage 96.6% lines /
87.7% branches — uncovered remains only the Atomics sleeper body and the
direct-invocation shim, both exercised outside instrumentation.

* fix(gateway): close the wave-10/11 findings — byte-accurate ceiling, OCR credential rotation, lazy upload copy (#3031)

- Upload parser: the size ceiling measures bytes (TextEncoder), not UTF-16
  units; unknown top-level policy blocks (grounding, reranker, egress)
  refuse as unsupportedSetting instead of being silently dropped on save;
  voice-profile personas validate against the known set and reject
  duplicates; the circuit-breaker extra-key guard uses Object.hasOwn.
- Server: a restored same-endpoint OCR provider follows a credential
  rotation (the fresh token never travels to a different endpoint), and
  OCR restoration applies only to INHERITED deployments — an explicitly
  submitted deployment list can remove OCR providers again.
- The upload control's copy moves to the lazily-loaded optional widget
  catalog and pluralizes per the catalog convention — the eager first-load
  catalogs shrink instead of growing (initial-page ceiling, ADR-0042 D3.6).

* ci(deps): admit MIT-0 in the permissive license allowlist (#3034)

The collected pdfjs/csstools updates pull two transitive packages
(@csstools/color-helpers, @csstools/css-syntax-patches-for-csstree)
published under MIT-0 — MIT without the attribution clause, strictly
more permissive than the MIT, Unlicense, and WTFPL entries already
admitted. The allowlist stays permissive-only; no per-package exception
is needed.

* test(server): satisfy exactOptionalPropertyTypes in the OCR rotation helper (#3031)

The savedOcr map builds entries with explicit undefined kinds; the
declared optional-property type rejected that under
exactOptionalPropertyTypes on the full-graph typecheck.

* fix(gateway): close the wave-13 findings — dedicated embedding connections survive rebuilds (#3031)

- Server (P1): an embedding provider on its OWN endpoint was silently
  rewritten onto the setup-wide gateway connection by any preserve-mode
  rebuild. Dedicated-endpoint embeddings now leave the candidate set and
  are restored verbatim like stored OCR (failure-first pin: connection,
  credential, and kind survive an unrelated image clear, never probed).
- Import: unsupported API key header names refuse at upload time
  (mirroring the gateway's supported set, case-insensitively) instead of
  failing Test & Save after a reported success.
- Settings panel: a failed dialog chunk load now surfaces the redacted
  loading error with a retry control instead of rendering nothing.

* fix(ui): keep uploaded-file content out of the error channel (#3031)

Engine error messages can embed excerpts of the parsed input, and the
uploaded gateway config may carry credentials — both reportError sites
now emit a static, body-free message instead of forwarding the caught
error (the mocked-parser pin asserts the sanitized message).

* fix(release): harden the issue-comment approval gate against its review findings (#3028)

- The approval phrase must stand on a line of its own: a substring match
  read a quoted denial ("DO NOT use Approved-for-publish: ...") as an
  affirmative approval.
- Live GitHub verification runs only for the release being published NOW;
  historical approvals are mutable artifacts and re-fetching them on
  every future publish would brick an append-only catalog the moment one
  is edited or deleted. Structural reference validation stays for every
  retained entry.
- One issue-comment artifact authorizes exactly one catalog record —
  scoped to the comment form deliberately, since unchanged staging
  contracts reuse their historical PR-review reference across versions
  by documented practice.
- The publish workflow doc now describes both accepted evidence forms,
  and the 0.3.0 rationale describes the artifact it actually references
  (owner-authored issue comment, not a backfilled PR review).
- Hermetic pins for all of the above: quoted-denial rejection, duplicate
  artifact rejection, and a reader spy proving historical entries are
  never re-fetched while the current release still verifies live.

* fix(ui): refuse duplicated top-level capability ids in uploaded configs (#3031)

A repeated id silently overwrote the earlier declaration — corrupted
input now refuses the whole file like every other malformed record.

* test(security): pin the omitted-timeout production bound deterministically (#3033)

The read-success protocol test joins the load-proof budget, and the two
tests whose names promised the omitted-timeout default are renamed to
what they actually exercise. The default itself gets REAL pins on both
the read and write paths: the one call that omits timeoutMs runs against
the hanging fixture on purpose — a fast fixture would flake on a
saturated runner (the incident this file hardens against), while the
hang deterministically proves the production bound fires.

* fix(gateway): close the wave-16 findings — every untouched block and connection survives rebuilds (#3031)

- Server (P1): the rebuilt configuration copied only grounding and figma —
  a configured reranker vanished and the persisted config lost its egress
  topology after restart. Every top-level block the rebuild does not
  produce now survives from the current configuration.
- Server (P1): dedicated-embedding identity compares the FULL stored
  connection (endpoint, credential, header) against the stored primary
  provider — a same-endpoint embedding with its own token is restored
  verbatim instead of being rebuilt with the gateway credential, and the
  verbatim-restore token refresh only follows a rotation for providers
  that SHARED the stored gateway connection.
- Server: stored voice ids leave the chat-probe candidate set during
  inherited rebuilds — a succeeding probe persisted a DUPLICATE provider
  next to the restored voice entry.
- Import: a capability flag may only be TRUE on the kind that owns it
  (canonical-parser parity; explicit false stays tolerated everywhere),
  and only a CHAT capability makes the chat flag lists configured — an
  embedding-only declaration no longer clears stored chat flags.
- Dialog: a failed upload-chunk load surfaces the redacted error and a
  retry instead of silently hiding the feature.

All three server repairs are failure-first pinned (probe spies included).

* test(server): pin blank submitted tokens against the endpoint-change guard (#3031)

trimmedSubmittedString already normalizes empty and whitespace-only
strings to undefined, so the exfiltration guard fires — this pin keeps
that equivalence from ever regressing.

* Revert "merge: dependabot #3016 bump @vitejs/plugin-react from 6.0.3 to 6.0.5"

This reverts commit 6fc686af647689e59a49d093fbbf1af837532b5a, reversing
changes made to 21e5e7d52601870d53d979f5938c12930e599f39.

* Revert "merge: dependabot #3015 bump vite from 8.1.4 to 8.2.0"

This reverts commit 21e5e7d52601870d53d979f5938c12930e599f39, reversing
changes made to 2194c2f5743efbdc9f351f31dadd52af01733456.

* fix(release): bind the prerelease tag to the built commit and never orphan the workdir (#3032)

- The release tag targets view.headSha — the exact commit the workflow
  built — instead of the branch ref, so assets and release source cannot
  disagree when the branch advances mid-run or an older --run-id is
  reused (pinned: --target carries the run SHA, never the ref).
- The mkdtemp work directory is removed in a finally block covering every
  exit: refusals through fail() and plan-only runs included (pinned via
  existsSync after a codesign refusal and after a plan-only run).

* fix(ui): close the wave-19 import findings — retry parity, role-bound tuning, lenient defaults (#3031)

- Generic retry tuning must match what the rebuild writes ({2, 500}) or
  the file refuses as unsupportedSetting — a different value would be
  silently rewritten on save. Voice providers stay exempt: the voice
  route inherits their stored tuning.
- Semantic turn detection without realtime support and voice profiles on
  a provider without an output role refuse as corrupted input.
- A partial circuitBreaker block whose omitted keys mean the rebuilt
  defaults now imports instead of refusing.

* fix(release): never orphan the workdir when asset assembly itself refuses (#3037)

A refusal inside downloadAssets (missing artifact, drifting publish set)
threw before the caller's finally existed — the mkdtemp directory now
cleans up on that path too, pinned via existsSync after the
missing-asset refusal.

* fix(release): write the release body via fs, not a shell pipeline (#3037)

CodeQL flagged the sh -c 'cat > path' construction; a direct
writeFileSync removes the shell from the path entirely.

* fix(gateway): patch image flags in place and assert imported embedding kinds (#3037)

- P1: a flags-only image edit (clear or shrink to already-verified ids)
  no longer takes the verified rebuild — it patches the stored capability
  flags in place exactly like workflow eligibility, so a transient smoke
  failure of an unrelated model can never delete that provider during a
  metadata edit (sabotage-proven pin with a flaky-probe double). A NEW
  image claim still demands the vision-probing rebuild (pinned).
- P1: fresh setups accept a client-asserted embeddingModelIds list —
  validated like every deployment list — so an imported embedding whose
  id defies the name heuristic is classified by its declared kind
  instead of being chat-probed and dropped (sabotage-proven pin). The
  upload importer derives the list from the file's capability records
  and the dialog carries it through the payload invisibly.
- The rebuild-class pins whose only trigger was the image clear now ride
  the credential-rotation trigger (the clear is a patch, by design).

* fix(release): bind the prerelease to the built commit's version and its own dispatched run, and keep fenced approval phrases from approving (#3037)

Three review fixes on the 0.3.0 release tooling:

- release-portable-prerelease reads package.json at the workflow run's
  head commit and refuses to publish when that version disagrees with
  the local checkout or when --tag does not name the built version — an
  older --run-id can no longer put another package version's assets
  under a v<version>-beta.N tag.
- dispatchWorkflow captures the pre-dispatch run-id set and polls
  (bounded, through the sleeper seam) until a run appears that was not
  in it, instead of trusting 'gh run list --limit 1' to name the run it
  just created — a previous or concurrent run can sit at the top of
  that list.
- check-release-impact's standalone-line approval check now tracks
  Markdown code fences (backtick and tilde) and blockquotes: a fenced
  example or quoted citation of the Approved-for-publish phrase never
  grants the approval; only a plain standalone line does.

The prerelease fixture tags now derive from the checkout's real
version, so the version-binding happy paths stay green across bumps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(release): verify both macOS seals, copy the publish set via node:fs, and derive approval fixtures from the producer (#3037)

Nine reviewer findings on the portable-prerelease script, its suite, the
release-impact gate suite, and the runbook:

- verifyMacosSeal now codesign-verifies BOTH macOS archives (arm64 and
  x64) — codesign judges the x64 seal statically on an arm64 host — and
  the release body names exactly what was verified; a damaged x64 seal
  refuses the publish (failure-first: the new test showed the old code
  publishing).
- The publish-set assembly uses mkdirSync/copyFileSync behind a new
  withAssetCopier seam instead of /bin/mkdir and /bin/cp spawns; the
  stray-file guard proof is rewired through the seam and still goes red
  when the guard is deleted.
- The accepted "failure" run conclusion is now explained in place: it
  aggregates non-gating lanes while assertStagingJobsSucceeded strictly
  judges the asset-producing jobs.
- The suite resolves the production script path once from
  import.meta.dirname for both the source read and the CLI-shim spawn.
- Source-text pins with behavioral twins are pruned; the four-asset
  publish set is now pinned behaviorally in the create line, and only
  the evaluation-dispatch and skip-warning pins remain as text.
- The non-darwin test asserts the rendered "skipped-non-darwin" line in
  the plan-only release body.
- publishApprovalPhrase is exported and every approval fixture body in
  the governance suite derives from it; the accepting tests also assert
  result.ok.
- The runbook states the approval phrase must stand on a trimmed line of
  its own, outside code fences and blockquotes, matching the gate.

* test(ui): pin the upload guards — sanitized apply-callback failure, read-pending contract, chunk-safe upload queries (#3037)

GatewayConfigUpload.test.tsx: the module mock now passes through to the real
parser by default (the parser-regression pin installs its throw for exactly one
call), adding coverage for two guards the component carries: a throwing onApply
is reported sanitized (exact message equality, no uploaded file content in the
error channel) with the honest invalid state instead of a success count, and the
onReadPendingChange contract — true before the file read starts, false after it
(invocation-order asserted against a Blob.text spy), with the oversize path
ending the flag false and provably never reading or parsing. Each guard was
proven failure-first: removing it turns the matching assertion red.

GatewaySetupDialog.test.tsx: three upload tests queried the lazily loaded
upload control synchronously and only passed because earlier tests had warmed
the dynamic chunk — each fails when run in isolation. They now await
screen.findByLabelText like the file's first upload test, so every test waits
independently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(gateway): carry the voice endpoint protocol through setup, rotate restored auth headers, and align the upload parser with the canonical rules (#3037)

- P1: voiceEndpointStyle/voiceApiVersion/voiceRealtimeAuthMode are now
  first-class setup fields — validated against the gateway's enums,
  submitted-over-template, persisted verbatim — so a fresh save of an
  Azure speech endpoint keeps its deployment URL shape instead of
  falling back to the OpenAI-compatible form (sabotage-proven pin plus
  unsupported-style and style/apiVersion pairing refusals). The upload
  parser imports the protocol from the file's voice connection (uniform
  across its providers, canonical pairing enforced, a SKIPPED realtime
  provider contributes nothing) and the dialog carries it invisibly.
- P2: a restored same-connection OCR/embedding provider now follows an
  authentication-header rotation together with the token (red proof:
  fresh token in the obsolete header), via sharesStoredGatewayConnection.
- P2: voice profiles on a realtime-only provider are refused exactly
  like the canonical parser refuses them (pin).
- P2: the undici override is scoped so jsdom 30 gets its declared ^8
  range while every other consumer keeps the 7.29.0 floor.
- The two identical dynamic-chunk loading fallbacks consolidate into
  DynamicChunkLoadFailure with its own suite (alert, retry, reload
  fallback, silent-while-loading).
- Review strengthenings: voice-hijack refusal now asserts the stored
  endpoint survives; the egress pin asserts the normalized value
  exactly; extracted helpers repair the four lint breaches the previous
  head shipped (complexity/max-lines), which is also why lint runs
  repo-wide in this wave's verification.
- Regenerated 1209 bundle evidence (byte metrics only; totals shrink).

* fix(ui): make hidden imported upload state file-scoped, and pin the governance rejections (#3037)

- P1: a corrected re-upload REPLACES the hidden imported embedding-kind
  list (and, when the file speaks about the voice connection, the
  imported endpoint protocol) instead of inheriting the previous
  file's declarations — a second upload declaring model-x as chat no
  longer submits the first file's embedding assertion (sabotage-proven
  dialog pin on the submitted payload).
- The two governance rejection tests now assert result.ok === false in
  addition to their message expectations.

* fix(gateway,release): file-scoped upload corrections, disk-only egress, exact fence closers, and reviewer strengthenings (#3037)

- P1: the approval-phrase fence walker now tracks the opening marker
  and closes only on the same type at same-or-greater length with no
  trailing text (CommonMark) — a ~~~ line inside a backtick fence or a
  shorter backtick fence inside a longer one can no longer smuggle a
  fenced example into an approval (red-proven regression pins).
- P1: a preserve-mode rebuild persists only the egress the stored file
  declares — the runtime aggregate (env-derived proxy/CA/private-network
  opt-ins) stays in the running process and off the disk, mirroring the
  settings-only path (sabotage-proven pin; fresh setups unchanged, incl.
  the bootstrap-config-file scenario).
- P2: stored embedding kinds now follow the inherited-only rule like
  every other stored restore list, so a corrected explicit deployment
  list can turn a mis-kinded embedding back into chat (red-proven pin).
- P2: the imported voice endpoint protocol is BOUND to the uploaded
  URL — a manually retyped endpoint no longer inherits the file's
  deployment-path shape (red-proven dialog pin).
- DynamicChunkLoadFailure takes an optional messageKey prop; the
  prerelease test resolves package.json from its own location; the
  jsdom undici override is pinned exactly (8.10.0); governance
  rejection tests assert result.ok; keiko-ui coverage baseline gains
  the new source file; 1209 bundle evidence reverted to the
  Linux-anchored measurement (the macOS regeneration was a platform
  artifact — nothing editor-fingerprinted actually changed).

* fix(release): fail closed on ambiguous dispatch binding and publish the prerelease draft-first (#3037)

Two reviewer findings on scripts/release-portable-prerelease.mjs:

- P1 dispatch identity: gh cannot return the created run id, so when two
  operators dispatch the same workflow on the same ref concurrently both
  new ids are unseen and .find() could bind — and publish — the competing
  operator's run. The poll now collects ALL unseen workflow_dispatch run
  ids for the ref (the list is also filtered to --event workflow_dispatch):
  exactly one binds, more than one refuses naming the concurrent-dispatch
  ambiguity, never a guess.

- P2 resumable superseding: the release used to go public on create with
  the predecessor supersede edit running afterwards — a transient edit
  failure left a live release without its superseded pointer and no retry,
  because the existing tag was refused up front. The create now carries
  --draft, the supersede edit runs against a not-yet-public release, and
  gh release edit <tag> --draft=false publishes as the LAST step. On
  resume, a DRAFT carrying the target tag (an interrupted run, judged via
  gh release view <tag> --json isDraft) is deleted and recreated fresh;
  a PUBLISHED release keeps the historical refusal.

Failure-first: the racing-dispatch double (two unseen runs), the
draft-order assertions, the failing-supersede no-draft=false pin, and the
draft-resume test were all red on the old code before the fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(gateway): pin the endpoint-pairing refusal by code and exact message (#3037)

* fix(ui): validate imported Azure api versions and state the voice retry-tuning reset loudly (#3037)

- P2: the upload parser now mirrors the gateway's API_VERSION_RE
  (YYYY-MM-DD or -preview) — a malformed apiVersion refuses the file at
  upload instead of failing Test & Save after a reported success
  (red-proven pin).
- P2: per-role voice retry tuning the flat form cannot express (the
  owner's file tunes TTS to maxRetries 3) no longer resets silently on
  a fresh import: the upload applies with the reduction STATED, exactly
  like voiceProfilesReduced (red-proven pin; en/de messages).

* fix(release): close three prerelease reviewer findings — indented-code approvals, plan-only draft deletion, stale tag-ref publishing (#3037)

- check-release-impact: a four-space- or tab-indented approval phrase is a
  CommonMark indented code block and can never approve; up to three spaces
  stays an ordinary paragraph (boundary pinned).
- release-portable-prerelease: the interrupted-draft deletion moves onto the
  actual publish path — a --plan-only preview mutates nothing and states the
  pending draft recovery in its plan output.
- release-portable-prerelease: before creating, the requested tag is resolved
  as a remote git ref (annotated tags peeled); an existing ref not at the
  built commit refuses, because gh release create --target binds only a tag
  that does not yet exist. The hermetic double answers the lookup 404 by
  default so every existing scenario keeps its meaning.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): make the invisible configured flags file-scoped like every hidden import (#3037)

A first upload declaring an explicit empty flag list left the invisible
configured flag armed forever — a corrected second file that stays
silent about the flag lists then submitted an empty clear the file
never asked for. Each upload now states whether THIS file speaks about
the lists; visible textarea values keep their user-correctable
persistence (red-proven dialog pin on the submitted payload).

* fix(release,ui): bind the release tag atomically at the built commit, and close two voice-protocol binding edges (#3037)

- The tag is now created atomically via a git/refs POST at the built
  commit BEFORE the release exists; an existing-ref conflict re-reads
  and validates, and gh release create runs with --verify-tag instead
  of --target — closing the check-then-create window in which a moved
  tag could re-bind fresh assets (pin relocation: the commit binding
  moved from the --target flag to the POST line, strictly stronger).
- The imported voice endpoint URL is stored trimmed, matching the
  submit-time comparison, and the positive branch of the protocol
  binding is pinned (upload -> submit carries the protocol verbatim).

* test(release): decompose the gh double's answer lookup below the complexity bar (#3037)

* fix(release,gateway): close three reviewer classes — lazy blockquote approvals, unbound --run-id refs, position-based primary classification (#3037)

- P1: the approval walker now carries CommonMark lazy-continuation
  state — a non-blank line directly after a blockquote line renders
  inside the quote and can never approve; a blank line ends the quote
  (red-proven both directions).
- P1: a supplied --run-id must be a workflow_dispatch run on exactly
  the requested ref — a successful evaluation run of an unmerged
  feature branch with a matching version could previously publish
  branch bytes publicly (two red-proven refusals; the dispatch path
  satisfies the rule by construction).
- P2: the stored primary gateway provider is now derived by capability
  instead of array position — a stored file listing a voice provider
  first no longer misclassifies a chat-sharing embedding as dedicated
  and restores it with its revoked credential after a rotation
  (red-proven pin).

* fix(release,gateway): invisible HTML-comment approvals, gap-tolerant supersede, and shared-connection endpoint moves (#3037)

- P1: a phrase inside a multi-line HTML comment renders nothing on
  GitHub and can no longer approve a publish (red-proven; a phrase
  after a CLOSED comment still approves).
- P2: previousBetaTag now picks the GREATEST existing lower beta, so a
  --tag override that skips numbers still supersedes the live latest
  beta (red-proven).
- P2: sharing is judged against the STORED primary connection and a
  shared provider follows the gateway wherever the update moves it —
  URL, token, and header travel together; dedicated connections stay
  untouched (red-proven on an endpoint move).

* fix(release,ui,security): column-aware code indentation, monotonic beta overrides, canonical locality ownership, and a leak-free hanging fixture (#3037)

- P1: indented-code detection in the approval walker now expands tabs
  to 4-column stops (CommonMark) — a space-plus-tab indent renders as
  code and can no longer approve; three plain spaces stay a paragraph
  (red-proven both directions).
- P1: the keychain HANGS fixture execs sleep instead of forking it, so
  the spawn timeout's kill reaches the hanging process itself — no
  orphaned sleeps leak across later suites.
- P2: a --tag override below the highest existing beta refuses — a
  lower newest release would leave the real highest beta unsuperseded
  (red-proven; resuming the highest beta's own draft stays allowed).
- P2: the upload parser rejects voiceProviderLocality on a non-voice
  capability, matching the canonical assertNoVoiceFieldsForNonVoiceKind
  (red-proven).

* fix(release): walk every HTML-comment marker on a line in the approval gate (#3037)

A single '-->' followed by '<!--' on one line closes a comment and
opens the next — judging only the first marker ended the comment state
while GitHub kept rendering the following lines invisibly. Every marker
is now processed in order; an inline comment leaves no open state
(red-proven both directions).

* fix(release,gateway,ui): raw-HTML approval blocks, chat-role primary, and voice-role replacement on corrected uploads (#3037)

- P1: the approval walker excludes raw-HTML blocks — <pre>/<script>/
  <style>/<textarea> run to their closing tag (blank lines included),
  any other '<'-opened block runs to the next blank line; a phrase
  inside renders as markup and can never approve (red-proven; phrases
  after closed blocks still approve).
- P2: the stored primary is the main CHAT connection (absent capability
  defaults to chat) — a dedicated embedding/OCR listed first no longer
  misclassifies chat-sharing providers as dedicated (red-proven).
- P2: an uploaded voice section REPLACES the form's role set, so a
  corrected file that dropped a role cannot silently re-add it via the
  stale visible field (red-proven).
- Review strengthenings: positive dedicated-header pin, tag-POST-
  before-create ordering pin, and the equal-index boundary of the
  monotonicity guard.

* fix(release,ui): list-item approval contexts, default draft resumption, and file-scoped voice profiles (#3037)

- P1: blockquotes and LIST ITEMS share the container-continuation rule
  in the approval walker — an instructional list ('- To approve, use:')
  keeps the marker inside the item, indented or lazy, until a blank
  line ends the container (red-proven; a phrase after the list still
  approves).
- P1: an ordinary retry after a crash between create and publish now
  RESUMES the highest existing beta when it is a draft instead of
  allocating the next number — the old default picked the still-private
  draft as predecessor and left the live release unsuperseded
  (red-proven).
- P2: the output voice is file-scoped with the roles — a corrected
  voice section that dropped voiceProfiles clears the field and its
  configured flag, so the form demands a voice VISIBLY instead of
  silently persisting the removed profile (red-proven).

* refactor(release): extract the container-continuation check below the complexity bar (#3037)

* fix(release,ui): column-zero approval anchoring, canonical URL import rules, secret-ref refusal, and paginated tag lineage (#3037)

- P1: the approval marker must start at column zero — leading
  indentation can be list-item continuation context (including a
  blank-separated child paragraph), so the former three-space paragraph
  tolerance is strengthened away; trailing whitespace stays tolerated
  (red-proven; documented strengthening of the relocated pin).
- P2: the upload parser mirrors validateBaseUrl — absolute http(s),
  plaintext http only on loopback, no credentials/query/fragment — so a
  malformed URL refuses at upload instead of failing Test & Save
  (red-proven).
- P2: apiKeySecretRef refuses on every provider kind: no form field can
  carry a secret reference, and the product's own persisted file keeps
  its credentials in the sealed vault outside the JSON (red-proven).
- P2: release-tag lineage derivation paginates past 100 releases
  (--paginate --slurp), so beta numbering and supersede pointers stay
  correct on long histories.

* fix(release,ui): fence-opaque walker ordering, canonical loopback range, and expanded URL refusal pins (#3037)

- The approval walker judges an OPEN fence before comment/HTML state:
  an unclosed <!-- inside a fenced example no longer poisons the state
  past the closing fence (the ordering pin was red before this fix).
- representableBaseUrl mirrors validateBaseUrl's loopback set exactly —
  localhost, ::1 bracketed or not, and all of 127.0.0.0/8.
- URL refusal pins gain the credential and fragment branches.

* fix(release,server,ui): close the eighth review wave — fence-closer indentation, workflow-identity run binding, publish-boundary tag recheck, canonical voice refusals, protocol-scoped voice mutations (#3037)

- check-release-impact: a would-be closing fence indented four-plus columns
  (or a tab) is fenced CONTENT (CommonMark allows at most three) — judged on
  the raw line, so an over-indented closer can no longer end the fence early
  and let the next column-zero phrase approve; runbook now states the
  column-zero requirement explicitly.
- release-portable-prerelease: a supplied --run-id must belong to the
  portable-assets workflow itself (workflowDatabaseId resolved from the
  workflow path — same-branch impostor workflows with identical job/artifact
  names are refused); the publication boundary re-reads the tag ref and
  refuses a moved OR vanished tag (a draft's tag stays mutable until
  publication; --verify-tag only proved existence at create).
- ADR-0163/portable-assets.yml: reconciled the 'never publishable' evaluation
  wording with the owner-approved beta prerelease program the document's own
  D9 amendment already acknowledges (stable release bundle stays closed).
- keiko-ui gatewayConfigParsing: mirror two more canonical refusals — a
  transcription model requires supportsRealtimeVoice, and every voice
  capability must declare voiceProviderLocality (no silent azure-foundry
  default; drifted absence now surfaces as disagreement, never a rewrite).
- keiko-server gateway-setup: voiceEndpointStyle/voiceApiVersion/
  voiceRealtimeAuthMode are connection mutations — an unscoped protocol
  update across heterogeneous audio connections is refused instead of
  spreading an Azure protocol onto an OpenAI-compatible realtime endpoint.

All behavioral fixes proven failure-first (new pins red on the prior code,
sabotage-inverse for the two script guards); 45+52+198+221 tests green,
tsc, eslint (root+ui), prettier, local sonar PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui,ci): voice section requires its base URL, strict file-scope role gate, zizmor anchors advanced (#3037)

KfQ wave on 4f928ee7 plus the CI red it left:
- gatewayConfigParsing: a voice section whose providers carry no baseUrl is
  refused as invalid (the canonical parser requires baseUrl on every provider
  and the sealed file always carries it) — role ids can no longer arrive
  while voiceBaseUrl stays undefined; new pin red before the fix.
- GatewaySetupDialog.applyUploadedVoiceRoles: the file-scope gate alone
  decides (speaksAboutVoice), now provably whole through the parser refusal.
- .github/zizmor.yml: the portable-assets.yml shell anchors moved two lines
  with the evaluation_build description edit (129→131, 199→201) — exactly
  what check-zizmor-anchors reported in both red coverage lanes.

222/222 modals, 12/12 anchor tests, ui lint, tsc, prettier, sonar PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@oscharko

oscharko commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Integrated into dev through the review-complete collector #3037 (squash commit 8df349b) — every finding raised here was carried, repaired failure-first, and re-reviewed there. Closing in favor of the collector.

@oscharko oscharko closed this Aug 8, 2026
@oscharko
oscharko deleted the deps/dependabot-collector branch August 13, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant