GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat: add get, list and delete routes for chat automations by ThomasK33 · Pull Request #32079 · coder/coder

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Nov 12, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Chat automations send a saved prompt to a chat from a webhook or a schedule (RFC: Automations for Coder Agents). This PR adds the routes that read and delete them, behind the chat-automations experiment, so that create, the scheduler and the webhook endpoint can follow in small PRs. Part of CODAGT-1135.

Stacked on #32067 and #32063 through the base branch tk/automations-base-api-read, which holds both. Review only this diff. This PR is retargeted to main when both are merged.

What changed

  • Three routes under /api/experimental/organizations/{organization}/chats/automations: list (with ?owner=me, a user ID or a username), get, and delete. A middleware answers 404 when the experiment is off for the caller, and when the experiment rules cannot be read.
  • Access follows the RFC role table. A member with agents-access reads and deletes their own automations. Organization administrators and deployment owners read and delete every automation in the organization. The list filters rows in SQL. A caller who can read an automation but not delete it gets 403 on delete. A caller who cannot read it, or who uses the wrong organization in the path, gets 404. An API key with an external scope gets 404 on get and delete, and on list either 200 [] or, when it cannot read the organization, 404.
  • codersdk.ChatAutomation is the response type, built by explicit converters. It has no secret field, only webhook_secret_version, and get and list never copy the stored secret. A chat title appears only when the caller can read that chat. An owner appears only when the caller can read that user, and a ?owner= username that names a user the caller cannot read gives 200 []. next_run_times holds up to five upcoming runs of an enabled schedule.
  • chatautomation.Delete takes the automation's advisory lock, re-reads the row as the caller, and deletes it in one transaction. It is the one function that the later API and agent tool paths call.
  • ChatAutomation is audited for delete. prompt and webhook_secret are masked secret fields. ResourceTypeChatAutomation loses its "retained for audit logs" comment, which is no longer true, so gofmt re-aligns the constant block.
  • Two queries that the routes need: GetChatsByIDs (chat titles for a page of rows) and GetChatIDsWithQueuedMessagesByAutomationID (the delete check), both with dbauthz checks.

Suggested reading order: coderd/chatautomations.go, coderd/x/chatd/chatautomation/delete.go, coderd/database/db2sdk/chatautomation.go, codersdk/chatautomations.go, then the tests. The rest is generated code and docs.

Scope

  • Not in this PR: create, update, secret rotation, the run path, the webhook endpoint, the scheduler and the agent tool. No code writes chat_queued_messages.automation_id yet.
  • With the experiment off, which is the default, the routes answer 404 and nothing else changes. The experiment that chore!: remove the chat automations experiment #30412 removed was never in a tagged release, so a leftover --experiments=chat-automations flag exists only on dev or dogfood deployments, and those turn these routes on.
  • Two replicas on different versions during an upgrade: no case exists. A replica without this PR has none of the routes and answers 404, as the gate does. A replica ignores a stored rule for an experiment that it does not know.

Tradeoffs

  • Delete refuses while a queued message names the automation. Nothing writes such a message before the publish PR, which replaces the refusal with the queue cleanup. The refusal is a generic 500 with an empty detail and the cause in a log field, and nothing is deleted.
  • The list has no pagination, as in the RFC. An organization administrator's list holds every automation of the organization (members times the per-owner cap that the create PR adds), and each row carries its prompt, up to MaxPromptBytes.
  • The response has three fields beyond the RFC example: new_chat_model_config_id, project_id and reasoning_effort, named as in the create request. The RFC says PATCH "takes the same fields as create", so an editor must be able to read them. paused_reasons is always [] until the run path exists, and there is no field for the count of skipped and refused runs: that field arrives with its writer.
  • The audit action map for ChatAutomation lists only delete. The generated audit log page lists every action in the map, and nothing emits create or write yet. Later PRs add the actions they emit.
  • The RFC says "Custom roles can grant any chat_automation action." The custom role API lets an actor grant only the permissions that the actor holds (customRoleEscalationCheck), and no built-in role holds create. This PR adds no create route and keeps the role table: a custom role with read and delete deletes, one with read only gets 403, and one with delete and without read gets 404 and deletes nothing, because the delete re-reads the row with read.

Live check

On a local enterprise build with its own PostgreSQL, two users, and the experiment on for one of them: list, get, delete, a repeat delete (404) and a delete refused by a queued message (500, nothing deleted) behaved as described, the user with the experiment off got 404 on all three routes, the delete wrote one audit entry with the prompt masked, and a canary secret and prompt appeared 0 times in the audit log, the server log and the PostgreSQL log (the secret also 0 times in every response).


Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
ThomasK33 added 22 commits November 12, 2026 06:31
@ThomasK33
feat(coderd/audit): audit chat automations
28548fe
Mark database.ChatAutomation as an Auditable, with the target name and ID,
the organization requirement, and the audit table. webhook_secret and
prompt are ActionSecret, so an entry shows that they changed and never
their value.
@ThomasK33
docs: regenerate the audit log fields for chat automations
68b1321
@ThomasK33
test(coderd/database): cover GetChatsByIDs
96b3b3e
@ThomasK33
feat(coderd/database): add the queries that deleting a chat automatio…
b579722
…n needs

