GeezerVison is showing github.com — feat: add organization-scoped Coder Agents instructions by ibetitsmike · Pull Request #30272 · coder/coder
Conversation
ibetitsmike
commented
Oct 2, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Adds organization-scoped Coder Agents instructions. Organization admins set them in Admin settings > AI > Coder Agents > Organization settings, or with GET/PUT /api/v2/organizations/{organization}/chats/config/system-prompt. Implements CODAGT-984.
The instructions add to the deployment system prompt and never replace it. When a chat is created, chatd stores the organization prompt as its own system row right after the deployment row, only for chats in that organization. Subagents resolve their parent organization's current prompt when they spawn, and existing chats keep their stored rows. Access reuses the organization chat_model_config permission: owners and organization admins edit, auditors read, members get 404 on read and 403 on write. Writes reuse the deployment prompt's sanitization, size limit (128 KiB by default), and audit behavior, with a new chat_organization_system_prompt audit resource type. Migration 000613 (the next number after 000612 on main) adds the chat_organization_system_prompts table.
Testing
- Go: enterprise authorization (including an update-only custom role), validation, and audit tests; chatd row order and subagent tests.
- Frontend: Vitest interaction tests and stories for the card (loading, load error, refetch error over the cached value, save error, read-only).
- Remote dogfood UAT, evidence chat: round 1 PASS on
b027cb5ca67 (permission matrix, validation, UI, row order, cross-organization isolation, audit, subagents, regression). Round 2 PASS on 618bff67c75 (loading and load-error states, refetch error over the cached value with unsaved edits kept, update-only custom role saves over the API, row order, the documented size limit, rapid organization switching, double-click save).
- CI: rebased onto
main (98332c739b0) as 3850fbaa922; other commit SHAs in this description are from before the rebase. Every check passed on 3850fbaa922, with test-go-pg green on the first attempt. After the review fixes in item 7, main was merged in as 006c4951749 to resolve new conflicts in generated files and renumber the migration to 000613. Every check passes on 006c4951749. Before the rebase, every check passed on b4e76543df2. test-go-pg (ubuntu-latest) passed on its fourth attempt; the first three failed only the cli package goroutine leak check, with every test passing. Two of those leaked a coderd instance, which also happens intermittently on main: TestServer/Logging cancels coder server during startup, and an early return in cli/server.go skips closing coderd. That fix is in fix(cli): close coderd on server startup errors #30280. The first attempt leaked an idle HTTP connection instead (not investigated).
Screenshots
From remote UAT on a test deployment (test data only).
Organization admin saves instructions (b027cb5ca67) |
Auditor sees read-only instructions, no save actions (b027cb5ca67) |
 |
 |
Loading state while the first fetch is pending (618bff67c75) |
Refetch error shown above the field; the unsaved edit is kept and Save stays enabled (618bff67c75) |
 |
 |
