Skip to content

BC5 readiness: forward-compat spec, briefs, parity lint#293

Open
jeremy wants to merge 11 commits into
mainfrom
bc5-readiness-spec-foundations
Open

BC5 readiness: forward-compat spec, briefs, parity lint#293
jeremy wants to merge 11 commits into
mainfrom
bc5-readiness-spec-foundations

Conversation

@jeremy
Copy link
Copy Markdown
Member

@jeremy jeremy commented May 1, 2026

Summary

Foundation PR for BC5 release readiness. Additive across the board — no behavior changes, no breaking renames.

  • Forward-compat Smithy additions for BC5 read paths on existing operations:
    • Notification gains bubble_up_url, bubble_up_at
    • GetMyNotificationsOutput gains bubble_ups, scheduled_bubble_ups
    • Person gains tagline (alias of bio)
    • Todo gains steps (reuses existing CardStep shape)
    • Todoset gains todos_count, completed_loose_todos_count, todos_url, app_todos_url
    • memories member documented as observed-current behavior pending BC team's back-compat decision
  • Parallel BC4/BC5 provenance: spec/api-provenance.json restructured. .bc3 tracks the active branch (five), .compatibility.bc3-master keeps the BC4 baseline. Existing tooling reads the same .bc3 keys and works unchanged.
  • make generate aggregator runs Smithy build, behavior model, URL routes, provenance sync, and per-language SDKs in dependency order.
  • make check-bucket-flat-parity flags bucket-scoped GET list operations without flat counterparts. Initial allowlist seeded with webhooks (legitimately per-project).
  • Branch-aware make sync-status reports drift for the active branch and the BC4 compatibility branch as two clearly-labeled blocks.
  • API gap registry at spec/api-gaps/ — 11 entries aligned with the BC3 parity plan's Phase 3 deliverables, plus COORDINATION.md describing the SDK ↔ BC3 plan relationship and the absorption lifecycle.
  • make validate-api-gaps validates frontmatter and required body sections (Ruby stdlib only, no gem deps).

The api-gap registry is durable: each entry transitions through a documented lifecycle (no-json-contractaddressed-in-bc3-pr-Nabsorbed-in-sdk) with status changes flowing through git history. Living next to basecamp.smithy in spec/ makes the spec-ecosystem mental model explicit — entries describe expected future spec state and link back to Smithy structures on absorption.

Commit structure

  1. spec(bc5) — Smithy additions + provenance restructure + parity-lint allowlist seed
  2. build(make) — generate aggregator + parity lint + branch-aware sync-status + validator make-target
  3. docs(api-gaps) — API gap registry + COORDINATION.md + validator + CONTRIBUTING updates
    4-9. One commit per SDK (ts, ruby, python, kotlin, swift, go) for regenerated artifacts

Cross-team contract decisions (called out in COORDINATION.md)

Two items the SDK canary will surface that need BC team resolution before release:

  • memories: [] on BC5 — back-compat or accept-and-document.
  • Longstanding app_todoslists_url typo — server fix, alias period, or SDK accommodation.

Test plan

  • make smithy-check, make behavior-model-check, make provenance-check, make sync-spec-version-check, make sync-api-version-check
  • make go-check-drift, make kt-check-drift, make py-check-drift, make auth-routable-check
  • make ts-check, make rb-check, make py-check, make kt-check, make swift-check, make go-check
  • make conformance-{go,kotlin,typescript,ruby,python}
  • make check-bucket-flat-parity (1 bucket-scoped list op, allowlisted)
  • make validate-api-gaps (11 entries + allowlist, clean)
  • make sync-status reports both .bc3 and .compatibility.bc3-master blocks
  • bash scripts/validate-api-gaps.sh passes from a clean shell (env -i ..., ruby --disable-gems ...)
  • make lint-actions

What this PR is NOT

This PR is the foundation. It does not include:

  • The TS canonical wire-capture canary (PR 2, stacked on this one)
  • Cross-language wire-replay decoders (PR 3)
  • Pairwise BC4↔BC5 comparison + check-bc5-compat orchestrator (PR 4)
  • API gap detector tooling (PR 5)
  • New SDK services for any registered gap — those land per-entry as BC3 ships each Phase 3 deliverable

Copilot AI review requested due to automatic review settings May 1, 2026 21:58
@github-actions github-actions Bot added documentation Improvements or additions to documentation typescript Pull requests that update TypeScript code ruby Pull requests that update the Ruby SDK go kotlin swift spec Changes to the Smithy spec or OpenAPI labels May 1, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Spec Change Impact

  • Added: Forward-compatibility specifications, briefs, and parity lint rules.

  • Modified: Existing specifications updated for BC5 readiness with no noted field removals.

  • Removed: No operations, types, or resources removed.

  • SDKs requiring regeneration: All SDKs need to be regenerated to incorporate these changes.

  • Breaking change: No breaking API changes identified.

