You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Documents, Todolists, Schedule entries are genuine replace — these three keep the triad.
Blocked on five contract/modeling questions documented in that comment (see also the follow-up correction: blockers 4 and 5 are read-modeling gaps, not blockers). One is a live SDK-reachable data-loss bug — ScheduleEntry's unconditional replace_participants wipes every participant on any update omitting participant_ids — and one is an active corruption trap: ScheduleEntry's writable :url collides with the recording's API url on read-back.
🤖 Drafted with agent assistance; filed by @jeremy.
Context
#372 fixed the partial-PUT-against-replace-semantics data-loss bug for todos: the spec operation was renamed to ReplaceTodo (content required, x-basecamp-write-semantics: {mode: replace, clearsOmitted: true}), and every SDK gained the three-method surface — merge-safe update (GET → overlay set fields → full PUT), edit (read-modify-write closure), and verbatim replace.
Sibling recordable endpoints share the same server contract (full replace, omission clears) and today have the same defect shape: typed partial-update surfaces transmitting sparse PUTs.
Scope
Audit and convert, using todos as the template (spec rename + @basecampWriteSemantics + generator grouping + per-language extension + conformance fixtures):
Messages (UpdateMessage)
Documents (UpdateDocument)
Cards (UpdateCard)
Todolists (UpdateTodolistOrGroup)
Schedule entries (UpdateScheduleEntry)
Each one needs the same verification as todos: confirm the server contract from BC3 controllers/docs (which fields are writable, which are required), then encode it in the behavior model and update-merge / edit-clear / replace-omission-clears conformance cases.
Template
The todos implementation to copy from:
Spec: ReplaceTodo in spec/basecamp.smithy + basecampWriteSemantics trait
Per-language: Go todos.go (shared replace transport + full-state vs sparse builders), TS services/todos-extensions.ts, Python services/todos.py (context-manager edit), Ruby services/todos_extensions.rb (prepend via zeitwerk on_load), Kotlin services/TodosService.kt (open generated class + accessor override), Swift TodosServiceExtensions.swift
🤖 Drafted with agent assistance; filed by @jeremy.
Context
#372 fixed the partial-PUT-against-replace-semantics data-loss bug for todos: the spec operation was renamed to
ReplaceTodo(contentrequired,x-basecamp-write-semantics: {mode: replace, clearsOmitted: true}), and every SDK gained the three-method surface — merge-safeupdate(GET → overlay set fields → full PUT),edit(read-modify-write closure), and verbatimreplace.Sibling recordable endpoints share the same server contract (full replace, omission clears) and today have the same defect shape: typed partial-update surfaces transmitting sparse PUTs.
Scope
Audit and convert, using todos as the template (spec rename +
@basecampWriteSemantics+ generator grouping + per-language extension + conformance fixtures):UpdateMessage)UpdateDocument)UpdateCard)UpdateTodolistOrGroup)UpdateScheduleEntry)Each one needs the same verification as todos: confirm the server contract from BC3 controllers/docs (which fields are writable, which are required), then encode it in the behavior model and
update-merge/edit-clear/replace-omission-clearsconformance cases.Template
The todos implementation to copy from:
ReplaceTodoinspec/basecamp.smithy+basecampWriteSemanticstraittodos.go(shared replace transport + full-state vs sparse builders), TSservices/todos-extensions.ts, Pythonservices/todos.py(context-manager edit), Rubyservices/todos_extensions.rb(prepend via zeitwerk on_load), Kotlinservices/TodosService.kt(open generated class + accessor override), SwiftTodosServiceExtensions.swiftconformance/tests/todos_write.json+requestMethod/requestBody/requestBodyAbsentassertionsRelated