Review record
- Codex, review on
c42b5f9e05c: 6 findings. Fixed the missing loading state, refetch failures hiding cached instructions, and two docs style issues (58eab5603a4, cc73b714630). Two were first declined in error, then corrected: the read-only test now checks that typing leaves the value unchanged (cc73b714630), and update-only custom roles no longer get a 500 on save (618bff67c75).
- Independent security review by a clean-context agent, comment on
c42b5f9e05c: no P0 to P2 findings. A stale P3 comment was fixed in 34c17aadb7f; returning err.Error() in 500 details was kept to match the deployment prompt handlers.
- Codex, review on
58eab5603a4: 2 findings (refetch errors not surfaced, docs line breaks), both fixed in cc73b714630.
- Codex, blockers only, review on
618bff67c75: 1 P2 (a failed refresh right after a successful save shows the previous value). Not a blocker, deferred.
- Final fresh advisory by a clean-context agent, comment on
618bff67c75: READY, no blockers and nothing to cut. It independently checked authorization, audit, the migration, chatd row insertion and subagent inheritance, the tests, and soft-deleted organization handling, and agreed with every deferral. No code changes followed: the snapshot behavior it suggested documenting is already documented, and its docs wording note joins the deferred docs item.
- Codex, comment on
b4e76543df2 (the docs-only follow-up below): no major issues. Mike asked for a passing Codex review loop after item 5, so this review goes past the planned stop at the final advisory. No code changes followed.
- ethanndickson, review on
3850fbaa922: approved with 4 comments. Fixed 3: the audit target is now empty (91e77d3fa8c), the docs no longer re-explain audit logs (a0fb6891af5), and the organization instructions stories went from 9 to 5 (e836097f93f). Not fixed: the organization prompt read fails open on a database error, like the deployment prompt, and ethanndickson is changing both after merge (thread). UAT did not rerun for these changes.
Not counted as reviews: the pre-PR frontend self-review, simplify pass, and test audit (de8377e94e1), and a second test audit of de8377e94e1..cc73b714630 (pass with nits; the update-only test case was added after it).
Docs-only follow-up after the advisory, requested by Mike: b4e76543df2 adds audit log guidance for prompt changes to the platform controls page and an update-only custom role note to the organizations page. Codex reviewed it (item 6). No UAT covers it, and the code is unchanged since 618bff67c75. The deferred claim that the Instructions page path is outdated was wrong, so it's dropped. Item 7 removed the audit log guidance again; the custom role note stays.
Soft-deleted organizations
UAT found that a soft-deleted organization's prompt stays readable and writable by UUID. This is inherited behavior, not new exposure: ExtractOrganizationParam resolves UUIDs without a deleted filter, so the sibling organization chat routes (MCP servers, model overrides, models) behave the same. The same chat_model_config RBAC still applies, nobody gains access to another organization, and writes are audited.
Deferred (owner: Mike)
- A failed refresh right after a successful save shows the previous value with an error alert, so a further edit from that view starts from the old text (Codex round 4, UAT round 2). Trigger: reports of stale values after saving on unreliable networks.
- Update-only custom roles can save over the API, but the card stays hidden without read access. Trigger: a customer uses such a role.
- Soft-deleted organization access by UUID, above. Trigger: the platform starts rejecting deleted organizations in
ExtractOrganizationParam or purging their configuration.
- A contrived "code word" instruction was refused as possible prompt injection; neutral instructions work. Trigger: reports of ignored organization instructions.
- UX polish: there is no retry action after a failed first load, the save toast can cover Cancel, there is no unsaved-changes guard, the oversize error omits the limit, and whitespace-only text clears the prompt without notice. Trigger: the next settings UX pass.
- Docs: the 413 response and organization name paths are undocumented. Trigger: the next Coder Agents docs pass.
- Test audit nits: a redundant
waitFor and an optional read-only plus refetch story. Trigger: the next change to these tests.
Xum, an AI coding agent, implemented, tested, and opened this PR on behalf of @ibetitsmike.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
chatgpt-codex-connector[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Docs preview
Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Security and authorization review (review pass 2 of at most 6)
Reviewed commit: c42b5f9e05c3928e7e601639b62e757bb83b194a (base 15382ebd5dd). A clean-context reviewer read the diff and the existing deployment prompt implementation; it ran no tests.
Verdict: go with minor follow-ups. No P0, P1, or P2 findings.
P3 findings and disposition
- Site and organization auditors can read the organization instructions (GET checks read access to the organization's chat model configs), while reading the deployment system prompt requires deployment config update access. This is deliberate and covered by the enterprise test that expects an organization auditor to get 200, and audit diffs already show prompt text to auditors. The dbauthz comment calls the deployment prompt "admin-only" as the thing being matched, which is imprecise. Disposition: keep the access design and correct the comment wording in the next commit.
- Both handlers return
err.Error() in 500 response bodies. Disposition: declined, this matches the deployment prompt handlers and the existing pattern in coderd.
Checked with no findings
- Authorization: reads and writes are checked in the handler and again in dbauthz, scoped to the URL organization; members get 404 on GET and 403 on PUT; other organizations' users are stopped by organization extraction.
- Cross-organization isolation: chat creation and subagent spawn look up the prompt by the chat's own organization ID; no cache; organization deletion cascades the row.
- Precedence and input handling: the organization prompt is a separate system message after the deployment prompt and cannot replace it; sanitized on write and read; same size limits as the deployment prompt.
- Audit: resource type wired, denied writes audited without request content, no-op saves skipped.
- Database: one row per organization (primary key plus cascading foreign key), idempotent enum addition, per-organization advisory lock for writes.
- API, SDK, and UI: Swagger annotations present; the UI renders the field read-only and hides save controls without edit access; the server's 403 is the backstop.
Xum, an AI coding agent, ran this review on behalf of @ibetitsmike.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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: c42b5f9e05
ℹ️ 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".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Codex Review Summary
This comment shows the latest Codex review activity on this pull request.
| Review |
Status |
Commit |
Review trigger |
| 📝 Code Review |
✅ Completed 2026-10-06T05:07:39.492530Z |
006c495 |
Manual request |
ℹ️ 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" or "@codex security review".
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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: 58eab5603a
ℹ️ 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".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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: 618bff67c7
ℹ️ 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".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Final advisory (review pass 5 of at most 6)
Reviewed commit: 618bff67c757e1a308420dffa186d53b5c28917a (base 15382ebd5dd). A fresh clean-context agent received the goal, the final diff, the review history with dispositions, the test and CI results, the UAT verdicts, and the proposed deferred list, with no preferred conclusion. It ran no tests.
Recommendation: READY. No blockers, and nothing to cut or split.
Checked independently
- Server paths: GET requires read access to the organization's chat model configs and returns 404 otherwise. PUT audits denied attempts without request content, then requires update access, bounds and sanitizes the body, enforces the prompt size limit (128 KiB by default) after sanitizing, and writes under a per-organization advisory lock. The system-context read of the previous value runs only after the update check and only feeds the audit diff.
- dbauthz gates both new queries on the organization's chat model configs, and the chatd subject already has read access to them.
- Migration
000608 follows 000607 on main, adds the enum value idempotently, and cascades on organization delete.
- chatd stores a non-empty organization prompt as its own system row right after the deployment row. Subagents resolve the parent's organization when they spawn. A failed read logs a warning and keeps the deployment prompt, matching the deployment prompt's fail-open handling.
- The tests would fail if the authorization checks, the row insertion, or the organization scoping were removed.
- Soft-deleted organizations: confirmed as inherited.
ExtractOrganizationParam looks up UUIDs without a deleted filter, while name lookups exclude deleted organizations.
Taken from evidence, not re-verified: UAT verdicts and screenshots, frontend states, docs content, and the review history.
Non-blocking notes: err.Error() in 500 details matches the deployment handlers; chat creation and subagent spawn add one primary key read; re-sanitizing on read is redundant but harmless; the organization prompt is a snapshot taken at chat creation, which the docs should state. It agreed with every proposed deferral and suggested folding the docs wording fix into any further push before merge.
Disposition: no code changes, because rounds 4 to 6 address blockers only. The snapshot behavior is already documented (platform-controls/index.md and organizations.md). The docs wording stays in the deferred docs item because no further push is planned. No review follows this one.
Xum, an AI coding agent, ran this review on behalf of @ibetitsmike.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Codex Review: Didn't find any major issues. Nice work!
Reviewed commit: b4e76543df
ℹ️ 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".
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add a per-organization chat system prompt that organization admins can
set. New chats created in the organization, including subagents, get the
organization instructions after the deployment instructions. Existing
chats are not affected.
- Storage: chat_organization_system_prompts table (migration 000608),
queries, dbauthz checks, audit table entry.
- API: GET/PUT /api/v2/organizations/{organization}/chats/config/system-prompt
with invisible-character sanitization and the shared prompt length limit.
- chatd: resolve the organization prompt at chat creation and subagent
spawn.
- UI: Organization instructions card on the organization agent settings
page, read-only for viewers.
- Docs: platform controls, organizations, architecture, best practices.
… organization instructions expose no save action
…uctions in the prompt size limit
…ached prompt on refetch failure
Address Codex review findings: add a Loader during initial
prompt fetch (FE5), treat a background refetch error with cached
data as a non-blocking issue instead of replacing the form with an
error alert, and fix docs DOC1 and DOC6 violations.
Address Codex review round 3. Show a failed background refetch
inline above the cached organization instructions instead of hiding
it, so administrators know the value may be stale while their draft
stays editable. Cover the refetch path with a Vitest test and a
story, and make the read-only test assert only the unchanged value.
Also put each added docs sentence on its own source line.
Address Codex review round 1. The update handler read the previous
organization instructions for the audit diff with the caller's
context, so a custom role that grants chat_model_config update
without read returned 500. Read the previous value under a system
context after the explicit update check, as the organization model
override handler does, and cover the role in the authorization test.
…ntries and update-only roles
Comment on lines
+4397
to
+4400
|
|
// Fail open: the deployment prompt still applies.
|
|
|
p.logger.Warn(ctx, "failed to fetch organization chat system prompt, omitting it",
|
|
|
slog.F("organization_id", organizationID), slog.Error(err))
|
|
|
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, and leaving it as is in this PR, since you're taking it in a follow-up. It matches resolveDeploymentSystemPrompt just above, which also falls back on a database error, so CODAGT-1330 can change both together.
Xum, an AI coding agent, replied on behalf of @ibetitsmike.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Codex Review: Didn't find any major issues. Can't wait for the next one!
Reviewed commit: 006c495174
ℹ️ 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".
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
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.
|