GetChatsByIDs reads the chats whose titles a response shows.
GetChatIDsWithQueuedMessagesByAutomationID and
DeleteChatQueuedMessagesByAutomationID let a delete lock the chats that hold
queued messages of the automation before it removes them.
@ThomasK33
feat(coderd): add get, list and delete routes for chat automations
caf74b1
The routes sit under /api/experimental/organizations/{organization}/chats/automations
behind the chat-automations experiment, which is evaluated for the caller and
answers 404 when off. The response type has no webhook secret field. Delete
locks the automation, then each chat that holds a queued message of it in chat
ID order like a chat transition, then removes the queued messages and the row.
@ThomasK33
docs(coderd/x/chatd): describe the delete of a chat automation queue
0ff268f
ARCHITECTURE.md prose was drafted by an agent at the user's request; the user
will review it.
@ThomasK33
fix(coderd): leave the cause out of a chat automation 5xx body
22ee326
The request logger logs the response body of a 5xx, so the handlers write the
message only and log the error.
@ThomasK33
fix(coderd): mark the get handler for revive
d13953b
@ThomasK33
test(coderd/x/chatd/chatautomation): cover the lock order of a chat a…
c11d52b
…utomation delete
@ThomasK33
docs(coderd/x/chatd/chatautomation): correct the reason for the chatd…
a5fbc07
… context
@ThomasK33
test(coderd): cover the chat automation get, list and delete routes
e834804
@ThomasK33
test(enterprise/coderd): cover the audit entry of a chat automation d…
115352e
…elete
@ThomasK33
test(coderd): trim the chat automation tests
9751020
Cut test rows, phases and helpers that no product mutant separates,
merge the two lock-order subtests into one test, and replace the
expected-value builder of the response test with targeted assertions.
Add TestChatAutomationsInternalError: a 500 from list, get or delete
carries a message and no detail, and the response body never holds the
cause.
@ThomasK33
test(coderd): cover the gate when the experiment rules cannot be read
340bb42
@ThomasK33
test(coderd): seed a fixed last run time in the chat automation respo…
c3cd378
…nse test
@ThomasK33
fix(enterprise/audit): list only the delete action of a chat automation
352408d
This PR audits only the delete. A later PR adds the action that it audits,
so that the audit log page never lists an action that nothing emits.
@ThomasK33
fix(coderd): answer 403 to a delete that the caller may not make
2b6c22e
A role that can read a chat automation and cannot delete it got 404. The
chat project routes answer 403 in that case. Also correct the comments that
the review found false or unclear, and the ARCHITECTURE.md bullet.
@ThomasK33
test(coderd): set the experiment rule through the SDK
48ed32f
@ThomasK33
fix(coderd/x/chatd/chatautomation): refuse a delete while a queued me…
fd29e3c
…ssage names the automation

Delete no longer removes queued messages. Nothing writes automation_id on a
queued row before the run path exists, and how a delete leaves a chat's queue
is a chat state decision that belongs with that path. Delete takes the
automation lock, re-reads the automation and refuses with ErrQueuedMessages
when a queued message names it. The handler answers a generic 500.
@ThomasK33
docs(coderd/x/chatd): drop the delete of a chat automation queue from…
58055c8
… the architecture
@ThomasK33
refactor(coderd/database): drop the query that deletes the queued mes…
ede693e
…sages of an automation

Delete refuses a queued message instead of removing it, so nothing calls the
query. GetChatIDsWithQueuedMessagesByAutomationID stays: Delete uses it for the
refusal.
@ThomasK33
docs(codersdk): drop the queued messages from the delete method comment
3e06f69
@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@linear-code

linear-code Bot commented Nov 12, 2026

Copy link
Copy Markdown

CODAGT-1135

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex security review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot assigned ThomasK33 Nov 12, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T15:02:21.795768Z a52fa51 Manual request
🔒 Security Review ✅ Completed 2026-11-12T15:04:17.123719Z a52fa51 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.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 3e06f69bb3

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

chatgpt-codex-connector[bot]
chatgpt-codex-connector Bot reviewed Nov 12, 2026
View reviewed changes

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

Copy link
Copy Markdown

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: 3e06f69bb3

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

All reactions
Comment thread coderd/chatautomations.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/chatautomations.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33
fix(coderd): read only the canonical form of a user ID in the chat au…
11cb0ba
…tomation owner filter

uuid.Parse also accepts 32 hexadecimal characters, which is a valid username,
and the braces and urn:uuid: forms. The owner filter took each of them for a
user ID. It now takes the ID branch only for the 36-character form with
hyphens, and looks up every other value as a username.
ThomasK33 added 6 commits November 12, 2026 10:32
@ThomasK33
fix: satisfy the fmt and lint checks of the chat automation PR
e259b06
Remove the blank line between the cdr.dev and github.com/coder import groups,
and read the audit log in the enterprise test as an auditor instead of the
owner.
@ThomasK33
test(coderd): cover the 403 of a delete by a role that can read and n…
5a9deea
…ot delete
@ThomasK33
test(coderd): cover a username filter that names a user the caller ca…
58e8054
…nnot read
@ThomasK33
fix(coderd): show each owner of a chat automation that the caller can…
8059849
… read

The batch read of the owners is all or nothing, so a caller who could read
some owners and not others saw no owner on any row. When the batch is not
authorized, read the owners one by one and leave out only those that the
caller cannot read.
@ThomasK33
docs(coderd/x/chatd/chatautomation): name the one path that takes no …
a3f6aea
…automation lock
@ThomasK33
test(enterprise/coderd): drop the audit entry test that the coderd te…
a52fa51
…sts already cover

No mutant of the product code turns only this test red. The coderd lifecycle test
fails when the entry is missing, the unit tests cover the resource type, target
and masking, and the lifecycle test now also checks the organization ID.
@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ThomasK33

ThomasK33 commented Nov 12, 2026

Copy link
Copy Markdown
Member Author

@codex security review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: a52fa51012

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: a52fa51012

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@chatgpt-codex-connector chatgpt-codex-connector[bot] chatgpt-codex-connector[bot] left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@ThomasK33 ThomasK33

Labels

None yet

Projects

None yet

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.

1 participant

@ThomasK33
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.