feat(site): add per-template Coder Agents controls by ethanndickson · Pull Request #27514 · coder/coder · GitHub
Skip to content

feat(site): add per-template Coder Agents controls - #27514

Merged
ethanndickson merged 13 commits into
mainfrom
feat-site-template-agents-allowed
Aug 6, 2026
Merged

feat(site): add per-template Coder Agents controls#27514
ethanndickson merged 13 commits into
mainfrom
feat-site-template-agents-allowed

Conversation

@ethanndickson

@ethanndickson ethanndickson commented Jul 27, 2026

Copy link
Copy Markdown
Member

Relates to CODAGT-713

Depends on #27285

This replaces the deployment-wide template allowlist UI with per-template Coder Agents controls. Each template's General Settings page exposes agents_allowed to organisation and template administrators through the existing template-update permission, whilst AI Settings > Templates gives deployment administrators a bulk management page. The bulk page requires both deployment-config and template-update permissions, reuses the same URL-backed server-side filter as /templates, tracks pending updates independently for each template, and surfaces failures through template-specific toasts. The copy refers to new workspace creation because disabling a template does not revoke an existing Coder Agent workspace.

This completes the frontend migration away from the experimental /template-allowlist API. #27515 removes the now-unused legacy storage, routes, SDK methods, generated types, and JSON utility. Later PRs add CLI flags and update the platform controls documentation. The stack is intended to merge as a unit.

@linear-code

linear-code Bot commented Jul 27, 2026

Copy link
Copy Markdown

CODAGT-713

@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@ethanndickson

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-08-05 02:37 UTC by @ethanndickson
Spend: $129.70 / $100.00

Review history
  • R1 (2026-07-27): 16 reviewers, 4 Nit, 2 Note, 2 P3, COMMENT. Review
  • R2 (2026-08-03): 14 reviewers, 5 Nit, 4 Note, 2 P3, APPROVE. Review
  • R3 (2026-08-03): 15 reviewers, 8 Nit, 5 Note, 4 P3, COMMENT. Review
  • R4 (2026-08-04): 15 reviewers, 8 Nit, 6 Note, 4 P3, COMMENT. Review
  • R5 (2026-08-04): 16 reviewers, 10 Nit, 8 Note, 4 P3, APPROVE. Review
  • R6 (2026-08-05): 16 reviewers, 11 Nit, 8 Note, 6 P3, COMMENT. Review
  • R7 (2026-08-05): 14 reviewers, 11 Nit, 10 Note, 6 P3, APPROVE. Review

deep-review v0.9.0 | Round 7 | 0702d40..ef6c531

Last posted: Round 7, 27 findings (6 P3, 11 Nit, 10 Note), APPROVE. Review

Finding inventory

