chore: sync with upstream 2026-07-28 - #86
Conversation
This is an automated nightly unsafe-cast remediation sweep. It replaces a high-risk request-body assertion at the authenticated session prompt boundary with Zod-backed parsing, following the TypeScript Coding Standards guidance for unsafe casts and parse-don't-assert validation. The shared schemas follow the Zod boundary-validation pattern established in PR ColeMurray#807. | Finding | Risk | Cast Removed | Fix | | --- | --- | --- | --- | | `packages/control-plane/src/routes/session-prompt.ts:43` | HIGH | `(await request.json()) as { content: string; source?: string; model?: string; reasoningEffort?: string; attachments?: unknown; callbackContext?: CallbackContext }` | Added shared `sendPromptRequestSchema` and `callbackContextSchema`, then used `safeParse` at the request boundary before forwarding prompt data. | Verification: | Command | Result | | --- | --- | | `npm run build -w @open-inspect/shared` | Passed | | `npm run build -w @open-inspect/control-plane` | Passed | | `npm run typecheck` | Passed | | `npm run lint` | Passed in a clean repo view after temporarily moving untracked local `.opencode` helper files that are not part of this branch or repository checkout. | | `npm run format` | Passed | | `npm test -w @open-inspect/shared -- --run src/types/boundary-schemas.test.ts` | Passed | | `npm test -w @open-inspect/control-plane -- --run src/router.session-prompt.test.ts` | Passed | | `npm test -w @open-inspect/shared` | Passed | | `npm test -w @open-inspect/control-plane` | Passed | --- *Created with [Open-Inspect](https://open-inspect-prod.vercel.app/session/a3ffb0d8f57202df1cc68ec9338de239)* Co-authored-by: waclaude <colemurray.cs+ghwaclaude@gmail.com> Co-authored-by: Cole Murray <colemurray.cs@gmail.com>
…1122) ## Summary Fixes **10 root-cause task units** identified by the nightly React Doctor scan while preserving existing behavior. The changes improve screen-reader form associations, avoid redundant render and parsing work, and simplify one frequently rebuilt helper. ## Tasks Fixed 1. **`react-doctor/async-parallel`** - `packages/web/src/app/api/image-builds/route.ts`: three independent response bodies were parsed sequentially. Parsing them together reduces avoidable endpoint latency. **Human severity: medium.** 2. **`react-doctor/label-has-associated-control`** - `packages/web/src/components/settings/integrations/github-integration-settings.tsx` (code-review instructions): the visible label was not programmatically tied to its textarea, making the field harder to identify with a screen reader. Added matching `htmlFor`/`id`. **Human severity: medium.** 3. **`react-doctor/label-has-associated-control`** - `packages/web/src/components/settings/integrations/github-integration-settings.tsx` (comment-action instructions): the visible label was not programmatically tied to its textarea. Added matching `htmlFor`/`id`. **Human severity: medium.** 4. **`react-doctor/label-has-associated-control`** - `packages/web/src/components/settings/integrations/linear-integration-settings.tsx`: the issue-session instructions label was not tied to its textarea. Added matching `htmlFor`/`id`. **Human severity: medium.** 5. **`react-doctor/prefer-module-scope-pure-function`** - `packages/web/src/components/settings/sandbox-settings.tsx`: `normalizePorts` was recreated on every editor render despite capturing no render state. Hoisted it to module scope. **Human severity: low.** 6. **`react-doctor/js-combine-iterations`** - `packages/web/src/components/settings/sandbox-settings.tsx`: port normalization made repeated filter/map passes and intermediate arrays. Replaced them with one behavior-preserving pass. **Human severity: low.** 7. **`react-doctor/label-has-associated-control`** - `packages/web/src/components/settings/sandbox-settings.tsx`: the visible Web Terminal label was not associated with its switch. Added matching `htmlFor`/`id`. **Human severity: medium.** 8. **`react-doctor/control-has-associated-label`** - `packages/web/src/components/settings/sandbox-settings.tsx`: the Web Terminal switch lacked an accessible name. The same visible label/control association now supplies it. **Human severity: medium.** 9. **`react-doctor/jsx-no-constructed-context-values`** - `packages/web/src/components/sidebar-layout.tsx`: the app-shell actions context received a fresh object each render, needlessly redrawing consumers. Memoized the value over its actual dependencies. **Human severity: low.** 10. **`react-doctor/jsx-no-constructed-context-values`** - `packages/web/src/components/ui/toggle-group.tsx`: the toggle-group context received a fresh object each render. Memoized it over `variant` and `size`. **Human severity: low.** ## Task Counting A diagnostic with a non-null `fixGroupId` counts with every diagnostic in that group as one task unit; an ungrouped diagnostic counts individually. All 10 selected diagnostics were ungrouped. No `fixGroupId` was split or partially fixed. The Web Terminal label and control diagnostics are therefore counted as two task units even though one association resolves both. ## React Doctor Results - Before: **131 total** (1 error, 130 warnings) - After: **121 total** (1 error, 120 warnings) - Raw diagnostics cleared: **10** - New stable diagnostic signatures: **0** - Relevant rule counts: - `async-parallel`: 1 -> 0 - `label-has-associated-control`: 21 -> 17 - `control-has-associated-label`: 2 -> 1 - `prefer-module-scope-pure-function`: 1 -> 0 - `js-combine-iterations`: 8 -> 7 - `jsx-no-constructed-context-values`: 2 -> 0 ## Validation - `npm run build -w @open-inspect/shared` - passed - `npm run typecheck -w @open-inspect/web` - passed - `npm exec prettier -- --check packages/web` - passed - `npm run lint -w @open-inspect/web` - passed - `npm test -w @open-inspect/web` - passed, 109 files and 933 tests - `env -u NODE_ENV npm run build -w @open-inspect/web` - passed - Full React Doctor after-scan - passed, selected tasks absent and no new stable finding signatures - `npx -y react-doctor@latest . --verbose --scope changed --base origin/main --yes --blocking none` - completed; only three pre-existing `prefer-useReducer` warnings in touched files remain - `git diff --check` - passed The initial baseline production build inherited a non-standard `NODE_ENV` and failed while prerendering `/automations/new`; rerunning with `NODE_ENV` unset passed. No pre-existing validation failures remain under the project command's expected environment. ## Deferred The remaining 121 diagnostics are explicitly left for later batches or human judgment. This includes migration-scale component splitting and state consolidation, auth-related Zod migration work, local-storage key migration, iframe sandbox policy, locale/time-zone UX decisions, image optimization requiring source/runtime validation, and effect/state diagnostics whose safe fixes require broader ownership decisions. Canonical validation also identified these current false positives, which were not suppressed or edited: - `effect-needs-cleanup` in `use-session-transport.ts`: teardown already closes the socket and clears timers. - `no-loading-flag-reset-outside-finally` in `use-sidebar-sessions.ts`: the loading flag is already reset inside `finally`. - `no-json-parse-stringify-clone` in `session-target.test.ts`: JSON serialization is intentional to verify that `undefined` is omitted; `structuredClone` would change the test's semantics. ## Visual Verification No browser artifact was required because these changes do not alter rendered layout, styling, or content. Form IDs/associations and context/value allocation are non-visual. Co-authored-by: waclaude <colemurray.cs+ghwaclaude@gmail.com>
## Summary - require a subscribed client identity before any non-transport WebSocket message can run - disable Better Auth direct Google ID-token sign-in while preserving authorization-code + PKCE - add regression coverage for unauthenticated stop/typing and hostile browser origins ## Security impact - unauthenticated sockets can no longer stop active work or trigger sandbox warming - callers cannot exchange a directly supplied Google ID token for an Open Inspect session - existing signed web-channel and Better Auth origin checks remain unchanged ## Validation - `npm run test -w @open-inspect/control-plane` (2,111 tests) - `npm run test:integration -w @open-inspect/control-plane` (654 tests before the final characterization-only additions) - focused auth/WebSocket integration suite (39 tests) - `npm run typecheck -w @open-inspect/control-plane` - `npm run lint -w @open-inspect/control-plane` - `npm run build -w @open-inspect/control-plane` ## TDD evidence - the pre-subscription stop test failed by mutating the processing message and timing out before the guard was added - the Google provider configuration test failed with `disableIdTokenSignIn` unset before the option was added <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Security** * Google sign-in now uses the approved flow: when Google is configured, ID-token sign-in is disabled. * Social sign-in requests from untrusted browser origins (with invalid session cookies) are rejected and do not set cookies. * **Bug Fixes** * WebSocket clients must subscribe before sending actions like typing or stopping execution; pre-subscription typing closes with code `4002`, and stop does not mark the in-flight message as failed. * **Tests** * Added/extended integration coverage for these authentication and WebSocket security boundaries. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - remove the unconditional skip for pull requests authored by the configured GitHub App bot - route bot-authored pull requests through the existing `allowedTriggerUsers` gate - make approved self-reviews comment-only because GitHub does not allow PR authors to approve their own pull requests - document the updated behavior and cover both allowlisted and rejected bot senders ## Why Automation sessions create pull requests with the GitHub App installation identity. The GitHub bot previously skipped those pull requests before evaluating the configured trigger-user allowlist, so adding `open-inspect[bot]` as an allowed trigger user had no effect. ## Impact Administrators can now opt into reviews of automation-created pull requests by adding the App bot login, including the `[bot]` suffix, to **Allowed Trigger Users**. Bot-authored pull requests remain rejected when the bot is not on that list. Self-reviews submit `COMMENT` reviews so findings are published without attempting an invalid self-approval. ## Validation - `npm test -w @open-inspect/github-bot` — 130 tests passed - `npm run typecheck -w @open-inspect/github-bot` - `npm run lint -w @open-inspect/github-bot` - `npm run build -w @open-inspect/github-bot` - `git diff --check` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added configurable support for reviewing bot-created pull requests when the bot is included in the allowed trigger list. * Bot-authored pull requests now use comment-only reviews, complying with GitHub’s restriction against self-approval. * **Documentation** * Updated guidance for configuring allowed trigger users and handling bot-created pull requests. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary - add a July 26 changelog entry for the Better Auth browser-authentication cutover - document control-plane-owned sessions, GitHub and optional Google sign-in, and the signed web proxy - call out the required sign-in after legacy browser tokens are retired ## Why The Better Auth runtime and full browser-authentication cutover merged in ColeMurray#1125 and ColeMurray#1126, but the user-facing changelog did not yet describe the change or its upgrade impact. ## Validation - `prettier --check CHANGELOG.md` - `git diff --check` - confirmed the change adds no Markdown links requiring target validation <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved browser authentication with more secure, control-plane managed sessions. * Added signed authentication routing for browser sign-in requests. * **Breaking Changes** * Legacy browser tokens are no longer supported. * Existing users must sign in again after upgrading. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cole Murray <2492022+ColeMurray@users.noreply.github.com>
## Summary - constrain the media lightbox to the dynamic mobile viewport - keep tall screenshots and videos scrollable within the available modal space - add an always-visible accessible close control - cover the close interaction with a regression test ## Root cause The media region could consume `80vh` before accounting for the title, source URL, gaps, and padding. On mobile Safari, browser chrome further reduces the visible dynamic viewport, allowing the centered fixed dialog to extend beyond the screen. ## Verification - `npm run lint -w @open-inspect/web` - `npm run typecheck -w @open-inspect/web` - `npm test -w @open-inspect/web -- src/components/screenshot-media.test.tsx` - full web test run: 796/797 passed; the single timeout passed when rerun independently - visual verification at 390x700 - before artifact: `2fd60db03d6015e885b921a8013e6014` - after artifact: `a47f9ac4737c9857397b5484a6499c55` --- *Created with [Open-Inspect](https://open-inspect-prod.vercel.app/session/de0a4097c37e1465acbb74c39939127a)* <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a clearly visible close button to the media viewer. * Improved media viewer layout, sizing, and scrolling across screen sizes. * Long titles and descriptions are now truncated for a cleaner presentation. * **Bug Fixes** * Improved video preview sizing within the media viewer. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Cole Murray <2492022+ColeMurray@users.noreply.github.com>
This is an automated nightly unsafe-cast remediation sweep. It replaces selected unsafe TypeScript assertions at boundary and opaque-cache reads with parse-don't-assert validation while preserving the existing fail-open/null/false contracts. The changes follow the TypeScript Coding Standards guidance for unsafe casts and parse-don't-assert validation, and the Zod boundary-validation pattern established in PR ColeMurray#807. | Finding | Risk | Cast removed | Fix | | --- | --- | --- | --- | | `packages/slack-bot/src/classifier/repos.ts:109` | HIGH | `(await response.json()) as ControlPlaneReposResponse` for the control-plane repo catalog used by Slack repository selection and cached for routing/classification | Added shared Zod repository catalog schemas and `controlPlaneReposResponseSchema.safeParse`; malformed responses log `invalid_response` and use the existing cache/fallback path | | `packages/slack-bot/src/classifier/repos.ts:165` | MEDIUM | `cached as RepoConfig[]` for the opaque KV `repos:cache` value | Added shared `repoConfigSchema` and validate the cached array before returning it; malformed cache values fall through to the existing fallback path | | `packages/linear-bot/src/utils/linear-client.ts:403` | HIGH | `(await response.json()) as { data?: { commentCreate?: { success: boolean } } }` for the external Linear comment mutation response | Added package-local Zod `linearCommentCreateResponseSchema.safeParse`; malformed responses preserve the existing `{ success: false }` behavior | Verification: | Command | Result | | --- | --- | | `npm run build -w @open-inspect/shared` | Passed | | `npm run build -w @open-inspect/slack-bot` | Passed | | `npm run build -w @open-inspect/linear-bot` | Passed | | `npm run typecheck` | Passed | | `npm run lint` | Passed after temporarily moving unrelated untracked local `.opencode/` helper files out of the repo and restoring them, so ESLint checked the tracked project tree | | `npm run format` | Passed | | `npm test -w @open-inspect/shared` | Passed, 37 files / 493 tests | | `npm test -w @open-inspect/slack-bot` | Passed, 28 files / 340 tests | | `npm test -w @open-inspect/linear-bot` | Passed, 13 files / 188 tests | No dependencies were added. --- *Created with [Open-Inspect](https://open-inspect-prod.vercel.app/session/3ec707511fea1b23341ace676c889963)* --------- Co-authored-by: waclaude <colemurray.cs+ghwaclaude@gmail.com> Co-authored-by: Cole Murray <colemurray.cs@gmail.com>
📝 WalkthroughWalkthroughThe PR adds runtime validation for authentication, session, repository, and external API payloads; refactors WebSocket client-context handling; enables configured GitHub bot self-reviews; and updates web UI behavior, accessibility, and memoization. ChangesAuthentication and request validation
WebSocket client context and presence
Runtime payload validation
GitHub bot self-review handling
Web UI and rendering updates
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
Terraform Validation Results
Pushed by: @NicolasWalter, Action: |
Terraform Plan ResultsStatus: ✅ Success Show Planterraform_data.cloudflare_custom_domain_gate: Refreshing state... [id=fa456fac-6c14-16e4-a484-3338d1a3718d]
terraform_data.access_control_gate: Refreshing state... [id=841ab6bc-98a7-018c-1031-ebad4f8b62bc]
random_password.service_auth_secret_github_bot: Refreshing state... [id=none]
null_resource.slack_bot_build[0]: Refreshing state... [id=7727411747602718703]
local_file.web_app_wrangler_production[0]: Refreshing state... [id=daff6090dd93678e6fd6719293e71437dc6f5d6b]
null_resource.control_plane_build: Refreshing state... [id=2042406076740975108]
null_resource.web_app_cloudflare_build[0]: Refreshing state... [id=1984921645726027654]
null_resource.github_bot_build[0]: Refreshing state... [id=7536682210187789111]
random_password.service_auth_secret_web: Refreshing state... [id=none]
random_password.service_auth_secret_slack_bot: Refreshing state... [id=none]
random_password.service_auth_secret_modal: Refreshing state... [id=none]
null_resource.linear_bot_build[0]: Refreshing state... [id=937584459833419549]
random_password.image_callback_token_pepper: Refreshing state... [id=none]
module.slack_kv[0].cloudflare_workers_kv_namespace.this: Refreshing state... [id=729b357dbb5e4c9d99ec9212cc45766e]
cloudflare_queue.slack_completion_delivery_dlq[0]: Refreshing state... [id=06ce03d2663f4aea937b0c0c1c379c17]
module.github_kv[0].cloudflare_workers_kv_namespace.this: Refreshing state... [id=87dbfaa1d9ce4a37a42e04c57c434a72]
cloudflare_r2_bucket.media: Refreshing state... [id=open-inspect-media-primo]
module.session_index_kv.cloudflare_workers_kv_namespace.this: Refreshing state... [id=7f18644fbed34121bbe3a196f373ea93]
cloudflare_d1_database.main: Refreshing state... [id=dba95b03-ace9-47a8-81e9-6e39d8d694c5]
module.linear_kv[0].cloudflare_workers_kv_namespace.this: Refreshing state... [id=d003f1ad81384910a1f48a0a33f18c09]
data.external.modal_source_hash[0]: Reading...
cloudflare_queue.slack_completion_delivery[0]: Refreshing state... [id=56ef0f3e13bd46a3a39f30c79ec547fa]
random_password.service_auth_secret_linear_bot: Refreshing state... [id=none]
module.modal_app[0].null_resource.modal_secrets[0]: Refreshing state... [id=2786381799123975256]
data.external.modal_source_hash[0]: Read complete after 0s [id=-]
module.modal_app[0].null_resource.modal_deploy: Refreshing state... [id=7095165949869290970]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
-/+ destroy and then create replacement
Terraform planned the following actions, but then encountered a problem:
# local_file.web_app_wrangler_production[0] will be created
+ resource "local_file" "web_app_wrangler_production" {
+ content = (sensitive value)
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "../../..//packages/web/wrangler.production.toml"
+ id = (known after apply)
}
# null_resource.control_plane_build must be replaced
-/+ resource "null_resource" "control_plane_build" {
~ id = "2042406076740975108" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-07-27T06:28:07Z" -> (known after apply)
}
}
# null_resource.github_bot_build[0] must be replaced
-/+ resource "null_resource" "github_bot_build" {
~ id = "7536682210187789111" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-07-27T06:28:07Z" -> (known after apply)
}
}
# null_resource.linear_bot_build[0] must be replaced
-/+ resource "null_resource" "linear_bot_build" {
~ id = "937584459833419549" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-07-27T06:28:07Z" -> (known after apply)
}
}
# null_resource.slack_bot_build[0] must be replaced
-/+ resource "null_resource" "slack_bot_build" {
~ id = "7727411747602718703" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-07-27T06:28:07Z" -> (known after apply)
}
}
# null_resource.web_app_cloudflare_build[0] must be replaced
-/+ resource "null_resource" "web_app_cloudflare_build" {
~ id = "1984921645726027654" -> (known after apply)
~ triggers = { # forces replacement
~ "always_run" = "2026-07-27T06:28:07Z" -> (known after apply)
}
}
Plan: 6 to add, 0 to change, 5 to destroy.
Error: failed to make http request
with cloudflare_d1_database.main,
on d1.tf line 5, in resource "cloudflare_d1_database" "main":
5: resource "cloudflare_d1_database" "main" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/d1/database/dba95b03-ace9-47a8-81e9-6e39d8d694c5":
401 Unauthorized
{"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[]}
Error: failed to make http request
with cloudflare_r2_bucket.media,
on r2.tf line 5, in resource "cloudflare_r2_bucket" "media":
5: resource "cloudflare_r2_bucket" "media" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/r2/buckets/open-inspect-media-primo":
403 Forbidden
{"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[],"result":null}
Error: failed to make http request
with cloudflare_queue.slack_completion_delivery[0],
on workers-slack.tf line 5, in resource "cloudflare_queue" "slack_completion_delivery":
5: resource "cloudflare_queue" "slack_completion_delivery" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/queues/56ef0f3e13bd46a3a39f30c79ec547fa":
403 Forbidden
{"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[],"result":null}
Error: failed to make http request
with cloudflare_queue.slack_completion_delivery_dlq[0],
on workers-slack.tf line 12, in resource "cloudflare_queue" "slack_completion_delivery_dlq":
12: resource "cloudflare_queue" "slack_completion_delivery_dlq" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/queues/06ce03d2663f4aea937b0c0c1c379c17":
403 Forbidden
{"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[],"result":null}
Error: failed to make http request
with module.linear_kv[0].cloudflare_workers_kv_namespace.this,
on ../../modules/cloudflare-kv/main.tf line 4, in resource "cloudflare_workers_kv_namespace" "this":
4: resource "cloudflare_workers_kv_namespace" "this" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/storage/kv/namespaces/d003f1ad81384910a1f48a0a33f18c09":
401 Unauthorized
{"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[]}
Error: failed to make http request
with module.github_kv[0].cloudflare_workers_kv_namespace.this,
on ../../modules/cloudflare-kv/main.tf line 4, in resource "cloudflare_workers_kv_namespace" "this":
4: resource "cloudflare_workers_kv_namespace" "this" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/storage/kv/namespaces/87dbfaa1d9ce4a37a42e04c57c434a72":
401 Unauthorized
{"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[]}
Error: failed to make http request
with module.slack_kv[0].cloudflare_workers_kv_namespace.this,
on ../../modules/cloudflare-kv/main.tf line 4, in resource "cloudflare_workers_kv_namespace" "this":
4: resource "cloudflare_workers_kv_namespace" "this" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/storage/kv/namespaces/729b357dbb5e4c9d99ec9212cc45766e":
401 Unauthorized
{"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[]}
Error: failed to make http request
with module.session_index_kv.cloudflare_workers_kv_namespace.this,
on ../../modules/cloudflare-kv/main.tf line 4, in resource "cloudflare_workers_kv_namespace" "this":
4: resource "cloudflare_workers_kv_namespace" "this" {
GET
"https://api.cloudflare.com/client/v4/accounts/bf66240843ed90d19b82e4b90916d29a/storage/kv/namespaces/7f18644fbed34121bbe3a196f373ea93":
401 Unauthorized
{"result":null,"success":false,"errors":[{"code":10000,"message":"Authentication
error"}],"messages":[]}
::error::Terraform exited with code 1.Pushed by: @NicolasWalter |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/github-bot/src/prompts.ts (1)
48-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMove the parameter default to a named constant.
Use a named default constant for
isSelfReviewrather than an inline parameter default. As per coding guidelines, “Define each default value exactly once in a named constant and import or reuse that constant everywhere.”🤖 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 `@packages/github-bot/src/prompts.ts` around lines 48 - 62, Move the inline default for isSelfReview in the surrounding prompt-building function to a named constant, then reuse that constant when destructuring params. Ensure the default value is defined only once and remains false.Source: Coding guidelines
packages/shared/src/types/session-api.ts (1)
18-26: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winSlack/automation callback fields allow empty strings; Linear's don't.
slackCallbackContextSchema(channel, threadTs, repoFullName, model) andautomationCallbackContextSchema(automationId, runId, automationName) use plainz.string(), whilelinearCallbackContextSchemausesnonEmptyStringSchemafor its identifiers. SincecallbackContextSchemais used to validate the externally-suppliedcallbackContexton prompt requests, an emptychannel/repoFullName/automationIdwould pass validation here and only fail later against the Slack/automation API.🔧 Suggested fix for tightening identifier fields
export const slackCallbackContextSchema = z.object({ source: z.literal("slack"), - channel: z.string(), - threadTs: z.string(), - repoFullName: z.string(), - model: z.string(), + channel: nonEmptyStringSchema, + threadTs: nonEmptyStringSchema, + repoFullName: nonEmptyStringSchema, + model: nonEmptyStringSchema, reasoningEffort: z.string().optional(), reactionMessageTs: z.string().optional(), });Also applies to: 69-74
🤖 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 `@packages/shared/src/types/session-api.ts` around lines 18 - 26, Update slackCallbackContextSchema and automationCallbackContextSchema to use the existing nonEmptyStringSchema for all required identifier fields, including channel, threadTs, repoFullName, model, automationId, runId, and automationName, so externally supplied callback contexts reject empty strings consistently with linearCallbackContextSchema.
🤖 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/github-bot/src/prompts.ts`:
- Around line 63-66: Update the reviewEvent value used by the command example so
it always contains one valid event rather than the literal pipe-separated list.
Preserve the self-review behavior while selecting a single valid placeholder or
concrete event for the non-self-review path, and keep the related
reviewEventGuidance in sync.
---
Nitpick comments:
In `@packages/github-bot/src/prompts.ts`:
- Around line 48-62: Move the inline default for isSelfReview in the surrounding
prompt-building function to a named constant, then reuse that constant when
destructuring params. Ensure the default value is defined only once and remains
false.
In `@packages/shared/src/types/session-api.ts`:
- Around line 18-26: Update slackCallbackContextSchema and
automationCallbackContextSchema to use the existing nonEmptyStringSchema for all
required identifier fields, including channel, threadTs, repoFullName, model,
automationId, runId, and automationName, so externally supplied callback
contexts reject empty strings consistently with linearCallbackContextSchema.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e7dcb3eb-bfde-42a3-97cb-c842e922e3f5
📒 Files selected for processing (33)
CHANGELOG.mdpackages/control-plane/src/auth/user/better-auth.tspackages/control-plane/src/routes/session-prompt.tspackages/control-plane/src/session/durable-object.tspackages/control-plane/src/session/presence-service.test.tspackages/control-plane/src/session/presence-service.tspackages/control-plane/test/integration/browser-auth.test.tspackages/control-plane/test/integration/stop-execution.test.tspackages/control-plane/test/integration/websocket-client.test.tspackages/control-plane/vitest.integration.config.tspackages/github-bot/README.mdpackages/github-bot/src/handlers.tspackages/github-bot/src/prompts.tspackages/github-bot/test/handlers.test.tspackages/github-bot/test/prompts.test.tspackages/linear-bot/src/utils/linear-client.test.tspackages/linear-bot/src/utils/linear-client.tspackages/shared/src/types/boundary-schemas.test.tspackages/shared/src/types/index.tspackages/shared/src/types/repository-catalog.test.tspackages/shared/src/types/repository-catalog.tspackages/shared/src/types/session-api.tspackages/slack-bot/src/classifier/repos.test.tspackages/slack-bot/src/classifier/repos.tspackages/slack-bot/src/index.test.tspackages/web/src/app/api/image-builds/route.tspackages/web/src/components/media-lightbox.tsxpackages/web/src/components/screenshot-media.test.tsxpackages/web/src/components/settings/integrations/github-integration-settings.tsxpackages/web/src/components/settings/integrations/linear-integration-settings.tsxpackages/web/src/components/settings/sandbox-settings.tsxpackages/web/src/components/sidebar-layout.tsxpackages/web/src/components/ui/toggle-group.tsx
| const reviewEvent = isSelfReview ? "COMMENT" : "COMMENT|APPROVE|REQUEST_CHANGES"; | ||
| const reviewEventGuidance = isSelfReview | ||
| ? "Use COMMENT because GitHub does not allow pull request authors to approve their own PRs." | ||
| : "Use APPROVE if the code looks good, REQUEST_CHANGES if changes are needed,\n or COMMENT for general feedback."; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
curl --fail --silent --show-error \
https://docs.github.com/en/rest/pulls/reviews \
| rg -n 'APPROVE|REQUEST_CHANGES|COMMENT'Repository: primo-devs/primo-bg-coding-agent
Length of output: 50389
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant file around the changed lines and nearby prompt assembly.
FILE="packages/github-bot/src/prompts.ts"
wc -l "$FILE"
sed -n '1,220p' "$FILE"
# Find other uses of the reviewEvent / reviewEventGuidance fields.
rg -n "reviewEvent|reviewEventGuidance|COMMENT\|APPROVE\|REQUEST_CHANGES|isSelfReview" packages/github-bot/src -SRepository: primo-devs/primo-bg-coding-agent
Length of output: 7256
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the prompt consumer and surrounding review-submission flow.
sed -n '320,390p' packages/github-bot/src/handlers.ts
sed -n '1,140p' packages/github-bot/src/prompts.tsRepository: primo-devs/primo-bg-coding-agent
Length of output: 6414
Use a single review event in the command example. event only accepts APPROVE, REQUEST_CHANGES, or COMMENT; COMMENT|APPROVE|REQUEST_CHANGES is invalid if copied literally. Replace it with a single placeholder or one concrete event before showing the command.
🤖 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 `@packages/github-bot/src/prompts.ts` around lines 63 - 66, Update the
reviewEvent value used by the command example so it always contains one valid
event rather than the literal pipe-separated list. Preserve the self-review
behavior while selecting a single valid placeholder or concrete event for the
non-self-review path, and keep the related reviewEventGuidance in sync.
Automated upstream sync
Clean merge from
ColeMurray/background-agents@main.This PR was opened automatically by
.github/workflows/sync-upstream.yml. Review the commit list and merge when CI is green.Summary by CodeRabbit
New Features
Bug Fixes
Accessibility