Checklist of SDKs needing updates:

  • Go
  • TypeScript
  • Ruby
  • Kotlin
  • Swift

@github-actions github-actions Bot added enhancement New feature or request and removed documentation Improvements or additions to documentation labels May 1, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Foundation work to prepare the SDK repo for BC5 readiness: additive Smithy/OpenAPI model updates, new repo-level spec/brief validation tooling, and regenerated multi-language SDK artifacts pinned to the updated API version.

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.

Changes:

  • Add BC5 forward-compat fields to the Smithy spec (notifications bubble-up fields, todo steps, todoset counts/URLs, person tagline) and regenerate OpenAPI + SDK model artifacts.
  • Introduce repo lints/utilities: bucket↔flat parity check, API gap brief validator, and branch-aware BC3 drift reporting wired into make check/make sync-status.
  • Add and validate API gap briefs + allowlist schema/docs, and add make generate as a full regeneration aggregator.

Reviewed changes

Copilot reviewed 34 out of 50 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
typescript/src/generated/schema.d.ts Generated TS schema typings updated for new BC5 fields + descriptions.
typescript/src/generated/openapi-stripped.json Generated stripped OpenAPI updated (version + new schema fields/docs).
typescript/src/generated/metadata.json Regeneration timestamp update.
typescript/src/client.ts Bump TS SDK API_VERSION to 2026-05-01.
swift/Sources/Basecamp/Generated/Models/Todoset.swift Generated Swift model updated with new todoset fields.
swift/Sources/Basecamp/Generated/Models/Todo.swift Generated Swift model updated with embedded steps.
swift/Sources/Basecamp/Generated/Models/Person.swift Generated Swift model updated with tagline.
swift/Sources/Basecamp/Generated/Models/Notification.swift Generated Swift model updated with bubble-up fields.
swift/Sources/Basecamp/Generated/Models/GetMyNotificationsResponseContent.swift Generated Swift response content updated with bubble-up collections.
swift/Sources/Basecamp/BasecampConfig.swift Bump Swift SDK apiVersion to 2026-05-01.
spec/bucket-scoped-allowlist.txt New allowlist for bucket-scoped list ops without flat counterparts.
spec/basecamp.smithy Smithy service version bump + additive BC5 model fields.
spec/api-provenance.json Provenance structure updated to track active branch + compatibility baseline.
scripts/validate-briefs.sh Shell entrypoint for briefs validation (Ruby).
scripts/validate-briefs.rb Ruby validator for brief frontmatter/body sections + allowlist schema checks.
scripts/report-bc3-drift.sh New helper to report drift for an arbitrary BC3 baseline/branch/label.
scripts/check-bucket-flat-parity.sh New lint to enforce bucket↔flat list-operation parity (with allowlist).
ruby/lib/basecamp/version.rb Bump Ruby SDK API_VERSION to 2026-05-01.
ruby/lib/basecamp/generated/types.rb Regenerated Ruby types with BC5 additive fields.
ruby/lib/basecamp/generated/metadata.json Regeneration timestamp update.
python/src/basecamp/generated/types.py Regenerated Python TypedDicts with BC5 additive fields.
python/src/basecamp/_version.py Bump Python SDK API_VERSION to 2026-05-01.
openapi.json Generated OpenAPI updated (version + new schema fields/docs).
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/Todoset.kt Regenerated Kotlin model updated with new todoset fields.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/Todo.kt Regenerated Kotlin model updated with embedded steps.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/Person.kt Regenerated Kotlin model updated with tagline.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/BasecampConfig.kt Bump Kotlin SDK API_VERSION to 2026-05-01.
go/pkg/generated/client.gen.go Regenerated Go client models with BC5 additive fields.
go/pkg/basecamp/version.go Bump Go SDK APIVersion to 2026-05-01.
go/pkg/basecamp/api-provenance.json Go copy of provenance updated to new structure.
briefs/api-gaps/todoset-completed-list-visibility.md New API gap brief.
briefs/api-gaps/step-top-level.md New API gap brief.
briefs/api-gaps/stack-doc-and-smithy.md New API gap brief.
briefs/api-gaps/search-filter-additions.md New API gap brief.
briefs/api-gaps/scratchpad.md New API gap brief.
briefs/api-gaps/schema.json New JSON schema for brief frontmatter.
briefs/api-gaps/rich-text-project-attachable.md New API gap brief.
briefs/api-gaps/recording-bubbleupable-field.md New API gap brief.
briefs/api-gaps/recordable-subtypes-doc.md New API gap brief.
briefs/api-gaps/everything-aggregates.md New API gap brief.
briefs/api-gaps/calendar.md New API gap brief.
briefs/api-gaps/allowlist.yml New allowlist for detector-classified routes that don’t require briefs.
briefs/api-gaps/allowlist-schema.json JSON schema for the briefs allowlist format.
briefs/api-gaps/activity-timeline.md New API gap brief.
briefs/api-gaps/README.md Overview doc + table of briefs + validation instructions.
briefs/COORDINATION.md Cross-team coordination doc for BC3 parity + SDK absorption lifecycle.
behavior-model.json Behavior model updated for new Person.tagline JSON path.
Makefile Add generate aggregator; wire new lints/validators into check; improve sync-status.
CONTRIBUTING.md Document make generate, parity lint, and briefs workflow.
.gitignore Ignore Kotlin .kotlin/ build artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread scripts/validate-api-gaps.rb
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

