chore: collect the five review-complete 0.3.0 hardening PRs into one integration - #3037
Conversation
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>
…ublish 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>
…njected 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>
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>
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>
… 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>
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
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>
…#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>
…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>
…udget 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>
… 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>
#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>
…ion (#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>
…h 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>
… 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.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
scripts/check-release-impact.mjs (1)
441-446: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHTML-comment context is evaluated before fence context, and no test pins that path.
approvalContextLinecallshtmlCommentContextLinebefore it checksstate.openFence, so an unclosed<!--inside a fenced example consumes the closing fence line and leaves bothinHtmlCommentandopenFenceset. Every later line stays context, and a valid column-zero approval phrase is rejected. The direction is fail-closed, so no approval leaks.
scripts/check-release-impact.mjs#L441-L446: move thestate.openFencecheck abovehtmlCommentContextLineandhtmlBlockContextLine.scripts/__tests__/release-impact-governance.test.mjs#L662-L673: add a case with a fenced block containing an unclosed<!--, followed by a blank line and the column-zero phrase, and assertokistrue.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/check-release-impact.mjs` around lines 441 - 446, The approvalContextLine logic must prioritize fenced-block handling: move the state.openFence check before htmlCommentContextLine and htmlBlockContextLine so a closing fence is processed even when the fenced content contains an unclosed HTML comment. Add a regression case in scripts/__tests__/release-impact-governance.test.mjs:662-673 covering an unclosed <!-- inside a fence, a following blank line, and a column-zero approval phrase, asserting ok is true.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.ts`:
- Around line 535-547: Extend the badUrl cases in the test “refuses base URLs
the canonical parser cannot accept” to include one URL with embedded credentials
and one URL containing a fragment, ensuring representableBaseUrl’s credential
and url.hash rejection branches are covered while preserving the existing
loopback acceptance case.
In `@packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts`:
- Around line 363-379: Update representableBaseUrl’s loopback HTTP host
validation to match validateBaseUrl: accept localhost, ::1/[::1], and every
well-formed IPv4 address in 127.0.0.0/8, while preserving the existing HTTPS,
credential, query, and fragment restrictions.
In `@scripts/__tests__/release-impact-governance.test.mjs`:
- Around line 662-673: Extend the release-impact governance tests near the
close-then-reopen case with a fenced-block scenario containing an unclosed HTML
comment followed by a column-zero approval phrase. Assert the validator’s
accepted behavior for this sequence, exercising the interaction between
htmlCommentContextLine and state.openFence while preserving the existing
inline-comment and reopened-comment expectations.
---
Duplicate comments:
In `@scripts/check-release-impact.mjs`:
- Around line 441-446: The approvalContextLine logic must prioritize
fenced-block handling: move the state.openFence check before
htmlCommentContextLine and htmlBlockContextLine so a closing fence is processed
even when the fenced content contains an unclosed HTML comment. Add a regression
case in scripts/__tests__/release-impact-governance.test.mjs:662-673 covering an
unclosed <!-- inside a fence, a following blank line, and a column-zero approval
phrase, asserting ok is true.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: eda77647-fb4d-4b32-84b3-e24e6c3a2158
📒 Files selected for processing (10)
packages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.tsscripts/__tests__/release-impact-governance.test.mjsscripts/__tests__/release-portable-prerelease.test.mjsscripts/check-release-impact.mjsscripts/release-portable-prerelease.mjs
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: sign review store
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx,js,mjs,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use Prettier formatting: 2-space indentation, double quotes, semicolons, 100-column width, trailing commas, and LF endings.
Files:
scripts/__tests__/release-impact-governance.test.mjsscripts/__tests__/release-portable-prerelease.test.mjspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxscripts/check-release-impact.mjspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tsscripts/release-portable-prerelease.mjspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
**/*
📄 CodeRabbit inference engine (AGENTS.md)
**/*: Use English in code, comments, identifiers, documentation, commit messages, issues, and pull requests.
Respect the inward dependency direction:keiko-contractsis the leaf,keiko-securitydepends only on contracts, and cross-package types belong in contracts.
Inspect and reuse existing helpers, contracts, and subsystems; do not create parallel workspace, graph, policy, evidence, memory, connector, workflow, or UI subsystems without a documented capability gap.
Keep manifests, audit exports, diagnostics, logs, configuration, tests, and evidence redacted: never expose secrets, keys, raw content, endpoints, PII, memory bodies, or customer data.
Never weaken trust boundaries, evidence redaction, governance gates, required checks, or authority limits to make a change pass; fail closed.
Never directly push todev, force-push, bypass required checks, dismiss findings to obtain green status, or merge outside the approved direct-check path.
Use branch names in the formtype/short-slug, never work directly ondev, and use imperative conventional commit subjects with an issue or PR reference and no secrets.
Run the applicable local typecheck, lint, format check, tests, architecture checks, Sonar gate, and touched-area gates before claiming a change or pull request is green; report only commands actually executed.
Files:
scripts/__tests__/release-impact-governance.test.mjsscripts/__tests__/release-portable-prerelease.test.mjspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxscripts/check-release-impact.mjspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tsscripts/release-portable-prerelease.mjspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
**/*.{ts,tsx,js,mjs}
📄 CodeRabbit inference engine (AGENTS.md)
Delete dead code instead of commenting it out and do not leave scaffolding or TODOs hiding unfinished branches.
Files:
scripts/__tests__/release-impact-governance.test.mjsscripts/__tests__/release-portable-prerelease.test.mjspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxscripts/check-release-impact.mjspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tsscripts/release-portable-prerelease.mjspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
**/*.test.{ts,tsx,mjs}
⚙️ CodeRabbit configuration file
**/*.test.{ts,tsx,mjs}: A behavioral fix needs a failure-first regression proof that fails without the fix. Cover
malformed, hostile, empty, and boundary inputs; never relax a regression pin or duplicate a
production formula inside a fixture.
Files:
scripts/__tests__/release-impact-governance.test.mjsscripts/__tests__/release-portable-prerelease.test.mjspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-server/src/gateway-setup.test.ts
scripts/**
⚙️ CodeRabbit configuration file
scripts/**: Gate and evidence tooling must fail closed, remain deterministic and redacted, and carry
negative tests proving that weakened configuration or stale evidence is rejected.
Files:
scripts/__tests__/release-impact-governance.test.mjsscripts/__tests__/release-portable-prerelease.test.mjsscripts/check-release-impact.mjsscripts/release-portable-prerelease.mjs
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use strict TypeScript settings, forbidany, require explicit function return types, and model states with discriminated unions rather than casts.
Keep cyclomatic complexity at or below 10, keep functions within 50 non-comment lines, and extract helpers when necessary.
Use the intended logger or diagnostic sink instead ofconsole.*in product code.
Validate hostile inputs before processing, fail closed at trust boundaries, and never route generated or model-produced code around the sandbox egress boundary.
Do not swallow errors with empty catches; surface sufficient diagnostic context, including a correlation ID for server-visible opaque 500 errors.
Files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
packages/keiko-ui/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
packages/keiko-ui/**/*.{ts,tsx}: Thekeiko-uiworkspace must enforce the root values for complexity, maximum function length, and explicit function return types; its suppression register may only shrink.
The UI must communicate with the server through shared contract types and must not redeclare governed wire types.
Files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
**/*.{test,spec}.{ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Tests must be hermetic: no real network, shared mutable global state, wall-clock or ordering races, or assumptions that a port is free; await conditions instead of sleeping.
Files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-server/src/gateway-setup.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{test,spec}.{ts,tsx}: Regression tests must fail before the fix and pass afterward; fixtures and mocks must derive expectations through production entry points rather than reimplementing formulas.
Cover empty, boundary, malformed, and hostile inputs, including both branches of every guard added.
Files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-server/src/gateway-setup.test.ts
packages/keiko-ui/**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
When changing UI code or styling, preserve the SHA-pinned visual-proof and accessibility expectations and run the required UI gates.
Files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
packages/**/src/**
⚙️ CodeRabbit configuration file
packages/**/src/**: Enforce ADR-0019 package direction and the owning trust boundary. Flag provider SDK imports
outside keiko-model-gateway, cross-package wire types outside contracts, workspace escape,
raw evidence bodies, silent failures, and parallel subsystems that should extend an owner.
Files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
packages/keiko-server/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
The server may use domain packages but must not depend on
keiko-editor; domain packages must not depend on the server.
Files:
packages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.ts
🧠 Learnings (6)
📚 Learning: 2026-07-25T18:42:13.123Z
Learnt from: oscharko
Repo: oscharko-dev/Keiko PR: 2716
File: packages/keiko-tools/src/editor-agent-client.test.ts:692-692
Timestamp: 2026-07-25T18:42:13.123Z
Learning: In Keiko TypeScript test files, do not request explicit return type annotations for callbacks passed to typed Vitest `it(...)` and `it.each(...)`. Specifically, avoid adding `: void` or `: Promise<void>` to those callback functions when the ESLint rule `typescript-eslint/explicit-function-return-type` is configured with `allowTypedFunctionExpressions: true` (i.e., typed function expressions are intentionally exempt). Only ask for explicit return types if the ESLint configuration changes; otherwise preserve the existing surrounding test-file style.
Applied to files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-server/src/gateway-setup.test.ts
📚 Learning: 2026-07-26T21:23:56.288Z
Learnt from: oscharko
Repo: oscharko-dev/Keiko PR: 2755
File: packages/keiko-server/src/grounded-qa-hybrid.ts:1006-1012
Timestamp: 2026-07-26T21:23:56.288Z
Learning: In Keiko’s internal “stable-ID” hash helper functions (e.g., where stable identifiers are computed for persistence/comparison), preserve the existing UTF-16 code-unit iteration semantics when modernizing. Specifically, if the current implementation iterates with `charCodeAt(i)` (code units) rather than `codePointAt(i)` (Unicode code points), keep `charCodeAt(i)` to avoid changing the resulting stable IDs. If changing from `charCodeAt` to `codePointAt` is ever desired, it must be an explicitly planned compatibility/migration decision (e.g., versioning, backfill, or dual-read/write) rather than a mechanical refactor.
Applied to files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
📚 Learning: 2026-07-27T10:55:30.485Z
Learnt from: oscharko
Repo: oscharko-dev/Keiko PR: 2766
File: packages/keiko-server/src/qualityIntelligence/figmaSnapshotRoutes.test.ts:1738-1738
Timestamp: 2026-07-27T10:55:30.485Z
Learning: When reviewing TypeScript files, do not flag single-quoted string literals as a violation if they match Prettier’s formatter-approved output. Specifically, if Prettier is configured to prefer double quotes but retains a single-quoted literal solely because switching to double quotes would require escaping embedded double quotes, allow the single quotes (i.e., don’t “fix” it beyond what Prettier would produce).
Applied to files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
📚 Learning: 2026-07-27T18:08:22.461Z
Learnt from: oscharko
Repo: oscharko-dev/Keiko PR: 2780
File: packages/keiko-server/src/store/migrations.test.ts:78-95
Timestamp: 2026-07-27T18:08:22.461Z
Learning: When reviewing TypeScript lint findings (e.g., from typescript-eslint/no-unsafe-assignment), ensure the issue is reproducible using the repository’s configured ESLint setup/TS project settings. Do not treat diagnostics observed under a mismatched TypeScript project/tsconfig as authoritative; only accept them as real if you can reproduce them with the same ESLint configuration the repo uses (e.g., via its full/targeted lint scripts). In related test code, prefer deriving branded identity types from the production function return types to keep RootIdentity/brand fields type-compatible and avoid unsafe assignments.
Applied to files:
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.tspackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsxpackages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsxpackages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.tspackages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts
📚 Learning: 2026-07-27T18:21:19.134Z
Learnt from: oscharko
Repo: oscharko-dev/Keiko PR: 2779
File: scripts/check-local-state.mjs:0-0
Timestamp: 2026-07-27T18:21:19.134Z
Learning: In CLI guard logic inside `scripts/check-*.mjs`, avoid manually building `file://` URLs like `file://${process.argv[1]}` (it can produce incorrect path encoding). Convert the CLI path to a proper file URL using Node’s URL utilities (e.g., `pathToFileURL(process.argv[1]).href`) so paths with spaces/special characters (and platform differences like Windows) are handled correctly. If this fix is unrelated to the current PR, handle it via a separate follow-up change.
Applied to files:
scripts/check-release-impact.mjs
📚 Learning: 2026-07-24T19:25:13.892Z
Learnt from: oscharko
Repo: oscharko-dev/Keiko PR: 2697
File: packages/keiko-server/src/editor/inlineCompletionRoutes.ts:616-616
Timestamp: 2026-07-24T19:25:13.892Z
Learning: In `packages/keiko-server`, follow ADR-0141 D5’s AppSession/request-authorization model for workspace root resolution. When reviewing code that performs the `resolveRequestRoot`-style authorization gate, ensure it (1) re-proves persisted workspace identity, (2) derives the request root path, (3) enforces canonical realpath containment within the expected workspace/root to prevent path traversal, (4) verifies workspace presence/validity, and (5) requires a live AppSession (launcher-attested, process-scoped authority per BFF). Do not require a task identity for this gate if AppSession does not model task identity; authorization should be uniform and based on the same-user local threat model rather than per-task/per-workspace session semantics.
Applied to files:
packages/keiko-server/src/gateway-setup.test.tspackages/keiko-server/src/gateway-setup.ts
🔇 Additional comments (13)
scripts/release-portable-prerelease.mjs (1)
203-224: LGTM!Also applies to: 267-277, 692-724
scripts/__tests__/release-portable-prerelease.test.mjs (1)
7-7: LGTM!Also applies to: 64-73, 229-229, 284-293, 363-363, 395-395, 516-516, 811-838, 848-848, 955-955
scripts/check-release-impact.mjs (3)
430-436: LGTM!
461-477: LGTM!
402-424: LGTM!scripts/__tests__/release-impact-governance.test.mjs (2)
598-601: LGTM!Also applies to: 618-642, 701-709
644-660: LGTM!packages/keiko-server/src/gateway-setup.ts (1)
731-742: LGTM!packages/keiko-server/src/gateway-setup.test.ts (1)
3339-3341: LGTM!Also applies to: 3447-3503
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.ts (1)
43-51: LGTM!Also applies to: 546-559
packages/keiko-ui/src/app/components/desktop/modals/gatewayConfigParsing.test.ts (1)
549-557: LGTM!packages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.tsx (1)
2127-2133: LGTM!Also applies to: 2360-2390, 2407-2431, 2686-2690
packages/keiko-ui/src/app/components/desktop/modals/GatewaySetupDialog.test.tsx (1)
1605-1667: LGTM!Also applies to: 1669-1726
…ge, 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.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d382e6593
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ndentation, 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>
…le gate, zizmor anchors advanced (#3037) KfQ wave on 4f928ee 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>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eaf37fdd5e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|



What
Owner-directed collector (2026-08-08): the five review-complete 0.3.0 hardening PRs, combined into one integration so they stop invalidating each other under strict up-to-date protection. Every branch merges cleanly; the union is verified as a whole below.
release:prerelease) with hermetic refusal-path suite (96.6% lines), commit-bound release target, workdir cleanupThe individual PRs remain the review record; they will be closed with a pointer once this collector merges.
Reuse / No-Duplication
Nothing new beyond the already-reviewed source branches; this PR adds zero own commits besides the five merges.
Verification
Union verified as a whole after
npm installon the bumped lockfile: full-graphnpm run typecheck, gateway-setup server suite, keiko-ui modal + lib suites, prerelease script suite, keychain suite,node scripts/check-release-impact.mjs, owner-config parse probe, andnpm run gates:sonaron the combined diff. Individual-branch verification (including failure-first pins for every server repair and the isolated first-load measurements) is documented in the source PRs.Update-Impact
The union of the source PRs; see their Update-Impact sections. Nothing beyond them.
🤖 Generated with Claude Code