Backend foundation for message-anchored comments - #1878
Open
simple-agent-manager[bot] wants to merge 4 commits into
Open
Backend foundation for message-anchored comments#1878simple-agent-manager[bot] wants to merge 4 commits into
simple-agent-manager[bot] wants to merge 4 commits into
Conversation
Contributor
|
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Builds the server-side foundation for SAM's message-anchored commenting MVP from idea
01M0JQB842XSJ3W172DYPB37HN.This is a constituent PR for a coordinated multi-PR effort. It intentionally does not deploy to staging and must not be merged by this PR; the parent integrator will combine it into the primary integration PR.
Scope delivered
032-message-comment-threadsforcomment_threads,comment_replies, andcomment_status_mutations.services/project-data.tswrappers./api/projects/:projectId/sessions/:sessionId/comments*with project membership/capability authorization.Out of scope by request: file comments, fuzzy file re-anchoring, mentions, reactions, notification inboxes, unrelated refactors, and actual agent prompt enqueueing for
sent.Exact HTTP contract
All routes require authenticated, approved users and are scoped by
projectIdthrough ProjectData. Reads require projecttask:read; writes require projecttask:write. HTTP writes derive the actor server-side from the authenticated user as{ kind: "human", id, name }.List threads
GET /api/projects/:projectId/sessions/:sessionId/commentsQuery params:
messageId?: string— when present, must exist in the same session/project.status?: "open" | "sent" | "resolved"afterSequence?: number— non-negative integer cursor.limit?: number— positive integer, clamped byCOMMENT_LIST_LIMIT_MAX.Response
200:Create thread
POST /api/projects/:projectId/sessions/:sessionId/commentsBody:
Response:
201for first write,200for idempotent replay.Create reply
POST /api/projects/:projectId/sessions/:sessionId/comments/:threadId/repliesBody:
Response:
201for first write,200for idempotent replay.Status transitions
POST /api/projects/:projectId/sessions/:sessionId/comments/:threadId/send->sentPOST /api/projects/:projectId/sessions/:sessionId/comments/:threadId/resolve->resolvedPOST /api/projects/:projectId/sessions/:sessionId/comments/:threadId/reopen->openBody:
Response
200:Error mapping
400validation failures, invalid status/query/body.404missing project/session/message/thread, including cross-session message anchors.409clientMutationIdreuse with a different mutation intent.422configured thread/reply/body/quote/idempotency limits exceeded.Exact shared model
Exact ProjectData RPC contract
Write RPCs are transactional inside the ProjectData DO. Service wrappers do not retry non-idempotent writes; clients should send
clientMutationIdfor optimistic retries.Exact WebSocket event contract
Project/session listeners on the existing ProjectData WebSocket route receive full authoritative thread payloads on first writes and real status changes:
Idempotent replays and no-op same-status updates do not rebroadcast.
Config contract
New env-backed defaults:
COMMENT_BODY_MAX_LENGTH=8000COMMENT_QUOTE_MAX_LENGTH=2000COMMENT_IDEMPOTENCY_KEY_MAX_LENGTH=200COMMENT_LIST_LIMIT_DEFAULT=100COMMENT_LIST_LIMIT_MAX=500COMMENT_THREADS_PER_SESSION_MAX=1000COMMENT_REPLIES_PER_THREAD_MAX=200Tests / validation
pnpm --filter @simple-agent-manager/shared buildpnpm --filter @simple-agent-manager/api typecheckpnpm --filter @simple-agent-manager/api test -- tests/unit/durable-objects/comments.test.ts tests/unit/durable-objects/project-data-comment-broadcast.test.ts tests/unit/routes/chat-comments.test.ts tests/unit/services/project-data-comments.test.tspnpm --filter @simple-agent-manager/api exec eslint src/durable-objects/project-data/comments.ts src/durable-objects/project-data/index.ts src/durable-objects/project-data/types.ts src/env.ts src/routes/chat.ts src/routes/chat-comments.ts src/schemas/comments.ts src/schemas/index.ts src/services/project-data.ts tests/unit/durable-objects/comments.test.ts tests/unit/durable-objects/project-data-comment-broadcast.test.ts tests/unit/routes/chat-comments.test.ts tests/unit/services/project-data-comments.test.tspnpm exec prettier --check .agents/skills/api-reference/SKILL.md .claude/skills/api-reference/SKILL.md apps/api/src/durable-objects/project-data/comments.ts apps/api/src/durable-objects/project-data/index.ts apps/api/src/durable-objects/project-data/types.ts apps/api/src/env.ts apps/api/src/routes/chat.ts apps/api/src/routes/chat-comments.ts apps/api/src/schemas/comments.ts apps/api/src/schemas/index.ts apps/api/src/services/project-data.ts apps/api/tests/unit/durable-objects/comments.test.ts apps/api/tests/unit/durable-objects/project-data-comment-broadcast.test.ts apps/api/tests/unit/routes/chat-comments.test.ts apps/api/tests/unit/services/project-data-comments.test.ts apps/www/src/content/docs/docs/reference/configuration.md packages/shared/src/constants/defaults.ts packages/shared/src/constants/index.ts packages/shared/src/types/comments.ts packages/shared/src/types/index.ts tasks/active/2026-08-21-message-anchored-commenting-backend.mdpnpm quality:do-migration-safetypnpm quality:source-contract-testspnpm quality:wrangler-bindingspnpm quality:type-boundariespnpm quality:file-sizesgit diff --checkStaging deployment: not run, per explicit instruction.
Specialist Review Evidence
.env.example, and docs entries; no hardcoded URLs/timeouts/identifiers added.quality:do-migration-safety; write RPCs use synchronous DO transactions and existing WebSocket fan-out.task:read/task:write; server derives human actor from auth; ProjectData rejects missing/cross-session message anchors and missing threads.COMMENT_*env vars are consistently named and present in Worker Env, ProjectData Env, Wrangler,.env.example, docs, and shared defaults.Contract assumptions for sibling PRs
{ kind: "message", messageId, quote }.sentis persisted/broadcast as a status only. This PR does not enqueue a prompt or perform agent delivery.Agent Preflight
Classifications:
External References
N/A: no external API documentation was needed; implementation sources were the SAM idea
01M0JQB842XSJ3W172DYPB37HN, prototype branch behavior, repository rules, and ProjectData code.Codebase Impact Analysis
Impacts
apps/apiProjectData migrations/storage/RPC/service/HTTP routes/tests,packages/sharedexported comment types/defaults,apps/wwwconfiguration docs, API reference skill docs, Wrangler/env examples, and the active task record undertasks/active.Documentation & Specs
Updated
.claude/skills/api-reference/SKILL.md,.agents/skills/api-reference/SKILL.md,apps/www/src/content/docs/docs/reference/configuration.md,apps/api/.env.example,apps/api/wrangler.toml, shared exported types/defaults, and the task file with validation/specialist evidence.Constitution & Risk Check
Checked Principle XI no-hardcoded-values with env-backed comment limits, append-only ProjectData migration safety, tenant/IDOR authorization, bounded writes, idempotency conflict handling, and WebSocket event convergence without client-authored state trust.