6 issues found across 50 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/validate-briefs.rb">

<violation number="1" location="scripts/validate-briefs.rb:78">
P2: `status =~ Regexp.new(status_pattern)` will raise a `TypeError` if YAML frontmatter supplies a non-string value (e.g., `status: 123`). Guard with `status.is_a?(String)` before applying the regex match so the validator reports a clean error instead of crashing.</violation>

<violation number="2" location="scripts/validate-briefs.rb:144">
P2: Reading `allowlist-schema.json` without an existence check can crash the validator with `Errno::ENOENT` when allowlist exists but schema is missing.</violation>
</file>

<file name="briefs/api-gaps/schema.json">

<violation number="1" location="briefs/api-gaps/schema.json:7">
P2: Top-level `additionalProperties: true` lets unknown/misspelled frontmatter fields pass validation, reducing the effectiveness of `validate-briefs`.</violation>
</file>

<file name="scripts/check-bucket-flat-parity.sh">

<violation number="1" location="scripts/check-bucket-flat-parity.sh:18">
P2: Default file paths are CWD-relative, so running this script outside repo root can produce false failures or skip the allowlist. Resolve paths from the script/repo root before reading files.

(Based on your team's feedback about anchoring shell scripts to the repository root.) [FEEDBACK_USED]</violation>

<violation number="2" location="scripts/check-bucket-flat-parity.sh:56">
P2: Silencing `jq` failures with `2>/dev/null || true` means that if the OpenAPI file is invalid JSON or the filter expression fails, `CANDIDATES` becomes empty and the lint exits with "0 bucket-scoped list operations found" — a false pass. Let `jq` errors propagate (or detect the non-zero exit explicitly) so spec-level problems aren't masked.</violation>
</file>

<file name="briefs/COORDINATION.md">

<violation number="1" location="briefs/COORDINATION.md:5">
P3: The document references a non-existent local planning file path, so collaborators cannot access the stated source of truth.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread scripts/validate-api-gaps.rb Outdated
Comment thread spec/api-gaps/schema.json Outdated
Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread scripts/validate-api-gaps.rb Outdated
Comment thread COORDINATION.md Outdated
@jeremy jeremy force-pushed the bc5-readiness-spec-foundations branch from 1e1c949 to 5bd407c Compare May 1, 2026 22:21
@jeremy jeremy requested a review from Copilot May 1, 2026 22:21
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label May 1, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 50 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread COORDINATION.md Outdated
Comment thread spec/api-gaps/README.md Outdated
Comment thread Makefile
Add optional fields to existing Smithy structures for BC5 read paths,
keeping BC4 readers fully compatible. All additions are opt-in: absent
fields are tolerated, present fields decode through the existing types.

* Notification: bubble_up_url, bubble_up_at (eligibility-gated)
* GetMyNotificationsOutput: bubble_ups, scheduled_bubble_ups; document
  current memories[] behavior pending BC team's back-compat decision
* Person: tagline (alias of bio in BC5)
* Todo: steps (reuses existing CardStep wire shape)
* Todoset: todos_count, completed_loose_todos_count, todos_url, app_todos_url

Restructure spec/api-provenance.json for parallel branch tracking — .bc3
keeps the active-branch baseline (now five), .compatibility.bc3-master
records the BC4 baseline for compatibility tracking. Existing tooling
(sync-spec-version, sync-api-version, Go provenance.go) reads the same
.bc3 keys and works unchanged.

Seed spec/bucket-scoped-allowlist.txt with the only existing bucket-only
list endpoint (webhooks) for the new parity lint.
@jeremy jeremy force-pushed the bc5-readiness-spec-foundations branch from 5bd407c to 63205bf Compare May 1, 2026 22:49
@jeremy jeremy requested a review from Copilot May 1, 2026 22:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 50 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread COORDINATION.md Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 63205bfebc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Makefile Outdated
jeremy added 4 commits May 1, 2026 16:02
…status

* make generate — single command to regenerate every machine-derived
  artifact in the repo (Smithy, behavior model, URL routes, provenance,
  per-language SDKs) in dependency order.

* make check-bucket-flat-parity — new lint that scans openapi.json for
  GET /{accountId}/buckets/{bucketId}/<resource>(/...).json list
  operations and verifies each has a flat counterpart at
  /{accountId}/<resource>.json (or is justified in
  spec/bucket-scoped-allowlist.txt). Cross-project SDK consumers
  shouldn't have to walk every project to query account-wide data.

* make sync-status — reads .bc3.branch and reports drift for the active
  branch (now five) and the compatibility branch (master) as two
  clearly-labeled blocks via scripts/report-bc3-drift.sh, instead of
  silently mixing them under HEAD.

* make validate-api-gaps target wired into make check (script lands in
  the api-gaps registry commit).
The SDK is the client-side demand signal for BC3 API coverage. spec/api-gaps/
is a durable, schema-validated registry: each entry tracks one BC5
user-visible feature that ships without (or with incomplete) JSON API
coverage, paired with the BC3 parity plan that owns server-side delivery.
Status changes flow through git history, making the absorption journey
publicly auditable.

Initial registry (11 entries aligned with BC3 plan Phase 3 deliverables):

* calendar — show/update only
* scratchpad — URL path deferred by BC3 plan
* step-top-level — doc-only addition (existing partial)
* everything-aggregates — Phase 3c flat top-level recording listings (~22)
* activity-timeline — /activity (global) + /projects/:id/timeline
* recordable-subtypes-doc — Journal, CloudFile, GoogleDocument; Door excluded
  (read paths + create operations per BC3 Phase 3a)
* stack-doc-and-smithy — full CRUD + list collectables
* search-filter-additions — additive filter params
* rich-text-project-attachable — Project as Attachable
* recording-bubbleupable-field — additive boolean
* todoset-completed-list-visibility — pending BC3 classification

Tooling:
* spec/api-gaps/schema.json + allowlist-schema.json validate frontmatter
* allowlist.yml records routes that don't warrant a registry entry
  (transient nav state, duplicates already covered elsewhere)
* scripts/validate-api-gaps.{sh,rb} — Ruby stdlib only, no gem deps

COORDINATION.md (root) describes the SDK ↔ BC3 plan relationship and the
absorption lifecycle for anyone reading the SDK repo cold.

CONTRIBUTING.md picks up the api-gaps section, the parity lint section,
and points at make generate as the single command to regenerate
everything.
@jeremy jeremy force-pushed the bc5-readiness-spec-foundations branch from 63205bf to 7e9c434 Compare May 1, 2026 23:03
@jeremy jeremy requested a review from Copilot May 1, 2026 23:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 34 out of 50 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/check-bucket-flat-parity.sh Outdated
Comment thread spec/api-gaps/todoset-completed-list-visibility.md
Both come in transitively via openapi-typescript → @redocly/openapi-core
(fast-uri through @redocly/ajv, brace-expansion through minimatch).
npm audit on the affected versions reports:

  fast-uri ≤3.1.1 — high — path traversal + host confusion
  (GHSA-q3j6-qgpj-74h6 / GHSA-v39h-62p7-jpjc)
  brace-expansion 4.0.0–5.0.4 — moderate — zero-step sequence
  hangs the process (GHSA-f886-m6hf-6m8v)

Lift both to the patched majors via overrides (alongside the existing
minimatch pin). The override path is preferred over plain dependency
bumps because the SDK doesn't depend on either package directly —
the responsibility for forwarding the fix sits with this repo until
the upstream packages cut new releases that pull the patches in
transitively.

Lands at the bottom of the BC5 stack so the wire-replay PRs above
(#294, #301) inherit the fix on rebase.
@jeremy jeremy requested a review from Copilot May 13, 2026 20:43
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label May 13, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 35 out of 52 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • typescript/package-lock.json: Language not supported

scripts/check-bucket-flat-parity.sh — drop `--slurpfile spec` and read
the spec via positional input instead. The previous form passed the
spec to jq twice (once via --slurpfile, once positionally), so jq
parsed it twice per invocation. Reading once via positional input then
binding `. as \$s` for cross-iteration access preserves the same
schema-resolution behavior with a single parse.

spec/api-gaps/todoset-completed-list-visibility.md — rewrite the
"PR 1 must classify" sentence so the constraint reads on its own,
without requiring the umbrella-plan cross-reference. The brief now
notes that classification must come from the BC3 side and the brief
stays in the registry either way; readers no longer need to know
which PR "PR 1" referred to.
@jeremy jeremy requested a review from Copilot May 13, 2026 20:47
@github-actions github-actions Bot removed the documentation Improvements or additions to documentation label May 13, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 35 out of 52 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • typescript/package-lock.json: Language not supported

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file enhancement New feature or request go kotlin ruby Pull requests that update the Ruby SDK spec Changes to the Smithy spec or OpenAPI swift typescript Pull requests that update TypeScript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants