Merged
Conversation
<img width="1156" height="155" alt="Screenshot 2026-03-09 at 12 56 47" src="https://github.com/user-attachments/assets/74add57d-2df6-429c-b620-4114bf2fb60e" /> <img width="1446" height="1638" alt="image" src="https://github.com/user-attachments/assets/e457e9c3-711f-4f4e-98d3-bdbf6ef7ec5c" /> Verified the full flow end-to-end via cURL — sending a signed Webflow webhook payload to a local api-server successfully enqueues the River job and sends a broadcast email via Resend as expected. The feature is gated by config: if `WEBFLOW_WEBHOOK_SECRET` and `RESEND_API_KEY` are not set, the handler and worker simply don't register. This means the code can ship safely now. To go live we need: - Add Webflow + Resend credentials to 1Password ([ENG-3043](https://linear.app/overmind/issue/ENG-3043/add-webflow-webhook-credentials-to-1password-global-vault), [ENG-3044](https://linear.app/overmind/issue/ENG-3043/add-webflow-webhook-credentials-to-1password-global-vault)) - Configure the Webflow webhook URL to point at the production api-server - Import verified user emails into the Resend [segment](https://resend.com/audience?segmentId=e562dcde-600f-4535-bdfc-5e72c5a16c3d) ([ENG-2957](https://linear.app/overmind/issue/ENG-2957/manual-csv-sync-of-verified-user-emails-to-resend)) - Automate adding new users to changelog notify [segment in resend](https://resend.com/audience?segmentId=e562dcde-600f-4535-bdfc-5e72c5a16c3d) [ENG-2958](https://linear.app/overmind/issue/ENG-2958/add-resend-contact-creation-to-user-signup-flow) - Once those are done, changelog publishes in Webflow will automatically trigger broadcast emails. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces a new externally reachable webhook endpoint and outbound email-sending worker; while gated by config and protected with HMAC + timestamp checks, mistakes could lead to unwanted job enqueues or email broadcasts. > > **Overview** > Adds a Webflow webhook integration that, when enabled via config, verifies `X-Webflow-Signature` (HMAC-SHA256) and timestamp tolerance, filters events by CMS collection ID, and enqueues a River `ChangelogEmail` job. > > Adds a River worker that renders a new embedded HTML template and uses the `resend-go` client to send a broadcast email to a configured Resend segment; wiring includes new CLI/env config fields with secret redaction and new ExternalSecret entries for Webflow/Resend credentials. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b1ac7f7b0e9605a99f8828d52942cd127515a8f2. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 782a27f26097b36ae2b053b9949ef49a962df666
…(#4193) Pin all runtime Alpine base images from 3.23 to 3.23.3 (ships zlib 1.3.2-r0) and add apk upgrade --no-cache to builder stages using golang:1.26-alpine, node:24-alpine, and nats:alpine where the base Alpine version cannot be pinned directly. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to Docker base image patch pinning and package upgrades, but they can affect container build reproducibility and potentially introduce subtle runtime/library differences. > > **Overview** > Pins all Alpine runtime stages from `alpine:3.23` to `alpine:3.23.3` across Go-based services/sources (and multi-stage images like `api-server`, `gateway`, `revlink`, `srcman`, etc.). > > Adds `apk upgrade --no-cache` to builder/base stages that inherit Alpine indirectly (`golang:1.26-alpine`, `node:24-alpine`, and `nats:alpine`) before installing required packages, ensuring patched system libraries (e.g., zlib) are picked up during image builds. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a8089e8113c4afcbc923f40d9de442f4227fac31. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 77fdaa992e127a8accaaa2328be36977e9c616fe
…(#4145) 📹 https://www.loom.com/share/4049912c73734143a8dde39ebf3f4fe6 📹 This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [github.com/auth0/go-jwt-middleware/v2](https://redirect.github.com/auth0/go-jwt-middleware) | `v2.3.1` → `v3.0.0` |  |  | --- > [!WARNING] > Some dependencies could not be looked up. Check the [Dependency Dashboard](../issues/370) for more information. --- ### Release Notes <details> <summary>auth0/go-jwt-middleware (github.com/auth0/go-jwt-middleware/v2)</summary> ### [`v3.0.0`](https://redirect.github.com/auth0/go-jwt-middleware/blob/HEAD/CHANGELOG.md#v300-2026-01-19) [Compare Source](https://redirect.github.com/auth0/go-jwt-middleware/compare/v2.3.1...v3.0.0) [Full Changelog](https://redirect.github.com/auth0/go-jwt-middleware/compare/v2.3.1...v3.0.0) **BEFORE YOU UPGRADE** - This is a major release that includes breaking changes. Please see [MIGRATION\_GUIDE.md](MIGRATION_GUIDE.md) before upgrading. This release will require changes to your application. ##### Added - Pure options pattern for validator, middleware, and JWKS provider ([#​357](https://redirect.github.com/auth0/go-jwt-middleware/pull/357), [#​358](https://redirect.github.com/auth0/go-jwt-middleware/pull/358), [#​360](https://redirect.github.com/auth0/go-jwt-middleware/pull/360)) - DPoP (Demonstrating Proof-of-Possession) support per RFC 9449 ([#​363](https://redirect.github.com/auth0/go-jwt-middleware/pull/363)) - Framework-agnostic core package for reusable validation logic ([#​356](https://redirect.github.com/auth0/go-jwt-middleware/pull/356)) - Type-safe claims retrieval with generics (`GetClaims[T]()`, `MustGetClaims[T]()`, `HasClaims()`) - Structured logging support compatible with `log/slog` - Support for 14 signature algorithms (HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512, ES256K, EdDSA) - Enhanced error responses with RFC 6750 compliance - Trusted proxy configuration for DPoP behind reverse proxies - Multiple issuer and audience support with new APIs - Documentation and linting configuration ([#​361](https://redirect.github.com/auth0/go-jwt-middleware/pull/361)) ##### Changed - Migrated from square/go-jose to lestrrat-go/jwx v3 ([#​358](https://redirect.github.com/auth0/go-jwt-middleware/pull/358)) - Module path updated to `github.com/auth0/go-jwt-middleware/v3` ([#​355](https://redirect.github.com/auth0/go-jwt-middleware/pull/355)) - Minimum Go version updated to 1.24 ([#​355](https://redirect.github.com/auth0/go-jwt-middleware/pull/355)) - Update examples for v3 module path and new APIs ##### Breaking - Pure options pattern: All constructors (`New()`) now require functional options instead of positional parameters - Context key: `ContextKey{}` is no longer exported - use `GetClaims[T]()` helper function - Custom claims now use generics for type safety - `TokenExtractor` returns `ExtractedToken` (with scheme) instead of `string` - Type naming: `ExclusionUrlHandler` renamed to `ExclusionURLHandler` ##### Migration Example **v2:** ```go // Validator with positional parameters jwtValidator, err := validator.New( keyFunc, validator.RS256, "https://issuer.example.com/", []string{"my-api"}, ) // Middleware middleware := jwtmiddleware.New(jwtValidator.ValidateToken) // Claims access via context key claims := r.Context().Value(jwtmiddleware.ContextKey{}).(*validator.ValidatedClaims) ``` **v3:** ```go // Validator with pure options jwtValidator, err := validator.New( validator.WithKeyFunc(keyFunc), validator.WithAlgorithm(validator.RS256), validator.WithIssuer("https://issuer.example.com/"), validator.WithAudience("my-api"), ) // Middleware with options middleware, err := jwtmiddleware.New( jwtmiddleware.WithValidator(jwtValidator), ) // Type-safe claims with generics claims, err := jwtmiddleware.GetClaims[*validator.ValidatedClaims](r.Context()) ``` See [MIGRATION\_GUIDE.md](MIGRATION_GUIDE.md) for complete migration instructions. *** </details> --- ### Configuration 📅 **Schedule**: Branch creation - "before 10am on friday" in timezone Europe/London, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/overmindtech/workspace). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41NS40IiwidXBkYXRlZEluVmVyIjoiNDMuNTYuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwiZ29sYW5nIl19--> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Upgrades a major authentication dependency and rewrites JWT validation/claim extraction paths, so mistakes could break auth enforcement or token parsing across the API server. > > **Overview** > Migrates the codebase from `github.com/auth0/go-jwt-middleware/v2` to `v3`, updating JWKS provider/validator/middleware construction to the new options-based APIs and adjusting token extraction/claims retrieval. > > Because `v3` no longer exposes `ContextKey{}`, the auth middleware now stores `*validator.ValidatedClaims` under a new `auth.ValidatedClaimsContextKey{}` and updates downstream callers (e.g. token expiry in `ManagementServiceHandler.CreateToken`) accordingly. The API server init path now skips validator setup when `AllowUnauthenticated` is enabled and tightens startup validation/error logging for missing Auth0 config; related tests set `AllowUnauthenticated: true` to accommodate `v3` rejecting empty audience/domain values. > > Also updates `go.mod`/`go.sum` for new transitive deps pulled in by `v3` (e.g. `lestrrat-go/jwx/v3`) and adds `github.com/resend/resend-go/v3` to the main require block. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e8a54151abc72beb9973302047684ad983aa5b8e. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: f8185846b5c05bebfd88c56b76c4d1bb95a592db
<!-- CURSOR_SUMMARY --> > [!NOTE] > **Medium Risk** > Primarily dependency hygiene, but it changes `go.mod` direct/indirect requirements (and adds a few direct deps), which can affect module resolution and builds. > > **Overview** > Adds a new Bugbot rule requiring `go.mod` to contain exactly two `require` blocks, with **all direct deps** in the first and **all `// indirect` deps** in the second. > > Updates `go.mod` accordingly by moving several modules between direct/indirect blocks and adding a few direct requirements (notably `cloud.google.com/go/auth/oauth2adapt`, `github.com/lithammer/fuzzysearch`, and `sigs.k8s.io/structured-merge-diff/v6`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f14e91b436c6b898c84f4570d0057733c5d8a304. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 3b467a861bd85514ce230e67ab433ffb49d4d600
<img width="2104" height="195" alt="image" src="https://github.com/user-attachments/assets/6fa988f4-669c-41b7-a80e-97a936042b05" /> <!-- CURSOR_AGENT_PR_BODY_BEGIN --> Upgrade `github.com/google/go-github` from v80 to v84 and `go-querystring` to resolve `ENG-3024`. The upgrade involved updating import paths and `go.mod`/`go.sum`. Although the upstream library had breaking changes between v80 and v84, our specific usage of the GitHub client library was not affected, and all existing tests pass. --- Linear Issue: [ENG-3024](https://linear.app/overmind/issue/ENG-3024/upgrade-github-libraries) <p><a href="https://cursor.com/agents/bc-a6d4c68b-e6b4-4705-8bad-124e129784ce"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-a6d4c68b-e6b4-4705-8bad-124e129784ce"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </p> <!-- CURSOR_AGENT_PR_BODY_END --> GitOrigin-RevId: e4fb546b7842a3fbf86f17a6fbf8a653f1a867b7
<img width="2934" height="1992" alt="image" src="https://github.com/user-attachments/assets/b29c553f-4169-478a-8f1a-04f4b5caf8b1" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces a new Azure resource adapter and changes GET query parsing for Azure to accept full resource IDs, which could affect query behavior for Azure adapters if path-key mappings are missing or incorrect. > > **Overview** > Adds a new Azure adapter for Elastic SAN volume snapshots, including an Azure SDK client wrapper, lookups/linking to parent Elastic SAN/volume group (and source volume when available), Terraform mappings, and unit tests/mocks. > > Extends the core `standardAdapterCore.Get` path parsing to accept full Azure resource IDs (e.g. from Terraform mappings) by extracting query parts based on per-type path key definitions, returning explicit query errors when unsupported. > > Also updates dependencies (`armelasticsan`), registers the new adapter in `azure/manual/adapters.go`, adds ElasticSAN item types/resources + resourceID path-key mapping, tightens k8s `Endpoints` staticcheck suppressions, and makes multiple tests safer by returning after `t.Fatal`/`t.Fatalf` to avoid nil dereferences. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c7e10ad43d6ec2031feae80015364980a25527af. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 97899d2e8b23eae053e5a6612affd3df5d872e73
<img width="1474" height="1002" alt="image" src="https://github.com/user-attachments/assets/8b62255e-97f6-4f78-94d7-2a62b1553c48" /> <!-- CURSOR_SUMMARY --> > [!NOTE] > **Medium Risk** > Adds a new Azure discovery adapter and client wiring that will increase API calls and linked-query generation for NSG scans. Risk is moderate because it touches adapter initialization/registration and paging logic, but is isolated to a new resource type. > > **Overview** > Adds support for discovering Azure NSG *default* security rules by introducing a new `NetworkDefaultSecurityRule` searchable adapter, including `Get`, `Search`, and streaming search, and wiring it into the Azure manual adapter registry. > > Introduces a thin `DefaultSecurityRulesClient` wrapper (with generated GoMock) and updates resource-ID path extraction to understand `azure-network-default-security-rule`; includes a dedicated unit test suite covering paging, validation, and error cases. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 83470e2e2e56c5effbd6bbf5b777f1b1fc789bb9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 3fb0c7bdbef4b58a368deeffa2e726c9a2aaa793
…4217) <img width="1476" height="1005" alt="image" src="https://github.com/user-attachments/assets/1ae1b591-ae66-469a-afed-65435d760819" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Adds a new read-only adapter and resource-ID parsing entry without changing existing adapter behavior; risk is mainly incorrect query-part parsing or linking causing missing/extra discovered items. > > **Overview** > Adds support for discovering Azure **Disk Access private endpoint connections** as a first-class item type. > > Introduces a new compute client interface + generated mock, a `SearchableWrapper` adapter that supports `Get` (by `diskAccessName` + connection name) and `Search/SearchStream` (list connections for a disk access), maps provisioning state to item health, and emits links to the parent `ComputeDiskAccess` and referenced `NetworkPrivateEndpoint`. > > Wires the new adapter into Azure `Adapters()` (including metadata-only mode) and updates `shared.GetResourceIDPathKeys` to parse this resource type from Azure resource IDs; adds unit tests covering happy paths, paging, nil-name filtering, and error handling. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fca452d9c38741050cb8789b70e89e5c94021b20. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: b5fa1330f689e5ff42d8a2a49e2621cad8986e62
## Summary - Skip `fdatasync` on every bbolt commit in the sdpcache layer by setting `NoSync: true` and `NoFreelistSync: true` - Eliminates the single-writer bottleneck that cascaded into 36K stuck goroutines under load (bbolt serializes write transactions behind fdatasync, ~930 pool workers were queuing on the write lock) - Safe because sdpcache is a pure cache -- crash durability provides no value ## Linear Ticket - **Ticket**: [ENG-3089](https://linear.app/overmind/issue/ENG-3089/relax-bbolt-cache-durability-to-fix-goroutine-pileup-under-load) — Relax bbolt cache durability to fix goroutine pileup under load - **Purpose**: Remove the fdatasync bottleneck that causes cascading goroutine pileups when sources are under heavy query load - **Priority**: Urgent ## Changes Single file change in `go/sdpcache/bolt_cache.go`: 1. Added a package-level `cacheOpenOptions` variable with `NoSync: true`, `NoFreelistSync: true`, and the existing `Timeout: 5s` 2. Replaced all 7 inline `&bbolt.Options{Timeout: 5 * time.Second}` with `cacheOpenOptions` All sdpcache tests pass. No API or behavioral change -- only the fsync guarantee is relaxed, which is irrelevant for a cache. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Disables bbolt fsync and freelist syncing for the cache DB, which can improve throughput but increases the chance of cache corruption/loss after crashes or power failures. > > **Overview** > Introduces a shared `cacheOpenOptions` for all `bbolt.Open` calls in `sdpcache` that sets `NoSync` and `NoFreelistSync` (keeping the existing 5s `Timeout`) to avoid per-commit `fdatasync` overhead. > > All cache DB open/reopen paths (startup, deletion recovery, and compaction temp DB creation/reopen) are updated to use these relaxed durability settings. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 60297db5a8b4e78b25a685c30ad8242f84ed17b1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 4de3a30393489e86e14f68b16c8bbd81b8f1f3da
<img width="1475" height="1005" alt="image" src="https://github.com/user-attachments/assets/bd0e6458-cbd6-4439-8e0d-0be453374457" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new Azure discovery adapter and wires it into adapter initialization, introducing new Azure SDK calls and item-linking logic that could affect discovery completeness/performance but not security-critical flows. > > **Overview** > Adds first-class discovery support for Azure Elastic SAN pools. > > Introduces a new `ElasticSanClient` wrapper around the Azure SDK plus a `NewElasticSan` manual adapter that supports `List`, `ListStream`, and `Get`, maps resources into SDP items (tags/health), and emits links to related `ElasticSanVolumeGroup` (SEARCH) and `NetworkPrivateEndpoint` (GET) resources. Wires the adapter into `manual/adapters.go` by initializing `armelasticsan.NewElasticSansClient` and registering the adapter (including the metadata-only nil-client path), and adds unit tests + generated GoMock for the new client. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f25b3ccbcbd2327205c52c84d28c5416570fdfa5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 9e98c7c8a21cbaaa192c5a6842fa8d1a1016ab68
## Implementation Notes — Deviations from Plan Parts 1, 2b, and 3 were implemented exactly as specified. Part 2a (CLI `terraform_plan.go`) has the following deviations, all driven by UX feedback during implementation: ### CLI Output Formatting Changes * **Change-level link:** Instead of a raw URL, now renders as a clickable OSC 8 hyperlink with text "Open in Overmind ↗" (matching the GitHub PR comment's "Open in Overmind ↗" wording) * **Preamble text:** Changed from "Check the blast radius graph and risks at:" to "View the blast radius graph and risks:" * **Link indentation:** Removed — both per-risk and change-level links have no indentation * **Inter-risk spacing:** Added extra blank line between risk blocks for readability * **Description-to-link spacing:** "View risk ↗" immediately follows the description (no blank line) ### Terminal Compatibility (not in original plan) Added `supportsHyperlinks()` detection to gracefully handle terminals that don't support OSC 8: * **TTY check:** Skips hyperlinks when stdout is not a terminal (piped output, file redirect) * **CI check:** Skips hyperlinks when `$CI` is set * **Env heuristics:** Checks `$TERM_PROGRAM`, `$VTE_VERSION`, `$TERM` (kitty, 256color), and `$TMUX` to detect modern terminals * **Fallback:** Renders raw URLs instead of hyperlinks in unsupported environments * `renderLink()` helper: Wraps the detection logic — returns OSC 8 hyperlink or raw URL ### Additional Tests (plan said no test changes needed) * `TestBuildChangeMarkdownUTMAttribution` — asserts `utm_source=github-comment` on change, signals, and risk URLs in generated PR markdown * `TestEnvSupportsHyperlinks` — 9 test cases covering CI, dumb terminal, screen, tmux, TERM_PROGRAM, VTE_VERSION, kitty, 256color, and no-signal scenarios * `TestRenderLinkFallback` — verifies raw URL fallback when stdout is not a TTY * `TestRenderRiskPreview` — visual inspection test using real lipgloss styles, ommited from CI test runs * `TestTerminalHyperlink` — verifies OSC 8 escape sequence format ### Files Changed * `services/api-server/service/changesservice.go` — UTM on 4 URLs (as planned) * `services/api-server/service/changesservice_test.go` — new UTM assertion test * `services/api-server/service/runtask.go` — UTM on 5 URLs (as planned) * `cli/cmd/terraform_plan.go` — per-risk hyperlinks, terminal detection, UTM params * `cli/cmd/terraform_plan_test.go` — new test file with hyperlink, detection, and visual preview tests * `cli/cmd/changes_submit_plan.go` — UTM on change URL (as planned) <!-- CURSOR_SUMMARY --> > [!NOTE] > **Low Risk** > Low risk: changes are limited to URL formatting/output (UTM query params + clickable terminal links) and add tests; minimal impact beyond link rendering and attribution tracking. > > **Overview** > Adds UTM attribution parameters to Overmind links emitted by the CLI, GitHub comment markdown, and HCP Terraform task outcomes (including per-risk deep links), and includes the CLI version on `utm_source=cli` links. > > Improves `terraform plan` CLI output by rendering OSC 8 clickable hyperlinks when running in a compatible TTY, with environment-based detection and new unit/preview tests to validate link rendering and UTM presence. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 126f33b4e7412264727c493c2541b4246caf9b4a. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: d9143a2ac795069df3872be9b1c7b232644f58f0
<img width="1464" height="1025" alt="image" src="https://github.com/user-attachments/assets/d9da04f8-c988-4ac2-b7bc-010af152bb34" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Mostly additive discovery logic, but it changes adapter initialization and resource-ID parsing; `shared/utils.go` modifications appear to have missing map-entry commas which could break builds and should be verified. > > **Overview** > Adds new Azure discovery adapters for **Elastic SAN** and **Elastic SAN Volume Groups**, including SDK client wrappers/interfaces, adapter registration in `manual/adapters.go`, and comprehensive unit tests plus generated GoMock clients. > > The new Volume Group adapter supports `Get`/`Search`/streaming and emits rich linked-item queries (Elastic SAN parent, volumes/snapshots children, private endpoints, subnets, Key Vault, UAI, DNS) and health mapping from provisioning state; `shared/utils.go` is extended to parse volume-group resource IDs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4b82060b80817f7cfe6ae129887851de76b61afd. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: 13b4a371e9a7b1a4a5cb574dc420a5b2d2040d46
## Summary - Relax `mapped_item_diffs` PK from `change_external_id` to `id` so multiple rows can be stored per change, enabling accumulation of partial Terraform plans from parallel CI workflows (e.g. Atlantis) - Add `AddPlannedChanges` RPC that appends planned change items to an existing change without triggering analysis - Modify `StartChangeAnalysis` to load and combine pre-stored items with any items provided in the request ## Linear Ticket - **Ticket**: [ENG-3098](https://linear.app/overmind/issue/ENG-3098/phase-1-backend-accumulate-partial-plans) -- Phase 1: Backend -- Accumulate Partial Plans - **Project**: [Multi-Plan Submission & GitHub App PR Commenting](https://linear.app/overmind/project/multi-plan-submission-and-github-app-pr-commenting-7b3d32c2ff24) - **Purpose**: Enable CI systems that produce multiple Terraform plans in parallel to submit each plan independently and trigger a single unified analysis - **Approver**: TP Honey ## Changes ### Schema & Queries - **Migration** (`20260311113037_relax_mapped_item_diffs_pk.sql`): Drops PK on `change_external_id`, adds PK on `id`, adds btree index on `change_external_id` - **SQLC queries**: `GetMappedItemDiff` and `GetMappedItemDiffsForAllModifications` changed from `:one` to `:many`; new `SetPlannedChangesStored` query added - All callers updated with `flattenMappedItemDiffs` helper across `changesservice.go`, `changetimeline.go`, `labelservice.go`, `signalservice.go`, `crm_sync.go`, and `area51/` ### Proto - New `AddPlannedChanges` RPC + `AddPlannedChangesRequest`/`AddPlannedChangesResponse` messages in `ChangesService` ### Handlers - `AddPlannedChanges`: validates auth, checks change is in `DEFINING` status, appends items via `InsertMappedItemDiff`, sets `planned_changes_stored` flag - `StartChangeAnalysis`: always loads stored items and combines with any provided items (supports single-plan, multi-plan, and hybrid flows) ### Tests - `TestAddPlannedChanges`: 6 subtests covering append, accumulate, flag verification, empty rejection, non-existent change - `TestAddPlannedChangesConcurrent`: 10 goroutines inserting in parallel, verifying no data loss - `TestWriteMappedItemDiffs`: updated to verify multi-row insert succeeds (was testing PK conflict) - All existing test callers updated for `:many` return type ## Deviations from Approved Plan ### 1. `StartChangeAnalysis` combines stored + provided items (not either/or) **Plan**: When `changingItems` is empty, load from DB. When provided, use them directly. **Implementation**: Always loads stored items and appends to provided items, supporting a hybrid flow. **Why**: Review feedback from @DavidS-ovm -- the endpoint should work when items are both stored AND provided, combining both rather than picking one. ### 2. No error on empty `changingItems` with no stored items **Plan**: Return `CodeFailedPrecondition` when both provided and stored items are empty. **Implementation**: Allow empty items through (analysis runs with empty set as before). **Why**: The existing `TestStartChangeAnalysis/UpdatePlannedChanges_with_no_changes` test calls `StartChangeAnalysis` with empty items and expects success (no-op when River is unconfigured). Adding an error here broke backward compatibility. ### 3. Additional callers updated beyond plan **Plan**: Listed 4 callers to update (`changesservice.go` x3, `changetimeline.go` x1). **Implementation**: Also updated callers in `labelservice.go` (x2), `signalservice.go` (x1), `crm_sync.go` (x1), `area51/changes.go` (x3), `area51/llm.go` (x3) -- 10 additional call sites. **Why**: The plan identified callers by grep but missed callers in other packages. All callers of `GetMappedItemDiff` must be updated for the `:one` to `:many` change. ### 4. `ErrNoRows` guards removed (not replaced) **Plan**: Did not explicitly address `pgx.ErrNoRows` handling. **Implementation**: Removed `ErrNoRows` guards at all `GetMappedItemDiff` call sites. **Why**: With `:many` queries, pgx returns an empty slice and `nil` error instead of `ErrNoRows` ([pgx#2251](jackc/pgx#2251)). The guards were dead code. ### 5. `flattenMappedItemDiffs` duplicated in `area51` package **Plan**: Single helper in `changesservice.go`. **Implementation**: Added a second copy in `area51/changes.go` because `area51` is a separate package and cannot import from `service`. **Why**: Go package boundaries -- the `area51` package has its own callers of `GetMappedItemDiff`. ### 6. `schema.sql` manually edited (not generated by PG16) **Plan**: Generate via `make_migration.sh` + `reset_database.sh`. **Implementation**: Generated locally with PG18 (only version available in cloud agent), then manually corrected to match PG16 `pg_dump` format. **Why**: Cloud agent environment lacks Docker Compose services (PG16 runs as a sidecar in devcontainer). Installed PG18 from Debian packages as a workaround. The schema.sql was corrected to match CI's PG16 output by reverting to the parent commit's file and applying only the PK + index changes. ### 7. No changes to `CalculateMappedResources` logic **Plan**: Update comments in `CalculateMappedResources` to reflect new semantics. **Implementation**: Done as planned -- comment updated from "avoid primary key conflicts" to "replace pre-stored partial plans with resolved results". No functional changes. <!-- CURSOR_AGENT_PR_BODY_BEGIN --> Enable accumulation of partial change plans by modifying the `mapped_item_diffs` schema, adding an RPC to store items, and updating `StartChangeAnalysis` to load them. <div><a href="https://cursor.com/agents/bc-18981e8f-e02d-44e6-a56c-45f12c629a3e"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-18981e8f-e02d-44e6-a56c-45f12c629a3e"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> <!-- CURSOR_AGENT_PR_BODY_END --> --------- GitOrigin-RevId: 19d327de5a8ada8cef3a4d7629821c2fc6a9fe27
…command (#4229) ## Summary - Add `--no-start` flag to `submit-plan` so it stores planned changes via `AddPlannedChanges` without triggering analysis, enabling multi-plan workflows (e.g., Atlantis parallel planning) - Add new `start-analysis` subcommand that triggers analysis on a change with previously accumulated planned items, with optional `--wait` to block until completion - Extract shared analysis flags (`addAnalysisFlags`), config builder (`buildAnalysisConfig`), and analysis polling (`waitForChangeAnalysis`) into reusable helpers ## Linear Ticket - **Ticket**: [ENG-3104](https://linear.app/overmind/issue/ENG-3104/phase-2-cli-submit-plan-no-start-start-analysis) -- Phase 2: CLI -- submit-plan --no-start + start-analysis - **Purpose**: Enable CI systems that produce multiple Terraform plans in parallel to submit each plan independently and then trigger a single unified analysis - **Project**: Multi-Plan Submission & GitHub App PR Commenting ## Changes **Core feature** (reviewers should focus here): - `cli/cmd/changes_submit_plan.go` -- branches on `--no-start`: calls `AddPlannedChanges` RPC when set, `StartChangeAnalysis` when not. Refactored to use shared `buildAnalysisConfig`. - `cli/cmd/changes_start_analysis.go` -- new command: resolves change via `--ticket-link`/`--uuid`/`--change`, builds analysis config, calls `StartChangeAnalysis` with empty `changingItems` (backend loads pre-stored items). Supports `--wait`. - `cli/cmd/flags.go` -- new `addAnalysisFlags()`, `AnalysisConfig` struct, `buildAnalysisConfig()`, and `waitForChangeAnalysis()` shared helper. **Refactoring:** - `cli/cmd/changes_get_change.go`, `cli/cmd/changes_get_signals.go`, `cli/cmd/changes_start_change.go` -- replaced inline analysis-polling loops with shared `waitForChangeAnalysis()`. **Tests:** - `cli/cmd/changes_start_analysis_test.go` -- tests for `addAnalysisFlags` registration, `buildAnalysisConfig` with various flag combinations, `startAnalysisCmd` flag presence, and `submitPlanCmd` `--no-start` flag registration. **Unrelated:** - `.cursor/commands/create-project-plan.md` -- adds a model gate requiring MAX mode (separate from Phase 2 work). ## Deviations from Approved Plan - **`waitForChangeAnalysis` shared helper (addition)**: The plan did not mention extracting the analysis polling loop. The implementation extracted the duplicated poll-until-done loop from `get-change`, `get-signals`, and `start-change` into a shared `waitForChangeAnalysis()` in `flags.go`. This reduces ~120 lines of duplication across 3 files and is needed by `start-analysis --wait`. - **UTM tracking on change URLs**: `submit-plan` and `start-analysis` append `?utm_source=cli&cli_version=<version>` to their change URL output. This follows the established pattern from ENG-3047 Phase 1 (UTM Attribution on External Links) and was applied to the new code paths rather than leaving them inconsistent with the rest of the CLI. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: David Schmitt <DavidS-ovm@users.noreply.github.com> GitOrigin-RevId: 1165783ff4d163d05efd654abe5cd6245657fe53
Introduce WithResourceMetadata middleware that sets a WWW-Authenticate header with a resource_metadata URL on 401 responses, enabling MCP clients (e.g. Cursor) to discover the authorization server automatically. Serve PRM at both path-based and root well-known URIs per RFC 9728. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches authentication-adjacent HTTP middleware and changes routing/headers for `401` responses, which could affect client auth flows and caching/proxies if misconfigured. Scope is limited to MCP endpoints and well-known PRM routes with added tests. > > **Overview** > Enables MCP OAuth discovery per RFC 9728 by adding `auth.WithResourceMetadata`, which injects `WWW-Authenticate: Bearer resource_metadata="…"` on `401 Unauthorized` responses. > > Wires this into the api-server’s `/area51/mcp` route (when `MCPResourceMetadataURL` is configured) and serves Protected Resource Metadata from both `/.well-known/oauth-protected-resource/area51/mcp` (path-based) and the root `/.well-known/oauth-protected-resource` endpoint; adds unit tests covering the new header behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2f65fb73d3efae8da6f553ff42614f481f2ca406. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: c8cc2f110b6f9e83a8663ffd4ee93ddc74ce63a0
## Summary - Implements Phase 3 of the Multi-Plan Submission + GitHub App PR Commenting project: the backend posts change analysis results as a comment on the linked GitHub PR using the installed GitHub App - Uses a static hidden HTML marker (`<!-- overmind-change-summary -->`) for idempotent upserts — re-runs update the same comment instead of duplicating - All PR comment failures are non-fatal — logged and traced but never fail the analysis job ## Linear Ticket - **Ticket**: [ENG-3113](https://linear.app/overmind/issue/ENG-3113) — Phase 3: Backend — GitHub App PR Commenting - **Purpose**: Enable the backend to post analysis results directly to GitHub PRs, so CI/CLI can detect `github_app_active` and skip its own commenting - **Depends on**: Phase 1 (ENG-3098, merged) and Phase 2 (ENG-3104, PR #4229 rebased onto this branch) ## Changes ### Proto (`sdp/changes.proto`) - `StartChangeAnalysisRequest`: added `post_github_comment` (field 8) - `StartChangeAnalysisResponse`: added `github_app_active` (field 1) - `GetChangeSummaryResponse`: added `github_app_comment_posted` (field 2) ### Schema + SQLC - Migration adding nullable `github_comment_id bigint` to `changes` table - New `SetGithubCommentID` query ### GitHub App PR Commenting (`githubapp/githubapp.go`) - `ParseGitHubPRURL` — extracts owner/repo/number from PR URLs - `PostOrUpdatePRComment` — posts or updates a comment using static hidden HTML marker for dedup; handles 403 gracefully (returns 0, nil) - `CheckInstallationCanComment` — verifies `pull_requests:write` permission on the installation - `findExistingComment` documented with marker-vs-DB tradeoff rationale ### Shared Markdown & Signal Aggregation (`service/change_summary.go`) - `BuildChangeSummaryMarkdown` — gathers data from DB and renders the same markdown template used by `get-change --format markdown`. Takes `*config.LLMConfig` and performs LLM-based signal aggregation internally. - `AggregateChangeOverviewSignals` — shared signal aggregation function extracted from `signalservice.go`, called by both `GetChangeOverviewSignals` RPC and `BuildChangeSummaryMarkdown`. Ensures PR comments show identical signal values to the dashboard/CLI. - `computeBlastRadiusContext` — extracted from `GetChangeSummary` to remove duplication ### Signal Service Refactor (`service/signalservice.go`) - `GetChangeOverviewSignals` RPC handler now delegates to shared `AggregateChangeOverviewSignals`, keeping only auth checks and RPC wrapping (~90 lines of business logic removed) ### Worker Wiring (`changeanalysis/change_analysis.go`) - `PostGithubComment bool` added to `ChangeAnalysisCalculationArgs` - `FrontendDNS` and `BuildMarkdownFunc` callback added to worker struct (callback avoids circular import) - `postAnalysisGithubPRComment` runs after `STATUS_DONE` — non-fatal, logged + Sentry, with `cenkalti/backoff/v5` retries - `ovm.auth.accountName` set on the comment span for worker-context observability - OTEL attributes use `ovm.github.pr_comment.skipped_reason` for all early-exit paths ### RPC Wiring (`changesservice.go`) - `checkGithubAppCanComment` helper checks installation permissions - `StartChangeAnalysis` returns `github_app_active` and passes flag to worker args - `GetChangeSummary` returns `github_app_comment_posted` from `change.GithubCommentID.Valid` ### LLM: Fix web search `outputToParam` crash - **Root cause**: `outputToParam` crashed with `"no action present"` when OpenAI returned a `web_search_call` whose action type was unrecognized by the SDK's `AsAny()` (returns `nil` for types other than `search`, `open_page`, `find_in_page`). This happened non-deterministically, causing test flakes in `TestWebSearchTool`. - **Fix**: The `default` case now sets `skipped = true` instead of returning a fatal error, since web search items are purely informational and already ignored in the main processing loop. The caller emits a structured `Warn` log with `callId`, `status`, `actionType`, `actionRawJSON`, and `model` for Honeycomb analysis. The span event also now includes `actionTypeRaw` and `actionRawJSON`. - **Secondary fix**: The `search` action case was silently dropping `Queries` and `Sources` fields during the output-to-param conversion — these are now preserved. ### Tests - `githubapp_test.go`: URL parsing (9 cases), comment create/update/403, permissions check (httptest mocks), pinned marker format test to prevent silent duplicate-comment regressions - `changesservice_test.go`: `checkGithubAppCanComment`, `SetGithubCommentID` DB roundtrip - `change_summary_test.go`: `BuildChangeSummaryMarkdown`, `AggregateChangeOverviewSignals` (single-signal-per-category pass-through), `computeBlastRadiusContext` ## Deviations from Approved Plan - **BuildMarkdownFunc callback instead of direct import**: The plan suggested the worker call `BuildChangeSummaryMarkdown` directly. Due to a circular import (`changeanalysis` cannot import `service`), a `BuildMarkdownFunc` callback field was added to the worker struct, set at init time in `main.go`. Same behavior, different wiring. - **Retry with `cenkalti/backoff/v5`**: The plan did not specify retry logic for `PostOrUpdatePRComment`. Exponential backoff retries (3 attempts) were added in `postAnalysisGithubPRComment` to handle transient GitHub API failures, since the library was already available in the project. - **All PR comment code consolidated in `githubapp.go`**: The plan suggested a separate `pr_comment.go` file (and `changeanalysis/github_comment.go`). All PR comment functions (`ParseGitHubPRURL`, `PostOrUpdatePRComment`, `CheckInstallationCanComment`, `findExistingComment`) and their tests were consolidated into the existing `githubapp.go` / `githubapp_test.go` to combat file sprawl and keep all GitHub App logic grouped together. `postAnalysisGithubPRComment` remains in `change_analysis.go` alongside the existing worker methods. - **No `postAnalysisGithubPRComment` unit tests in `change_analysis_test.go`**: The plan called for direct tests of this method. Testing it requires mocking the full River worker context, GitHub API, and DB. The function is non-fatal by design and its components (`PostOrUpdatePRComment`, `BuildChangeSummaryMarkdown`, `AggregateChangeOverviewSignals`) are tested individually. --------- Co-authored-by: David Schmitt <david.schmitt@overmind.tech> GitOrigin-RevId: ed78774f122809a4568368f44c21b677ebcb2107
## Summary - Add `--comment` flag to CLI (`submit-plan`, `start-analysis`) and `--wait` flag to `get-change` to enable GitHub App PR commenting and control analysis polling - Add `comment` and `wait` inputs to the `submit-plan` composite action, with backward-compatible `fetch-change` deprecation - Migrate internal workflows (`terraform.yml`, `terraform-meta.yml`) to use the new inputs and disable legacy Slack plan notifications ## Linear Ticket - **Ticket**: [ENG-3123](https://linear.app/overmind/issue/ENG-3123/phase-4-cli-action-wire-comment-flag-auto-detect-and-skip-wait) — Phase 4: CLI + Action — Wire Comment Flag, Auto-Detect, and Skip Wait - **Project**: Multi-Plan Submission & GitHub App PR Commenting (Phase 4 of 5) ## Changes ### CLI (`cli/cmd/`) - `flags.go`: New `--comment` bool flag on `addAnalysisFlags`, requesting the GitHub App to post PR comments - `changes_submit_plan.go`: When `--comment` is set, outputs eval-able `CHANGE_URL` and `GITHUB_APP_ACTIVE` assignments instead of bare URL; passes `PostGithubComment` to `StartChangeAnalysis` RPC - `changes_start_analysis.go`: Same `--comment` behavior and `PostGithubComment` plumbing for the standalone `start-analysis` command - `changes_get_change.go`: Adds `--wait` flag (default `true`); skips `waitForChangeAnalysis` when `--wait=false`. Also fixes `MarkDeprecated` referencing wrong command (`submitPlanCmd` → `getChangeCmd`) - Housekeeping: replace `_ = MarkDeprecated`/`MarkHidden` with `cobra.CheckErr(...)` across 7 call sites ### Action (`actions/submit-plan/action.yml`) - New `comment` (default `"true"`) and `wait` (default `"false"`) inputs - `fetch-change` marked deprecated with backward-compatible shim - New `github-app-active` output; fixes `message` output (was incorrectly mapped to `change-url`) - When `comment=true`: tries `--comment` flag, falls back gracefully if CLI is older (`unknown flag` detection), and only fetches/posts sticky comment when the GitHub App is not active - Stderr isolation: redirects stderr to temp files (`submit-stderr.log`, `get-stderr.log`) instead of `2>&1` to prevent logrus output from polluting eval'd shell assignments or PR comment content ### Workflows (`.github/workflows/`) - `terraform.yml` and `terraform-meta.yml`: migrate from `fetch-change` to `comment`, add push-event guard, disable Slack plan notifications (GitHub App replaces them) ## Deviations from Approved Plan ### Additions not in the plan 1. **Stderr isolation in action shell logic** (`actions/submit-plan/action.yml`): The plan uses `eval "$(cli ...)"` directly. The implementation captures stdout to a variable with stderr redirected to temp files (`2>./overmindtech/submit-stderr.log`, `2>./overmindtech/get-stderr.log`), then evals the variable. This prevents logrus stderr lines (containing invalid bash identifiers like `change-url`) from breaking `eval`, and prevents log noise from leaking into PR comment content. 2. **Backward compatibility fallback for older CLIs** (`actions/submit-plan/action.yml`): The plan assumes the CLI supports `--comment` and `--wait`. The implementation adds fallback: if the CLI returns "unknown flag" (detected via the stderr temp file), it falls back to the legacy code path and logs a `::notice::`. This enables rolling out the action change before all CLI versions support the new flags. 3. **Push-event guard in workflows** (`.github/workflows/terraform.yml`, `terraform-meta.yml`): The plan removes `fetch-change` without adding an equivalent guard. The implementation passes `comment: ${{ github.event.number != '' }}` instead of unconditional `comment: true`, preventing comment logic from running on push events where there's no PR number. ### Minor approach changes 4. **Sticky comment condition**: The plan checks `inputs.comment != 'false'`. The implementation checks `steps.submit-plan.outputs.message != ''` — more robust since `message` is only populated when the change was actually fetched. 5. **`fetch-change` deprecation mapping**: The plan maps both `true` → `comment: true` and `false` → `comment: false`. The implementation only remaps the `false` case (setting `OVM_COMMENT='false'`), since `comment` already defaults to `"true"`. ### Omissions from the plan 6. **Part 8 — Linear issue for Slack notification feature**: The plan calls for creating a Linear issue titled "Investigate Slack notification feature for change analysis results". This was **not created** and should be filed separately. ## Test Plan - [x] Flag registration tests for `--comment` on `submit-plan` and `start-analysis` - [x] Flag registration test for `--wait` on `get-change` (default `true`) - [ ] Verify `submit-plan` action with `comment: true` on a PR event (GitHub App active path) - [ ] Verify `submit-plan` action with `comment: true` when GitHub App is not installed (sticky comment fallback) - [ ] Verify `submit-plan` action with older CLI that doesn't support `--comment` (graceful fallback) - [ ] Verify `comment: false` skips all PR commenting logic - [ ] Verify `wait: true` blocks until analysis completes and populates `message` output <!-- CURSOR_SUMMARY --> > [!NOTE] > **Medium Risk** > Changes GitHub Actions and CLI behavior around when to wait for Overmind analysis and where results are posted; misconfiguration could lead to missing plan feedback or altered CI timing. Touches deployment workflows but not Terraform execution logic itself. > > **Overview** > Routes Terraform plan reporting away from Slack and toward PR comments, wiring workflows to pass a new `comment` input to `actions/submit-plan` (and disabling the plan-to-Slack steps). > > Updates the `submit-plan` composite action and Overmind CLI to support `comment`/`wait` controls (deprecating `fetch-change`), including conditional fetching of analysis results, GitHub App vs sticky-comment handling, and new CLI flags/outputs (`--comment`, `get-change --wait`). Also tightens flag handling by checking errors when hiding/deprecating Cobra flags and adds targeted tests for the new flags. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1690417e01470b73fe9bd371b2eb1f878895d32d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> GitOrigin-RevId: a0fb20e395e0f0ffb62e32a3970c48dff980e184
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Copybara Sync - Release v1.17.0
This PR was automatically created by Copybara, syncing changes from the overmindtech/workspace monorepo.
Original author: David Schmitt (david.schmitt@overmind.tech)
What happens when this PR is merged?
tag-on-mergeworkflow will automatically create thev1.17.0tag on mainReview Checklist