Finding inventory - PR #27514

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P3 Author fixed (40740aa); panel verified R2 TemplatesPage.tsx:29 Container toggle state machine (pending set, per-row error isolation) has no interaction test R1 Netero P3, Bisky P3, Nami P3, Kite P3, Chopper P3, Mafuuu Nit Yes
CRF-2 P3 Author contested; panel accepted R2 (human decision made, description aligned) TemplatesPage.tsx:13 Page gate requires editDeploymentConfig && updateTemplates; over-restricts beyond backend authz and mismatches PR description R1 Meruem P2, Mafu-san P3, Kite Note, Chopper Note, Mafuuu Note, Razor Note, Pariston Nit Yes
CRF-3 Note Author accepted R2 (confirmed-server-state intentional) TemplatesPageView.tsx:95 Switch is fully controlled off server data with no optimistic update; appears frozen during PATCH+refetch R1 Hisoka P3, Nami Note, Pariston Note, Chopper Note, Meruem Note Yes
CRF-4 Nit Author fixed (40740aa); panel verified R2 TemplatesPageView.tsx:187 Per-row error fallback says "template access", inconsistent with "Coder Agents" vocabulary used everywhere else R1 Leorio Yes
CRF-5 Nit Author contested; panel accepted R2 (proportionate for a Nit) TemplatesPageView.tsx:177 Update error alerts render as a flat list below the whole table, detached from the failing row R1 Kite Yes
CRF-6 Nit Author fixed (40740aa); panel verified R2 TemplatesPageView.tsx:36 Doc comment restates the prop name (// Update failures keyed by template ID.) R1 Gon Yes
CRF-7 Nit Author fixed (40740aa); panel verified R2 templates.ts:68 Invalidation uses hardcoded ["templates"] literal instead of the exported key constant (FE7) R1 Mafuuu Yes
CRF-8 Note Author accepted R2 (out-of-scope migration acknowledged) templates.ts:56 New updateTemplateMeta helper duplicates two hand-rolled useMutation copies (TemplateSettingsPage, TemplateSchedulePage); migration out of scope R1 Robin Yes
CRF-9 Nit Author fixed (4dcfdf6) TemplatesPageView.tsx:141 Table aria-label "Coder Agents template access" retains the "access" phrasing the CRF-4 fix retired elsewhere R2 Zoro Yes
CRF-10 Note Author fixed (4dcfdf6) TemplatesPageView.tsx:93 Binary "Agents allowed" switch gates creation/discovery only, not existing or started workspaces; the control framing can read as broader access control R2 Mafuuu Yes
CRF-11 Note Author fixed (4dcfdf6) TemplatesPageView.tsx:89 Bulk table has no search/sort/pagination, unlike the searchable picker it replaced; scales poorly for large multi-org deployments R2 Pariston Yes
CRF-12 Nit Dropped by orchestrator (comment praised as behavior-describing by 4 reviewers; one redundant clause is marginal, not P2) TemplatesPage.tsx:23 Container error comment's first clause restates the per-template Map R2 Gon (P2) No
CRF-13 P3 Author fixed (33c31a7) TemplatesPageView.stories.tsx:60 New AI Settings Templates stories all sit behind a pre-existing pixel: { exclude: true } with an unticketed "fix later" TODO; visual-regression/pixel-env coverage lost, and this PR keeps adding stories behind it R3 Netero, Mafu-san Yes
CRF-14 Nit Author fixed (33c31a7) TemplateSettingsForm.tsx:178 Per-template General Settings checkbox label "Allow Coder Agents to use this template" was not reworded to the creation-scoped framing the CRF-10 fix applied to the bulk page; two surfaces for one field use two verbs R3 Mafu-san, Mafuuu, Leorio Yes
CRF-15 P3 Author fixed (33c31a7) TemplatesPageView.tsx:210 Per-row update-failure alert is rendered only for rows surviving the current server-side filter, so filtering out a failed row (or a filter validation error, which nulls the whole body) hides the active failure signal; worse with the non-optimistic switch R3 Mafuuu (raised to P3); also Codex P2 Yes
CRF-16 Nit Author fixed (33c31a7) TemplatesPageView.tsx:185 Filtered empty-state message "No results matched your search" lacks the terminal period the sibling messages use R3 Leorio Yes
CRF-17 Nit Author fixed (33c31a7) TemplatesPageView.tsx:77 Row markup hand-rolls the avatar+two-line label and the "N developers" label instead of reusing shared AvatarData and a shared helper, both of which the sibling /templates page (source of the lifted filter) uses R3 Robin Yes
CRF-18 Note Author fixed (33c31a7) TemplatesPage.tsx:21 The enabled: canManageTemplates gates that suppress the filter user-menu and templates fetches on the permission-blocked page have no test; permission stories pass via RequirePermission hiding the tree, not via skipped fetches R3 Bisky Yes
CRF-19 Note Author fixed (8bff9a9) TemplatesPageView.tsx:203 Flip side of the CRF-15 fix: the snapshot error alert clears only by re-toggling that row, so a failed toggle whose row is then filtered out is un-dismissable/un-retryable in-page, and a lost-response success leaves a stale alert that contradicts the now-confirmed switch until re-toggle R4 Mafuuu, Nami, Meruem Yes
CRF-20 Nit Author fixed (715c27a) TemplatesPage.tsx:30 PR description still says the page "tracks pending updates and errors independently for each template," but the R5 pivot removed the per-template error state (now transient toasts); only pendingTemplateIDs remains R5 Mafu-san Yes
CRF-21 Note Author fixed (715c27a) templates.ts:57 isTemplateListQuery is correct today but relies on an unenforced key-shape invariant; a future non-list ["templates", {...}] query would be silently skipped (stale value, the class this helper prevents) or throw a TypeError in the .some/.map updater. Mitigate by documenting the contract or using a discriminant key segment / centralized key builder R5 Meruem, Chopper, Knov, Leorio Yes
CRF-22 Note Author fixed (715c27a) TemplatesPage.tsx:47 The ConcurrentToggles toast-survival assertion is pinned only by sonner's implicit 4000ms auto-dismiss (flake if the filter roundtrip is slow). duration: Infinity on error toasts pins the assertion and keeps a failed write durably visible (also the Chopper/Pariston/Nami transient-toast tradeoff) R5 Komugi Yes
CRF-23 Nit Author fixed (715c27a) TemplatesPage.tsx:46 The toast fallback "Failed to update Coder Agents access" and the empty-state description "configuring Coder Agents access" (TemplatesPageView.tsx:172) keep the "access" framing the CRF-10 reword retired from the control labels in favor of "create workspaces" R5 Leorio Yes
CRF-24 P3 Author fixed (ef6c531) TemplatesPageView.tsx:132 The bulk page renders the load-error screen instead of the table whenever templatesQuery.error is truthy, without checking for cached data. Since every successful toggle now triggers a list refetch (seed-then-invalidate), a transient refetch failure (token expiry, 500) wipes the populated table even though the write succeeded. The sibling /templates page renders the same error additively above cached rows R6 Hisoka Yes
CRF-25 P3 Author fixed (ef6c531) templates.ts:97 The shared/canonical updateTemplateMeta helper invalidates templateByNameKey using the pre-update template.name (mutation vars) instead of result.name; a future rename caller routed through it leaves the new-name detail cache stale, the exact case the sibling General Settings path guards with data.name. Latent (current sole caller sends only agents_allowed) but the helper is exported and positioned (CRF-8) as the migration target. One-line fix: use result R6 Zoro P3, Hisoka Note, Chopper Note Yes
CRF-26 Nit Author fixed (ef6c531) templates.ts:22 templatesKey is a single-use module constant that only feeds templateListsKey; AGENTS.md says inline single-use module constants R6 Zoro Yes
CRF-27 Note Open templates.test.ts:68 The updateTemplateMeta.onSuccess 304 branch (result ?? template fallback: invalidate templateKey(id) + by-name off input template) is untested; the new rename test only exercises the result-present path. P4-equivalent, current sole caller toggles agents_allowed so a 304 is unlikely R7 Bisky Yes
CRF-28 Note Open TemplatesPageView.tsx:119 Four findings (CRF-11 filter, CRF-15 error placement, CRF-17 avatar/label, CRF-24 load-error rendering) share one root: the AI Settings page reimplements the /templates list view instead of sharing it, so the two hand-maintained copies keep drifting. Observation, not a refactor request at R7 (panel repeatedly accepted the parallel-page approach) R7 Pariston Yes

Contested and acknowledged

CRF-2 (P3, TemplatesPage.tsx:13) - Page gate requires editDeploymentConfig && updateTemplates

  • Finding: The bulk AI Settings > Templates page gates on editDeploymentConfig && updateTemplates, stricter than the backend template:update authz the operation actually needs, and the PR description said access is "limited to users who can update templates." Asked for a human decision: accept deployment-admin scoping and fix the description, or drop editDeploymentConfig.
  • Author defense (R2, PRRC_kwDOGkVX1s7cpX_F): Keeps the dual gate intentionally. The bulk surface is part of the deployment-admin Coder Agents settings; template administrators edit the same field per-template from General Settings (updateTemplates alone). Updated the PR description to state the bulk page requires both deployment-config and template-update permissions.
  • Status: Contested. The human decision the finding asked for has been made by the author (ethanndickson): dual gate is intentional and the description now matches the gate. No panel disposition yet; reviewers may evaluate whether the deployment-admin scoping reasoning holds.

CRF-3 (Note, TemplatesPageView.tsx:95) - Switch controlled off server data, no optimistic update

  • Finding: The Switch reads checked straight from the query cache with no optimistic value, so it does not move until the PATCH+refetch settles.
  • Author defense (R2, PRRC_kwDOGkVX1s7cpYBo): Intentional. Switch stays on confirmed server state, is disabled in flight, unchanged on failure, and updates after the successful refetch; the new interaction story documents both paths.
  • Status: Acknowledged. Finding was already framed as a conscious-tradeoff Note; author confirmed it is a deliberate choice.

CRF-5 (Nit, TemplatesPageView.tsx:177) - Error alerts detached from failing row

  • Finding: Update errors render as a flat list below the whole table rather than inline with the failing row.
  • Author defense (R2, PRRC_kwDOGkVX1s7cpYIh): Keeps alerts below the table. Each has role="alert" and the affected template label, and the new interaction story verifies row-scoped errors that clear on retry. Inline placement is a larger layout change beyond this Nit.
  • Status: Contested. Justification is proportionate for a Nit.

CRF-8 (Note, templates.ts:56) - Shared helper is the third wrapper

  • Finding: updateTemplateMeta is the third wrapper of API.updateTemplateMeta; migration of the two older copies was scoped out.
  • Author defense (R2, PRRC_kwDOGkVX1s7cpYQF): Shared helper is the canonical path for new callers; the two older wrappers carry distinct navigation, toast, 304, and local-storage behavior, so migrating them is a separate refactor.
  • Status: Acknowledged. Finding itself scoped migration out.

Round log

Round 1

Panel (16 reviewers: bisky, hisoka, mafu-san, mafuuu, pariston, nami, ging-react, ging-ts, komugi, gon, leorio, kite, chopper, robin, razor, meruem) plus Netero first pass. No Law (effective additions 432 < 1000). Reviewed against 2a999e0..35387b5.

Netero: 1 P3, 1 Note. P3-and-below cleared the mechanical floor, panel proceeded.

Cross-check resolution: Meruem rated the permission-gate issue P2 on the claim that the sidebar "Templates" link shows for updateTemplates alone and diverges from the page gate, creating a reachable dead-end. Verified against AISettingsSidebarView.tsx:55-75: the link (lines 65-67) is nested inside the permissions.editDeploymentConfig block AND gated on updateTemplates, so it renders only when editDeploymentConfig && updateTemplates, exactly matching the page gate (TemplatesPage.tsx:13-14). Meruem's divergence/dead-end claim is empirically false; empirical disproof wins. The surviving concern (gate over-restricts beyond the backend template:update authz + PR-description mismatch), corroborated by 6 reviewers at Note/Nit/P3, carried at P3 (CRF-2).

Downgrade gate CRF-3 (Hisoka P3 -> Note): keep-at-P3 argument is that the controlled Switch stays visually frozen for the whole PATCH+refetch, so a slow link looks like a missed click. Downgraded because disabled={isPending} disables the switch in-flight (prevents the double-click Hisoka posited), and 4 reviewers independently judged non-optimistic the correct choice for a write that must not show success before confirmation; residual is cosmetic lag, a conscious-tradeoff Note.

Process observations (CI fully red but not attributable to this diff; legacy SDK deferral to #27515; MixedOrganizations story-name overlap) surfaced in the review body, not as inline findings.

New findings: CRF-1 (P3), CRF-2 (P3), CRF-3 (Note), CRF-4 (Nit), CRF-5 (Nit), CRF-6 (Nit), CRF-7 (Nit), CRF-8 (Note). Event: COMMENT (no P0/P1).

Round 2

Churn guard: PROCEED (4 addressed, 1 acknowledged, 3 contested, 0 silent). Reviewed against 4083e82..40740aa. CI now green.

Between rounds the author also addressed two Codex findings not in this inventory (foreign IDs, not cross-referenced): a P1 on concurrent-toggle callbacks and a P2 on switch accessible names. The container toggleAgentsAllowed was refactored from per-mutate callbacks to awaiting each mutateAsync in its own try/catch/finally, and switch aria-labels now include the organization. This is a substantive production refactor of the concurrency logic; the round-2 panel reviews it fresh.

Panel (14: bisky, hisoka, mafu-san, mafuuu, pariston, komugi, meruem, nami, chopper, ging-react, ging-ts, gon, leorio + wildcard zoro) plus Netero. Netero: no findings, all mechanical CRFs verified fixed. Panel verified the CRF-1 fix (ConcurrentToggles story) is genuine and deterministic (Komugi cleared it for flake: ordering rests on sequential awaits and the onSuccess->invalidate->refetch happens-before edge, not scheduler luck). The mutateAsync try/catch/finally refactor confirmed structurally correct by Hisoka, Meruem, Mafuuu, Nami, Pariston. Contested/acknowledged CRF-2/3/5/8 accepted by the panel with no new evidence to re-raise; CRF-2's human decision was made by the author and the description now aligns.

Drop gate CRF-12 (Gon P2 -> dropped): keep-argument is that the comment's first clause "Errors are tracked per template" restates the ReadonlyMap type. Dropped because the same comment was cited as earning its lines (behavior-describing, not prop-restating) by Mafu-san, Leorio, Chopper, and Zoro this round and by Gon/Leorio/Bisky in R1; the redundancy is a single clause and does not rise to a Nit worth posting against that consensus.

New findings: CRF-9 (Nit), CRF-10 (Note), CRF-11 (Note). Process observations in body: new stories added under a pre-existing pixel: { exclude: true } with a vague unticketed TODO (Bisky); commit subject "review" is uninformative but squash-merge replaces it (Leorio). Event: APPROVE (auto-downgraded to COMMENT); nothing blocks.

Round 3

Churn guard: PROCEED (3 addressed, 0 silent). Reviewed against 40740aa..4dcfdf6. CI green.

CRF-9/10/11 fixed with real code: aria-label reworded (CRF-9); column header "Agents allowed" -> "New workspaces" and switch labels reworded to "Allow Coder Agents to create workspaces with ..." to scope the control to creation (CRF-10); and a URL-backed server-side TemplatesFilter/useTemplatesFilter (reused from /templates) wired through the page with filtered-empty and filter-validation-error handling, plus ServerSideFilter/FilteredEmpty stories (CRF-11). The filter is a substantive new production surface reviewed fresh this round; pagination intentionally omitted to match /templates. CRF-2/3/5/8 were settled in R2; not re-opened.

Panel (15: bisky, hisoka, mafu-san, mafuuu, pariston, nami, robin, meruem, chopper, kite, komugi, leorio, ging-react, ging-ts + wildcard knov) plus Netero. Filter extraction verified as genuine reuse (Pariston, Mafu-san, Kite, Knov): the hook was lifted into the shared TemplatesFilter module, both pages import one definition, and the added enabled option defaults to true so /templates is unchanged. Partial PATCH safety re-verified (Hisoka, Mafuuu, Chopper, Knov, Pariston). Komugi cleared the new ServerSideFilter story for flake (500ms wall-clock debounce inside a 1000ms waitFor budget).

Cross-check severity: CRF-15 (Mafuuu Note -> P3). Keep-higher argument: the round-3 filter couples the per-row failure alert to the filtered templates list, so filtering out a failed row, or a filter validation error that renders the whole results branch null, hides an active failure; combined with the non-optimistic switch (CRF-3, which never moves on click) a filtered-out failed toggle can show no feedback at all, and this bites exactly the large-list workflow the filter was added to serve. Downward argument (Mafuuu): the switch always reflects true server state and the error returns when the filter clears, so the signal is recoverable, not lost. Higher wins under doubt for an introduced regression that hides a write failure; P3.

CRF-13 (Netero P3, Mafu-san Note): held at P3. Pre-existing pixel: { exclude: true } masks play-function failures under pixel and has no ticket; this PR grows the excluded set for a third round. Needs a human decision (ticket or fix), not silent acceptance.

New findings: CRF-13 (P3), CRF-14 (Nit), CRF-15 (P3), CRF-16 (Nit), CRF-17 (Nit), CRF-18 (Note). Process note in body: commit subjects "review"/"review" uninformative (Leorio), harmless under squash-merge. Event: COMMENT (two open P3s, no P0/P1).

Round 4

Churn guard: PROCEED (6 addressed, 0 silent). Reviewed against 7713788..33c31a7. CI red but stack-inherited: 20/20 jobs red including Go/sqlc/offlinedocs which a frontend diff cannot touch; orchestrator verified biome, tsc, and the changed stories' play functions pass locally (the 3 storybook failures are an unrelated xterm error in AgentChatPageView.stories.tsx).

CRF-13/14/15/16/17/18 all fixed with real code. CRF-15 fix: alerts now render from Array.from(updateErrors.values()) with a new TemplateUpdateError type carrying its own template, decoupled from the filtered list; FilteredOutMutationError story added. CRF-17 fix: shared AvatarData + new formatTemplateActiveDevelopersLabel helper (with unit test) reused by this page and /templates. CRF-13 fix: pixel exclude and TODO removed. Panel reviews the error-state restructure, the shared-helper refactor (touches existing /templates), and the pixel-exclude removal fresh.

Open risk to confirm (not a code defect): CRF-13's fix removed the pixel: { exclude: true } that existed because the play functions were reported to fail under pixel. The hosted Storybook/pixel visual-regression run cannot be reproduced locally; its result on this head must be confirmed green before merge, since removing the exclude surfaces any real pixel failure it was masking.

Panel (15: bisky, hisoka, mafu-san, mafuuu, pariston, nami, robin, meruem, chopper, komugi, kite, leorio, ging-react, ging-ts + wildcard zoro) plus Netero. 11 no-findings. All round-3 fixes verified genuine: CRF-15 decoupled (alerts render from Array.from(updateErrors.values()) outside every branch, each carrying its own template; FilteredOutMutationError + ValidationError stories prove it; no leak on success), CRF-17 shared helper behavior-equivalent to the old /templates inline expression (unit test, no regression), CRF-13 exclude+TODO removed (per-cell data-pixel="ignore" correctly retained).

New CRF-19 (Note, convergent Mafuuu/Nami/Meruem): the CRF-15 fix's flip side. Because the error is a snapshot cleared only by re-toggling that row's Switch, (a) a failure whose row is filtered out has no in-page retry/dismiss until the filter clears or a reload, and (b) a lost-response success (PATCH succeeds server-side, client sees error) leaves a stale red alert while the refetched Switch shows success, so alert and switch contradict. All three rated it Note: bounded, recoverable, and the deliberate visible-over-hidden tradeoff the panel endorsed at CRF-15. Meruem's structural option: derive the alert from live query state (desired value vs refetched agents_allowed) so a confirmed success retires its own alert.

Pre-existing/out-of-scope (body only, not CRFs): Komugi Note (ServerSideFilter 500ms debounce inside 1000ms waitFor, unchanged since R3, accepted); Mafuuu P4 (updateActiveTemplateVersion invalidates templateByName by organization_id while detail subscribers key by name; the new updateTemplateMeta got it right, sibling is pre-existing); Leorio Note (commit subjects "review", R2/R3 already, squash-merge mitigates).

Event: COMMENT. No code defect blocks, but the hosted Storybook/pixel job on this head is unverified and must be confirmed green before merge (CRF-13 removed the exclude that masked pixel failures), so not APPROVE.

Round 5

Churn guard: PROCEED (1 addressed, 0 silent). Reviewed against 33c31a7..8bff9a9. CI now green (Storybook passes on this head, resolving the round-4 pixel confirmation).

Two new production surfaces this round, both reviewed fresh:

  1. CRF-19 fix (pivot): the persistent updateErrors ReadonlyMap, the TemplateUpdateError type, and the pinned role="alert" page-alert block were removed; per-row toggle failures now use dismissible Sonner toast.error(...). Container story asserts the toast survives filtering without coupling to the row.
  2. Codex P2 fix (foreign finding, not a CRF): a stale templates-list cache after a General Settings agents_allowed save. New updateTemplateListQueries helper synchronously replaces the returned template in every cached template-list query that contains it, then invalidates those list queries; General Settings awaits it before navigation. Unit tests exclude non-list keys.

Panel (16: bisky, hisoka, mafu-san, mafuuu, pariston, nami, meruem, robin, chopper, komugi, knov, kite, leorio, ging-react, ging-ts + wildcard razor) plus Netero. 10 no-findings. Both new surfaces verified sound by multiple reviewers: the toast pivot resolves both CRF-19 halves (transient dismissible toast decoupled from the row; ConcurrentToggles story proves it survives filtering), and the cache reconciliation's setQueriesData-then-invalidate ordering + isTemplateListQuery predicate are correct against every current ["templates", ...] key (verified by Razor, Kite, Knov, Hisoka, Nami, Pariston; unit test pins positive + negative).

New findings (nothing blocking): CRF-20 (Nit, description drift), CRF-21 (Note, convergent Meruem/Chopper/Knov/Leorio: isTemplateListQuery unenforced-invariant future-fragility, correct today), CRF-22 (Note, Komugi: toast-survival assertion pinned only by the 4000ms auto-dismiss; duration: Infinity fixes flake + keeps failed write visible), CRF-23 (Nit, Leorio: "access" vocabulary lingering in toast fallback + empty-state vs the CRF-10 creation-scoped reword).

Body-only (pre-existing/out-of-scope/endorsed, not CRFs): TemplateSchedulePage's hand-rolled updateTemplateMeta wrapper not brought into the list-reconciliation contract (Mafu-san/Pariston; CRF-8-adjacent, non-hazardous since it never changes agents_allowed); Robin's note that chats.ts has a similar isChatListQuery/updateInfiniteChatsCache pattern (correctly NOT abstracted, different cache shapes); Bisky's note that the toast description branch is untested; commit subjects "review" (Leorio, R2-R4, squash-merge mitigates); the transient-toast-on-non-optimistic-switch durable-indicator tradeoff (Chopper/Pariston/Nami, the endorsed CRF-19 tradeoff).

Event: APPROVE (auto-downgraded to COMMENT). All 19 prior findings fixed or settled, CI green (pixel confirmation resolved), new items are non-blocking Notes/Nits.

Round 6

Churn guard: PROCEED (4 addressed, 0 silent). Reviewed against 61e84fb..715c27a. CI red but stack-inherited again (20/20 including Go/sqlc/offlinedocs; base rebased to 61e84fb). Orchestrator verified biome + tsc clean on the changed files; no hardcoded old query keys remain.

All 4 round-5 findings fixed. Main new surface: the CRF-21 fix took the stronger mitigation, an explicit ["templates", "list", options] key hierarchy. templateListsKey = ["templates", "list"], getTemplatesQueryKey returns [...templateListsKey, options], updateTemplateListQueries targets { queryKey: templateListsKey } (prefix), and the isTemplateListQuery heuristic is removed entirely. This is a global query-key change to the shared templates list (both the AI Settings bulk page and the existing /templates page). Orchestrator pre-checks: only non-list ["templates","examples"] and ["templates", id, "resources"] manual keys remain (no collision with the new list prefix); no hardcoded old ["templates", options] list key survives; bare ["templates"] prefix invalidations elsewhere still match. CRF-22: error toasts now duration: Number.POSITIVE_INFINITY (still dismissible). CRF-23: fallback + empty-state reworded to creation-scoped, story assertions updated. CRF-20: PR body updated.

Panel (16: bisky, hisoka, mafu-san, mafuuu, pariston, nami, meruem, robin, knov, kite, chopper, komugi, leorio, ging-react, ging-ts + wildcard zoro) plus Netero. 11 no-findings. The CRF-21 key-hierarchy fix verified as the correct structural cure by ~8 reviewers (discriminant "list" segment, centralized builder, negative unit test seeding ["templates", {view}], no sibling collision, no /templates regression; every list consumer routes through getTemplatesQueryKey, incl. the TasksPage story that was migrated off the old shape).

New findings: CRF-24 (P3, Hisoka), CRF-25 (P3, convergent Zoro/Hisoka/Chopper), CRF-26 (Nit, Zoro).

CRF-24 severity: P3. The hasError(error) && !hasValidationError branch (TemplatesPageView.tsx:132) renders the load-error screen instead of the table without checking templates. TanStack Query v5 retains data and sets error on a failed background refetch; because every successful toggle now refetches the list (seed-then-invalidate), a transient list-endpoint failure swaps the whole populated table for "Failed to load templates." even though the toggle committed. Recoverable via Retry (P3), but fires on the feature's core action. Fix: match the sibling /templates page, render the error additively above cached rows.

CRF-25 severity: Zoro P3, Hisoka/Chopper Note -> held at P3. Keep-higher: the reachability-dismissal rule says do not downgrade an exported function's finding because no current caller hits it; this helper is exported and CRF-8's defense positioned it as the canonical migration target, so a future rename caller silently regresses the new-name detail cache, a bug the replaced General Settings code explicitly guards. Latent today; one-line fix (result?.name ?? template.name).

Body-only (pre-existing/out-of-scope/carryover, not CRFs): the standing updateActiveTemplateVersion organization_id-vs-name invalidation no-op (Knov/Chopper; Mafuuu R4 P4, line 245 untouched by this diff); Bisky's toast description branch untested (R5 carryover); Komugi's 500ms-debounce-in-1000ms-waitFor (pre-existing, accepted); commit subjects "review" (Mafu-san, squash-merge mitigates).

Event: COMMENT (two open P3s, no P0/P1).

Round 7

Churn guard: PROCEED (3 addressed, 0 silent). Reviewed against 0702d40..ef6c531. CI red but stack-inherited again (base rebased; 20/20 including Go/sqlc/offlinedocs).

All 3 round-6 findings fixed with real code:

  • CRF-24: load error now renders additively above the table (hasLoadError block, mb-4); the table renders when !hasValidationError && (!hasLoadError || templates !== undefined), so a refetch error with cached data shows both the alert and the cached rows, while an initial failure with no data hides the table (verified against the code). New RefetchError/LoadError stories.
  • CRF-25: updateTemplateMeta.onSuccess derives const updatedTemplate = result ?? template and keys the by-name invalidation off updatedTemplate (returned template, 304 fallback to input). New unit test seeds old- and new-name keys.
  • CRF-26: single-use templatesKey removed; templateListsKey = ["templates", "list"] defined directly.

Panel reviews the CRF-24 error-rendering restructure (edge cases: refetch-with-cache vs initial-no-data vs validation error) and the CRF-25 rename-safe invalidation fresh.

Panel (14: bisky, hisoka, mafu-san, mafuuu, pariston, nami, meruem, chopper, knov, kite, komugi, ging-react, ging-ts + wildcard razor) plus Netero. 12 no-findings. Both fixes verified sound: the three CRF-24 render states behave correctly (Pariston/Meruem traced refetch-with-cache -> alert+rows, initial-no-data -> alert only, validation -> table hidden + filter error, no double-error; Pariston notes the initial-error handling is actually cleaner than the sibling /templates page's permanent skeleton), and CRF-25's rename-safe invalidation matches the General Settings sibling with a test that pins the exact regression (fails on the pre-fix code). CRF-26 trivial.

New findings (both Notes, non-blocking): CRF-27 (Bisky, the 304 fallback branch is untested, P4-equivalent), CRF-28 (Pariston, structural observation that four findings share the parallel-list-view root; explicitly not a refactor request).

Mafu-san correction incorporated: the CI-red set also includes frontend-relevant jobs (test-js, Storybook, lint, fmt, gen), not only Go/sqlc/offlinedocs; he ran the changed unit tests, tsc, biome, and all 17 changed-story play functions locally and they pass, so the red is not attributable to this diff's changed files. Stack-inheritance stands, verified more broadly this round.

Event: APPROVE (auto-downgraded to COMMENT). All 26 prior findings fixed or settled; the two round-6 P3s are resolved; new items are non-blocking Notes.

Law analysis

Not run (effective additions 432 R1, 552 R2, 733 R3, 864 R4; all < 1000 threshold).

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35387b5d50

ℹ️ 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".

Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPage.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, net-negative migration: it swaps the deployment-wide allowlist picker for a per-template agents_allowed toggle across three surfaces (AI Settings > Templates, template general settings, sidebar nav) and adds a shared updateTemplateMeta mutation. The strongest part is the per-row state design: pending and error state are keyed by template ID in component-owned Set/Map with functional updaters and per-mutate onError/onSettled callbacks, so concurrent row toggles never clobber each other. Reviewers checked the backend contract end to end and confirmed the single-field PATCH is safe: resolveTemplateMetaUpdate falls back to the existing template for every nil field, so sending only { agents_allowed } does not wipe name, description, TTLs, or ACLs. Permission deny-paths and the two-error MutationError case are covered by stories, not just the happy path.

Severity count: 2 P3, 2 Note, 4 Nit. No P0/P1/P2.

One cross-check worth stating: the permission-gate finding was raised at P2 on the premise that the sidebar "Templates" link and the page gate disagree and leave a reachable dead-end. That premise does not hold. In AISettingsSidebarView.tsx the link (lines 65-67) is nested inside the permissions.editDeploymentConfig block and additionally gated on updateTemplates, so it renders only when editDeploymentConfig && updateTemplates, exactly matching the page's canManageTemplates. Sidebar and page are in sync. What survives is narrower and is filed as CRF-2 at P3: the gate requires editDeploymentConfig even though the operation is a template:update, so it is stricter than both the backend authz and the PR description ("limited to users who can update templates"). That is a design + description question a human should settle.

Process notes, not inline findings:

  • CI is fully red (20/20 required jobs, including fmt, lint, gen, offlinedocs, and unrelated Go jobs), but four reviewers independently ran tsc --noEmit, biome, and the changed story tests locally and all pass on this diff's files. The redness is consistent with the stacked dependency ("Depends on #27285") running against a base that lacks it, not with a defect in this diff. Please confirm the red is stack-inherited and clears once #27285 is in the base; "red because stacked" is currently an inference, not a verified fact.
  • The legacy API.getChatTemplateAllowlist / updateChatTemplateAllowlist SDK methods lose their last callers here and now target routes #27285 already deleted. The PR body defers their removal to #27515, so this is a deliberate split boundary, not a silent drop, worth confirming #27515 actually lands.
  • Minor: the MixedOrganizations story name promises grouping the view does not do (it renders three rows with different org labels). Worth knowing, not worth changing.

Hisoka, after trying to break the concurrency: "I tried to make it drop a row's error or leak another row's pending flag. It wouldn't. Nice work."

🤖 This review was automatically generated with Coder Agents.

Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPage.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPage.tsx
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated
Comment thread site/src/api/queries/templates.ts Outdated
Comment thread site/src/api/queries/templates.ts Outdated
@ethanndickson
ethanndickson force-pushed the feat-agents-template-access-control branch from 2a999e0 to 4083e82 Compare August 3, 2026 05:12
@ethanndickson
ethanndickson force-pushed the feat-site-template-agents-allowed branch from 35387b5 to 616f118 Compare August 3, 2026 05:12
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@ethanndickson

Copy link
Copy Markdown
Member Author

/coder-agents-review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 40740aa78a

ℹ️ 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".

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2 lands the round-1 feedback cleanly and the new production code holds up. The concurrency refactor is the substantive change: toggleAgentsAllowed now awaits each mutateAsync in its own try/catch/finally with pending and error state keyed per template ID, so a shared useMutation observer can no longer clobber a row (this also resolves the Codex P1 on per-call callbacks). The panel traced it end to end and it is correct: the switch is disabled synchronously before the first await (no double-fire), success resolves only after the invalidation refetch settles (no snap-back flicker), and per-row errors neither overwrite nor clear each other.

The CRF-1 fix is a real interaction test, not a token render check. The new ConcurrentToggles story drives two overlapping toggles through deterministic deferreds, rejects one while resolving the other, asserts the failing row keeps its scoped alert while the succeeding row updates, then retries and asserts the alert clears. Komugi cleared it for flake specifically: ordering rests on sequential awaits and the onSuccess -> invalidate -> refetch happens-before edge, not scheduling luck.

Round-1 disposition: CRF-4, CRF-6, CRF-7 fixed and verified. CRF-2 (dual permission gate) was the one item needing a human decision; the author made it (deployment-admin scoping is intentional, template admins still edit the field per-template from General Settings) and aligned the PR description, and the sidebar/page gates match with no reachable dead-end, so the panel accepts it. CRF-3 (non-optimistic switch) and CRF-5 (below-table alerts) remain conscious, proportionate tradeoffs; CRF-8 stays a correctly scoped-out migration.

New this round: 1 Nit, 2 Notes, nothing blocking. The two Notes are product judgment calls for a human, not defects: the binary "Agents allowed" switch only gates creation and discovery (the copy is honest about this), and the bulk table dropped the searchable picker for an unsorted, unfiltered wall of switches that scales poorly on large multi-org deployments.

Process notes: the round adds several stories into a file carrying a pre-existing pixel: { exclude: true } with a vague unticketed TODO, so the Templates table has no visual-regression coverage; worth a human deciding whether the pixel-harness failure gets a ticket before more stories pile up behind the exclude (the container stories are not excluded, so the concurrency test does run). The fix commit subject is the single word "review", which is uninformative, but Coder squash-merges so the PR title replaces it on main.

Bisky on the new test: "It fires two toggles while both mutations sit unresolved on deferreds ... Deterministic deferreds, no time.Now(), no wall-clock. This tests the exact concurrency the container refactor introduced, not a mock echoing itself."

🤖 This review was automatically generated with Coder Agents.

Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx
@ethanndickson

Copy link
Copy Markdown
Member Author

/coder-agents-review

@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4dcfdf6fc7

ℹ️ 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".

Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 3 lands the round-2 items with real code and the new surface mostly holds. CRF-9 (aria-label reworded), CRF-10 (column renamed "New workspaces", switch labels scoped to creation), and CRF-11 (URL-backed server-side filter) are all fixed. The CRF-11 fix is genuine reuse, not a fork: the useTemplatesFilter/TemplateFilterState hook was lifted out of the general /templates page into the shared TemplatesFilter module, both pages now import one definition, and the added enabled option defaults to true so /templates behavior is unchanged while the AI Settings page threads enabled: canManageTemplates into both the filter user-menu and the templates query. Partial-PATCH safety, the dual permission gate, and query invalidation were all re-verified against the backend.

Severity count: 2 P3, 1 Note, 3 Nit. No P0/P1.

The one worth fixing before merge is CRF-15: the new filter coupled the per-row failure alert to the filtered result set, so filtering out a failed row, or a filter validation error that blanks the whole results body, hides an active update failure. Because the switch is non-optimistic (CRF-3, it never moves on click), a filtered-out failed toggle can show no feedback at all, and that bites exactly the large-list workflow the filter was added for. The signal is recoverable (it returns when the filter clears), which is why Mafuuu filed it as a Note, but hiding a write failure during the feature's own workflow is a P3 in my read. Keying the alerts off updateErrors directly rather than the filtered templates list closes it.

The rest are minor: the CRF-10 reword didn't reach the sibling per-template General Settings checkbox (three reviewers), a missing period on the filtered-empty message, and some row markup that could reuse the shared AvatarData and developer-count helper the sibling page already uses. CRF-13 (the pre-existing pixel: { exclude: true } with an unticketed TODO, now carrying more stories each round) is held at P3 and needs a human decision: file a ticket or fix the play functions, not silent acceptance. Interaction coverage still runs in the normal Storybook runner; only visual-regression/pixel coverage is lost.

Process note: the last two commit subjects are both "review", which is uninformative, though squash-merge under the PR title makes it harmless on main.

Hisoka, on the fresh filter surface: "I came to fight the fresh round-3 surface and it held. Boring in the best way. No strike to throw."

🤖 This review was automatically generated with Coder Agents.

Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.stories.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPageView.tsx Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPage.tsx
@ethanndickson
ethanndickson force-pushed the feat-agents-template-access-control branch from 4083e82 to 7713788 Compare August 4, 2026 04:28
@ethanndickson
ethanndickson force-pushed the feat-site-template-agents-allowed branch from 4dcfdf6 to 33c31a7 Compare August 4, 2026 04:28
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@ethanndickson

Copy link
Copy Markdown
Member Author

/coder-agents-review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33c31a7550

ℹ️ 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".

@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

Re: Filter task templates by agent allowance

Thanks, but this is not a bypass of the new control. agents_allowed replaces the legacy chat template allowlist and applies to the Coder Agents list_templates, read_template, and create_workspace tools. TasksPage uses the separate Tasks API, which the legacy allowlist did not control.

The story change only updates the React Query cache key to match the existing production query.

Adding only agents-allowed:true to the frontend query would also be insufficient enforcement. A client could still call the Tasks API directly. If this setting should also govern the Tasks API, that requires a separate backend-first change with API tests, followed by the frontend filter and story updates.

Closing this as out of scope.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 477367be7b

ℹ️ 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".

@ethanndickson
ethanndickson force-pushed the feat-site-template-agents-allowed branch from 73e9ab6 to e1df7ab Compare August 5, 2026 09:50

@DanielleMaywood DanielleMaywood left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly okay! I'm not the biggest fan of the useTemplatesFilter hook but I'll be honest and say I'm not 100% sure what the alternative looks like.

Comment thread site/src/api/queries/templates.ts Outdated
Comment thread site/src/pages/AISettingsPage/TemplatesPage/TemplatesPage.stories.tsx Outdated
@ethanndickson
ethanndickson force-pushed the feat-site-template-agents-allowed branch from 34696f8 to 6cd0526 Compare August 6, 2026 03:31
@ethanndickson
ethanndickson force-pushed the feat-agents-template-access-control branch from 048b091 to 3fd69e5 Compare August 6, 2026 03:31
@ethanndickson
ethanndickson force-pushed the feat-site-template-agents-allowed branch from 6cd0526 to ccd94e6 Compare August 6, 2026 03:51
@ethanndickson
ethanndickson force-pushed the feat-agents-template-access-control branch from 3fd69e5 to 6f99844 Compare August 6, 2026 03:51

ethanndickson commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

@ethanndickson
ethanndickson changed the base branch from feat-agents-template-access-control to graphite-base/27514 August 6, 2026 04:05
ethanndickson added a commit that referenced this pull request Aug 6, 2026
Relates to CODAGT-713

Depends on #27284

This makes the per-template `agents_allowed` field authoritative in the API and chatd. It adds optional create and metadata update fields with the intended default and omission semantics, supports `agents-allowed:` template search, includes the value in telemetry, and makes `list_templates`, `read_template`, and `create_workspace` read the template row directly. Existing-workspace retries remain idempotent, and blocked same-organisation templates return an actionable message.

The experimental `/template-allowlist` routes remain temporarily because the shipped AI Settings page still calls them, but they no longer control chatd enforcement. #27514 moves that page to per-template metadata, #27515 removes the legacy storage, routes, SDK types, and utility, #27517 adds the CLI flags, and #27518 updates the platform controls documentation for the per-template model, directly addressing CRF-5 and CRF-6. The stack is intended to merge as a unit.
@ethanndickson
ethanndickson changed the base branch from graphite-base/27514 to main August 6, 2026 04:14
@ethanndickson
ethanndickson force-pushed the feat-site-template-agents-allowed branch from ccd94e6 to 35c2c38 Compare August 6, 2026 04:15
@ethanndickson
ethanndickson merged commit 01c00ce into main Aug 6, 2026
27 checks passed
@ethanndickson
ethanndickson deleted the feat-site-template-agents-allowed branch August 6, 2026 04:23
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants