feat(coderd/database): add chat_context_resources table#26430
Conversation
Add chat_context_resources: a per-chat pinned copy of the agent context resources a chat is hydrated against. The agent-side table (workspace_agent_context_resources) is last-writer-wins and keeps no history, so a chat takes its own copy at hydration and context refresh to keep a stable view of its pinned resources while the agent drifts. This is the schema foundation only. The copy/list queries, prepareGeneration wiring, and SDK/frontend exposure land in follow-up changes. - Mirrors workspace_agent_context_resources columns and reuses its enum types (workspace_agent_context_body_kind, workspace_agent_context_resource_status); the down migration leaves those types in place since 000522 owns them. - chat_id uuid NOT NULL REFERENCES chats(id) ON DELETE CASCADE for retention/cleanup parity with other chat-scoped tables. No agent FK so the pin survives agent replacement and workspace rebuilds. - PK (chat_id, source).
|
/coder-agents-review |
|
Chat: Review posted | View chat Review historydeep-review v0.7.1 | Round 2 | Last posted: Round 2, 4 findings (1 P3, 2 Nit, 1 Note), APPROVE. Review Finding inventoryFindings
Round logRound 1Panel. 1 P3, 2 Nit, 1 Note new. 1 dropped (cross-table inconsistency). Reviewed against bca0ce0..4b84e39. Round 2Panel. CRF-1, CRF-3, CRF-4, CRF-5 all addressed. 0 new findings. Reviewed against bca0ce0..3b483ea. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
Clean, well-documented schema foundation. The table design is sound: composite PK mirrors the source table, CASCADE follows the chat child table convention, the intentional absence of an agent FK is correct for survivability, and enum reuse avoids type duplication. Pariston explored four alternative framings (versioned agent resources, inline JSONB, derive-on-demand) and couldn't build a case against the copy-table approach. Hisoka probed PK collision potential and CASCADE chains with no findings. Knuckle confirmed the schema, fixture, and generated code are all consistent.
Severity count: 1 P3, 2 Nit, 1 Note. No blocking issues.
"Boring, correct DDL." — Hisoka
coderd/database/queries/chats.sql:32
Nit [CRF-4] This comment enumerates cascaded child tables but the list is stale. It says "Related chat_messages, chat_diff_statuses, and chat_queued_messages are removed via ON DELETE CASCADE" but was already missing chat_debug_runs, chat_debug_steps, chat_file_links, and chat_heartbeats. This PR adds chat_context_resources, widening the gap.
A partial list is worse than no list because it implies completeness. Either enumerate all cascaded tables or replace with: "All chat-scoped child tables are removed via ON DELETE CASCADE."
Not introduced by this PR, but widened by it. (Knuckle)
🤖
In reply to IC_kwDOGkVX1s8AAAABGXgOGQ:
Nit [CRF-5] Three emdashes (U+2014) in the PR description body. Project convention (AGENTS.md) bans emdash/endash in documentation, and PR descriptions count. Occurrences: (1) after the enum type list, (2) after the test command, (3) in the cleanup parity paragraph. Replace with periods or semicolons. The commit message and all SQL comments are clean. (Leorio, Mafu-san)
🤖
🤖 This review was automatically generated with Coder Agents.
- Condense the migration header comment to defer table semantics to COMMENT ON TABLE, keeping only the migration-specific notes (no agent FK rationale, enum reuse from 000522). [CRF-1] - Reword the fixture comment to "non-reserved body kind" instead of the undefined "v1 body kind" shorthand. [CRF-3] - Replace the stale partial cascade list in DeleteOldChats with "All chat-scoped child tables are removed via ON DELETE CASCADE". [CRF-4]
|
Addressed the Round 1 findings in 3b483ea:
Coder Agents, on behalf of @kylecarbs |
|
/coder-agents-review |
There was a problem hiding this comment.
All R1 findings addressed in 3b483ea. CRF-1 header condensed (verified by Gon, Razor, Pariston). CRF-3 "v1" reworded to "non-reserved" (verified by Gon, Razor). CRF-4 stale cascade list generalized to future-proof phrasing (verified by Razor against all 8 child table FKs). CRF-5 emdashes removed from PR description. No new findings from the R2 panel (7 reviewers).
"The agent fixed the class, not just the instance." — Mafu-san, on the CRF-4 fix
🤖 This review was automatically generated with Coder Agents.
…t-resources-table
…0525 000524 was taken by 000524_aibridge_token_usage_cost after merging the latest main. Renumbered the migration and its fixture from 000524 to 000525; regeneration confirms no schema drift and the migration tests pass against the merged set.
What
Adds the
chat_context_resourcestable: a per-chat pinned copy of the agent context resources a chat is hydrated against.The agent-side table
workspace_agent_context_resourcesis last-writer-wins (overwritten on everyPushContextState, no history). For a chat to keep a stable view of the resources it was pinned to while the agent drifts, it must take its own copy at hydration / context refresh. This PR is the schema foundation only.Schema
workspace_agent_context_resourcescolumns and reuses its enum types (workspace_agent_context_body_kind,workspace_agent_context_resource_status). The down migration leaves those types in place since000522owns them.chat_id uuid NOT NULL REFERENCES chats(id) ON DELETE CASCADEfor retention / cleanup parity with the other chat-scoped tables. No agent FK so the pin survives agent replacement and workspace rebuilds.(chat_id, source).dump.sql,models.go, and the FK/unique constraint enumerations viamake gen. No queries, dbauthz, or audit entries yet (agent-derived copy; same precedent as the agent context tables andboundary_logs).000519) rather than hard-coding a chat id.Out of scope (follow-ups)
prepareGenerationconsuming pinned instructions + skills (gated on a newchat-context-sourcesexperiment).codersdk.ChatContext(resources + changed diff) and the frontend indicator/refresh.last_injected_context.Testing
make genclean (no drift beyond this table).go test ./coderd/database/migrations/...:TestMigrate,TestMigrateUpWithFixtures(fixture + up/down round trip),TestCheckLatestVersion.TestAuditableResourcespasses without an audit entry.make pre-commitgreen.Decision log
Dedicated table (Option A) over reusing
chat_messagesparts. Messagecontext-file/skillparts get compacted away and re-derived (ReloadMessages); a dedicated table is compaction-immune and later powers the SDKresourcesview. Heavy content (can reach ~2 MiB) also stays off the hotchatsrow (list/watch paths), unlike a jsonb column.Cleanup parity. All chat-scoped child tables (
chat_messages,chat_debug_runs/steps,chat_diff_statuses,chat_file_links,chat_heartbeats,chat_queued_messages) usechat_id ... ON DELETE CASCADE. dbpurgepurgeChatsInTxcallsDeleteOldChats, which cascades to children, so CASCADE alone covers retention purge; no separate purge query needed.No agent FK. The pin must outlive the agent that produced it (agent replacement / workspace rebuild), so there is intentionally no FK to
workspace_agents.This PR was created by Coder Agents on behalf of @kylecarbs.