Skip to content

Schedules: the carve-out seeds ARE guarded; correct the Ruby comment denying it - #636

Merged
jeremy merged 1 commit into
mainfrom
docs/ruby-schedules-merge-safe-comment
Aug 4, 2026
Merged

jeremy merged 1 commit into
mainfrom
docs/ruby-schedules-merge-safe-comment

Conversation

@jeremy

@jeremy jeremy commented Aug 4, 2026 •

Copy link
Copy Markdown
Member

fields_from_entry's docstring told the reader that highlighted is unguarded — one line above the guard that reads it:

+highlighted+ is taken verbatim: it is optional, absent from the reduced calendar partial +GetUpcomingSchedule+ renders, and — unlike every other member — cannot reach the wire unless the caller assigns it, so there is nothing to refuse a malformed value on behalf of.

highlighted: MergeSafe.writable_boolean(body, "highlighted", record: RECORD, escape: ESCAPE_HATCH)

writable_boolean deliberately refuses a wrong-typed highlighted before 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

  • "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 exactly the same reason.
  • The inference — "reaches the wire only when addressed" is not "never reaches the wire." Dirty tracking is by setter invocation, deliberately (module docs, 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_value asserts 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_seeds docstring says "the values are still guarded, because entry.url = entry.url is a legitimate write and would otherwise carry a malformed value into the PUT." The Ruby comment now states that 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.

The general point

Asked to check whether the sibling carve-out comments make the same claim: within Ruby they do not. url (seeded from join_url, never from url), participant_ids and notify ("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: url and participantIds are 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) at ad9a33bd4, PRE_SHA == POST_SHA == 017a79016:

No drift detected.
1358 runs, 30434 assertions, 0 failures, 0 errors, 0 skips
151 files inspected, no offenses detected
==> Ruby SDK checks passed

Summary by cubic

Corrected Ruby comments in fields_from_entry to state that carve-out seeds (highlighted, url, participant_ids) are guarded, removing the false “taken verbatim” claim. Clarifies highlighted is 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.

Review in cubic

…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.
Copilot AI balanced review requested due to automatic review settings August 4, 2026 04:06
@jeremy jeremy added the documentation Improvements or additions to documentation label Aug 4, 2026
@github-actions github-actions Bot added the ruby Pull requests that update the Ruby SDK label Aug 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 highlighted with the "optional boolean guard" explanation, noting a "yes" or 1 is 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.

@jeremy
jeremy merged commit c95d81c into main Aug 4, 2026
44 checks passed
@jeremy
jeremy deleted the docs/ruby-schedules-merge-safe-comment branch August 4, 2026 04:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation ruby Pull requests that update the Ruby SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants