Schedules: the carve-out seeds ARE guarded; correct the Ruby comment denying it - #636
Conversation
…ng it fields_from_entry's docstring said +highlighted+ "is taken verbatim" and "cannot reach the wire unless the caller assigns it, so there is nothing to refuse a malformed value on behalf of." The very next expression reads it through MergeSafe.writable_boolean, which refuses a non-boolean before the PUT. The code is right and the comment contradicted it. Three things were wrong: * "taken verbatim" — it is not; writable_boolean admits absent/nil as false and refuses "yes" or 1 rather than coercing them. * "unlike every other member" — participant_ids and url are carve-outs too, read through writable_id_list and writable_string for the same reason. * the inference itself — "reaches the wire only when addressed" is not "never reaches the wire". Dirty tracking is by setter invocation, deliberately, so assigning a seed straight back is an address and sends whatever the seed held (test_edit_entry_sends_a_carve_out_assigned_its_own_read_back_value). And a block that only inspects a corrupt seed still decides on garbage. That is already the stated rationale for the other two seeds — the schedules test's "a block inspecting a corrupt value would decide on garbage", and Python's _carve_out_seeds docstring, "the values are still guarded, because entry.url = entry.url is a legitimate write". The Ruby comment now says the same thing for all three, and gives +highlighted+ its real justification: the member is optional because the reduced calendar partial behind GetUpcomingSchedule omits it, so absence is genuinely "not highlighted" — the wrong type still is not. Comments only. The sibling comments for url, participant_ids and notify make no such claim and are unchanged.
There was a problem hiding this comment.
Pull request overview
This PR corrects a documentation comment in Ruby's fields_from_entry (the private helper backing the merge-safe update_entry/edit_entry schedule composites). The prior comment claimed highlighted was "taken verbatim" and, "unlike every other member," could not reach the wire unless assigned — asserting there was "nothing to refuse a malformed value on behalf of." That contradicted the code one line below, which guards highlighted with MergeSafe.writable_boolean. The revised comment explains that all three carve-outs (highlighted, url, participant_ids) are guarded because dirty tracking is by setter invocation, and gives highlighted its correct justification: it is optional (absent from the reduced calendar partial GetUpcomingSchedule renders) but still type-checked.
Changes:
- Rewrote the carve-out seeding note to state that seeding puts nothing on the wire yet the values are still guarded, since assigning a seed back (
entry.url = entry.url) is a legitimate write. - Replaced the incorrect "taken verbatim" account of
highlightedwith the "optional boolean guard" explanation, noting a"yes"or1is refused rather than coerced.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fields_from_entry's docstring told the reader thathighlightedis unguarded — one line above the guard that reads it:writable_booleandeliberately refuses a wrong-typedhighlightedbefore the full-replace PUT. The code is right; the comment contradicted it. A valid review finding on #632 that shipped inside a suppressed-comment block.Three things were wrong
writable_booleanadmits absent/nil asfalseand refuses"yes"or1rather than coercing them.participant_idsandurlare carve-outs too, read throughwritable_id_listandwritable_stringfor exactly the same reason.ScheduleEntryFields), so assigning a seed straight back is an address like any other and sends whatever the seed held.test_edit_entry_sends_a_carve_out_assigned_its_own_read_back_valueasserts precisely that. And a block that only inspects a corrupt seed still decides on garbage.The corrected text
The right account already existed for the other two seeds — the schedules test says "a block inspecting a corrupt value would decide on garbage", and Python's
_carve_out_seedsdocstring says "the values are still guarded, becauseentry.url = entry.urlis a legitimate write and would otherwise carry a malformed value into the PUT." The Ruby comment now states that for all three, and giveshighlightedits real justification: the member is optional because the reduced calendar partial behindGetUpcomingScheduleomits it, so absence is genuinely "not highlighted" — the wrong type still is not.The general point
Asked to check whether the sibling carve-out comments make the same claim: within Ruby they do not.
url(seeded fromjoin_url, never fromurl),participant_idsandnotify("nothing in the response seeds a directive") are all accurate and unchanged. TypeScript and Python are correct too.One copy of the same sentence lives outside this PR's scope, verbatim, in
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/services/SchedulesService.kt:317-322. Kotlin's"taken verbatim"is accurate there — kotlinx.serialization is the typed decoder, so no hand-written guard is needed — but the stated reason ("cannot reach the wire unless the caller assigns it") is the same wrong one, and "unlike every other member" is wrong there too:urlandparticipantIdsare carve-outs with the same setter-based dirty tracking. Left for a follow-up rather than widening a Ruby-comments PR into a Kotlin build.Scope and verification
Ruby comments only — no spec, no generated files, no behaviour.
make rb-check(drift + tests + rubocop) atad9a33bd4,PRE_SHA == POST_SHA == 017a79016:Summary by cubic
Corrected Ruby comments in
fields_from_entryto state that carve-out seeds (highlighted,url,participant_ids) are guarded, removing the false “taken verbatim” claim. Clarifieshighlightedis optional yet type-checked and notes setter-based dirty tracking; comments only, no behavior changes.Written for commit ad9a33b. Summary will update on new commits.