Skip to content

Absorb everything-aggregates bucket-grouped family (bc3 #11627, PR-5b of 2)#438

Open
jeremy wants to merge 1 commit into
everything-flat-familyfrom
everything-bucket-grouped
Open

Absorb everything-aggregates bucket-grouped family (bc3 #11627, PR-5b of 2)#438
jeremy wants to merge 1 commit into
everything-flat-familyfrom
everything-bucket-grouped

Conversation

@jeremy

@jeremy jeremy commented Jul 25, 2026

Copy link
Copy Markdown
Member

Completes #434 (the everything-aggregates absorption). Part of the post-#401 BC3 follow-up program (PR-5b, the final unit).

Stacked on #435 (PR-5) → #431#426#424#419#416. Base is everything-flat-family; review the PR-5b commit only. Will retarget to main as the stack merges.

Summary

The second everything-aggregates contract family: the 9 todo/card filter sub-routes returning a Link-paginated array of buckets, each grouping the matching recordings (with embedded steps) under their parent project.

  • 9 ops on EverythingService: GetEverythingOpen/Completed/Unassigned/NoDueDate Todos and Open/Completed/Unassigned/NoDueDate/NotNow Cards — each Link-paginated, single-member output → bare array of groups (smithy-bare-arrays).
  • Group shapes BucketTodosGroup {bucket, todos} / BucketCardsGroup {bucket, cards}, reusing the full Todo/Card shapes (which already model steps/assignees/due_on). Kotlin needed both group types in the generator TYPE_ALIASES to emit typed models.
  • Go wrappers (OpenTodos/… and OpenCards/…/NotNowCards) with multi-page Link-following; Go tests cover multi-page pagination and the {bucket, todos|cards}-with-steps grouping.

Absorption complete

All 17 everything routes are now modeled, generated across the six SDKs, Go-wrapped, and decode-tested — so everything-aggregates.md flips to absorbed-in-sdk. Conformance paths.json path-assertions + per-runner dispatch and per-group live-canary entries remain as supplementary verification infra (the live canary is dormant); the modeled surface itself is complete.

Verification

make generate && make check — clean (all six SDK suites, conformance, wrapper/Kotlin drift at 223 operations, 24 api-gap entries).


Summary by cubic

Adds bucket-grouped todo/card filters to EverythingService, returning Link-paginated arrays of {bucket, todos|cards} groups. Completes the everything-aggregates absorption across all SDKs and flips the gap doc to absorbed-in-sdk.

  • New Features
    • Adds 9 operations: Todos (Open, Completed, Unassigned, NoDueDate) and Cards (Open, Completed, Unassigned, NoDueDate, NotNow), all Link-paginated with bare array outputs via smithy-bare-arrays.
    • Introduces BucketTodosGroup and BucketCardsGroup models reusing Todo/Card (with embedded steps); Kotlin generator adds TYPE_ALIASES for both.
    • Implements Go wrappers with multi-page Link following and tests; updates generators/metadata and routes/spec for TypeScript, Kotlin, Python, Ruby, and Swift.

Written for commit 04279fa. Summary will update on new commits.

Review in cubic

…R-5b of 2)

Complete the everything-aggregates absorption with the second contract family:
the 9 todo/card filter sub-routes that return a Link-paginated array of buckets,
each grouping the matching recordings (with their embedded steps) under their
parent project.

- 9 operations on EverythingService: GetEverythingOpen/Completed/Unassigned/
  NoDueDate Todos and Open/Completed/Unassigned/NoDueDate/NotNow Cards, each
  Link-paginated with a single-member output → bare array of groups via the
  smithy-bare-arrays transform.
- Group shapes BucketTodosGroup {bucket, todos} and BucketCardsGroup
  {bucket, cards}, reusing the full Todo/Card shapes (which already model steps,
  assignees, due_on, etc.). Kotlin needed both group types added to the
  generator TYPE_ALIASES to emit typed models.
- Go wrappers (OpenTodos/… and OpenCards/…/NotNowCards) with multi-page
  Link-following; Go tests cover multi-page pagination and the
  {bucket, todos|cards}-with-steps grouping.

All 17 everything routes are now modeled, generated across the six SDKs,
Go-wrapped, and decode-tested, so everything-aggregates.md flips to
absorbed-in-sdk. Conformance paths.json path-assertions + per-runner dispatch
and per-group live-canary entries remain as supplementary verification infra
(the live canary is dormant); the modeled surface itself is complete.
Copilot AI review requested due to automatic review settings July 25, 2026 06:15
@github-actions github-actions Bot added 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 Jul 25, 2026
@github-actions

Copy link
Copy Markdown

Spec Change Impact

Summary of Changes

  • Operations/Types/Resources Added: None
  • Operations/Types/Resources Modified: bucket-grouped family absorbed into everything-aggregates.
  • Operations/Types/Resources Removed: bucket-grouped family removed.

Breaking API Change

Yes, this change removes the bucket-grouped family, which may break consumers relying on those operations/types.

SDK Regeneration Required

This change affects all SDKs due to modifications in type definitions and resource structure.

Checklist of SDKs Needing Updates:

  • Go
  • TypeScript
  • Ruby
  • Kotlin
  • Swift

@github-actions github-actions Bot added the enhancement New feature or request label Jul 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 04279fa186

ℹ️ 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 spec/basecamp.smithy
@basecampRetry(maxAttempts: 3, baseDelayMs: 1000, backoff: "exponential", retryOn: [429, 503])
@basecampPagination(style: "link", totalCountHeader: "X-Total-Count", maxPageSize: 50)
@http(method: "GET", uri: "/{accountId}/todos/open.json")
operation GetEverythingOpenTodos {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add required cross-SDK tests for the nine operations

These nine new wire operations are generated for TypeScript, Ruby, and Python, but this commit adds no corresponding service tests; repo-wide searches of the existing Everything test files find none of the new todo/card methods. Consequently, their paths, pagination, response decoding, and error handling can regress without coverage, and the repository explicitly requires happy-path and error tests in all three SDKs for every new operation.

AGENTS.md reference: AGENTS.md:L295-L307

Useful? React with 👍 / 👎.

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 completes the everything-aggregates absorption by modeling the bucket-grouped todo/card filter sub-routes (9 ops) and fanning them out through Smithy → OpenAPI → generated SDKs, plus Go wrappers + tests and registry flip to absorbed-in-sdk.

Changes:

  • Adds 9 Everything aggregate filter operations (todos + cards) returning Link-paginated arrays of { bucket, todos|cards } groups.
  • Introduces BucketTodosGroup / BucketCardsGroup models across SDKs and updates generator wiring/metadata.
  • Updates Go wrappers + tests for multi-page Link-following and grouped decode; flips the api-gap entry to absorbed.

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.

Reviewed changes

Copilot reviewed 9 out of 30 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
behavior-model.json Registers readonly/pagination/retry behavior for the new Everything operations.
go/pkg/basecamp/everything.go Adds Go wrapper APIs and group types for bucket-grouped todo/card filters.
go/pkg/basecamp/everything_test.go Adds decode/pagination tests for the new bucket-grouped Everything wrappers.
go/pkg/basecamp/url-routes.json Adds route metadata for the new Everything endpoints.
kotlin/generator/src/main/kotlin/com/basecamp/sdk/generator/Config.kt Adds type aliases so the Kotlin generator emits typed models for the new group shapes.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/Metadata.kt Adds retry configuration entries for the new operations.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketCardsGroup.kt Adds Kotlin model for {bucket, cards} group entries.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/models/BucketTodosGroup.kt Adds Kotlin model for {bucket, todos} group entries.
kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/services/everything.kt Adds Kotlin service methods for the new bucket-grouped filters.
python/src/basecamp/generated/metadata.json Adds retry config entries for the new Everything operations.
python/src/basecamp/generated/services/everything.py Adds sync/async Python service methods for the new bucket-grouped filters.
python/src/basecamp/generated/types.py Adds BucketTodosGroup / BucketCardsGroup TypedDicts.
ruby/lib/basecamp/generated/metadata.json Adds retry/pagination metadata for the new operations.
ruby/lib/basecamp/generated/services/everything_service.rb Adds Ruby generated service methods for the new bucket-grouped filters.
ruby/lib/basecamp/generated/types.rb Adds Ruby generated type classes for the new group shapes.
spec/api-gaps/README.md Flips everything-aggregates registry status to absorbed-in-sdk.
spec/api-gaps/everything-aggregates.md Marks absorption complete and records Smithy refs for bucket-grouped family + shapes.
spec/basecamp.smithy Adds Smithy operations + shapes for the bucket-grouped todo/card filter family.
spec/overlays/tags.smithy Tags the new operations under the Everything service grouping.
swift/Sources/Basecamp/Generated/Metadata.swift Adds retry config entries for the new Everything operations.
swift/Sources/Basecamp/Generated/Models/BucketCardsGroup.swift Adds Swift model for {bucket, cards} group entries.
swift/Sources/Basecamp/Generated/Models/BucketTodosGroup.swift Adds Swift model for {bucket, todos} group entries.
swift/Sources/Basecamp/Generated/Services/EverythingService.swift Adds Swift service methods + pagination options structs for the new endpoints.
typescript/src/generated/metadata.ts Adds retry/pagination metadata for the new Everything operations.
typescript/src/generated/path-mapping.ts Maps new Everything paths to their operation names.
typescript/src/generated/schema.d.ts Adds new paths/operations/schemas for bucket-grouped Everything filters.
typescript/src/generated/services/everything.ts Adds TypeScript EverythingService methods + options types for the new endpoints.
Comments suppressed due to low confidence (8)

go/pkg/basecamp/everything.go:495

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingCompletedTodosWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:509

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingUnassignedTodosWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:523

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingNoDueDateTodosWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:537

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingOpenCardsWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:551

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingCompletedCardsWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:565

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingUnassignedCardsWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:579

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingNoDueDateCardsWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

go/pkg/basecamp/everything.go:594

  • The page argument is documented as selecting a specific page, but this call always fetches page 1 because no page query is ever set. Passing page=2 will still return the first page (and just disables auto-pagination). Consider adding a per-request editor to set ?page= when page > 0 so callers can request an explicit page number.
	r, err := s.client.parent.gen.GetEverythingNotNowCardsWithResponse(ctx, s.client.accountID)
	if err != nil {
		return nil, err
	}
	return s.finishCardGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

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

Comment on lines +477 to +481
r, err := s.client.parent.gen.GetEverythingOpenTodosWithResponse(ctx, s.client.accountID)
if err != nil {
return nil, err
}
return s.finishTodoGroupsPage(ctx, r.HTTPResponse, r.Body, r.JSON200, page)

@cubic-dev-ai cubic-dev-ai Bot 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.

3 issues found across 30 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="go/pkg/basecamp/everything.go">

<violation number="1" location="go/pkg/basecamp/everything.go:477">
P2: Passing a positive `page` currently only disables Link-following but still fetches the first page, because the initial request never sends a `page` query parameter. This makes `page` behave differently from its doc comment and can return unexpected results for explicit-page callers.</violation>

<violation number="2" location="go/pkg/basecamp/everything.go:625">
P3: Pagination behavior now has two near-identical implementations. Future fixes to Link handling, metadata, or decode errors can diverge; extract the shared page-finalization flow with typed conversion callbacks, leaving only todo/card conversion local.</violation>
</file>

<file name="typescript/src/generated/services/everything.ts">

<violation number="1" location="typescript/src/generated/services/everything.ts:162">
P2: These new Everything todo/card service methods are added in TypeScript, Ruby, and Python without corresponding service test coverage in this change. Adding happy-path and error-path tests for the new operations would reduce regression risk around path wiring, pagination behavior, and response decoding.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

return nil, err
}
defer done(&err)
r, err := s.client.parent.gen.GetEverythingOpenTodosWithResponse(ctx, s.client.accountID)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Passing a positive page currently only disables Link-following but still fetches the first page, because the initial request never sends a page query parameter. This makes page behave differently from its doc comment and can return unexpected results for explicit-page callers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At go/pkg/basecamp/everything.go, line 477:

<comment>Passing a positive `page` currently only disables Link-following but still fetches the first page, because the initial request never sends a `page` query parameter. This makes `page` behave differently from its doc comment and can return unexpected results for explicit-page callers.</comment>

<file context>
@@ -416,6 +416,240 @@ func (s *EverythingService) OverdueCards(ctx context.Context) (result []Card, er
+		return nil, err
+	}
+	defer done(&err)
+	r, err := s.client.parent.gen.GetEverythingOpenTodosWithResponse(ctx, s.client.accountID)
+	if err != nil {
+		return nil, err
</file context>

@@ -26,6 +26,36 @@ export type Todo = components["schemas"]["Todo"];
export interface EverythingBoostsEverythingOptions extends PaginationOptions {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: These new Everything todo/card service methods are added in TypeScript, Ruby, and Python without corresponding service test coverage in this change. Adding happy-path and error-path tests for the new operations would reduce regression risk around path wiring, pagination behavior, and response decoding.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At typescript/src/generated/services/everything.ts, line 162:

<comment>These new Everything todo/card service methods are added in TypeScript, Ruby, and Python without corresponding service test coverage in this change. Adding happy-path and error-path tests for the new operations would reduce regression risk around path wiring, pagination behavior, and response decoding.</comment>

<file context>
@@ -95,6 +149,106 @@ export class EverythingService extends BaseService {
+   * const result = await client.everything.everythingCompletedCards();
+   * ```
+   */
+  async everythingCompletedCards(options?: EverythingCompletedCardsEverythingOptions): Promise<components["schemas"]["GetEverythingCompletedCardsResponseContent"]> {
+    return this.requestPaginated(
+      {
</file context>

return &BucketTodosGroupsPage{Groups: groups, Meta: ListMeta{TotalCount: totalCount, Truncated: truncated}}, nil
}

func (s *EverythingService) finishCardGroupsPage(ctx context.Context, httpResp *http.Response, body []byte, json200 *[]generated.BucketCardsGroup, page int32) (*BucketCardsGroupsPage, error) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Pagination behavior now has two near-identical implementations. Future fixes to Link handling, metadata, or decode errors can diverge; extract the shared page-finalization flow with typed conversion callbacks, leaving only todo/card conversion local.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At go/pkg/basecamp/everything.go, line 625:

<comment>Pagination behavior now has two near-identical implementations. Future fixes to Link handling, metadata, or decode errors can diverge; extract the shared page-finalization flow with typed conversion callbacks, leaving only todo/card conversion local.</comment>

<file context>
@@ -416,6 +416,240 @@ func (s *EverythingService) OverdueCards(ctx context.Context) (result []Card, er
+	return &BucketTodosGroupsPage{Groups: groups, Meta: ListMeta{TotalCount: totalCount, Truncated: truncated}}, nil
+}
+
+func (s *EverythingService) finishCardGroupsPage(ctx context.Context, httpResp *http.Response, body []byte, json200 *[]generated.BucketCardsGroup, page int32) (*BucketCardsGroupsPage, error) {
+	if err := checkResponse(httpResp, body); err != nil {
+		return nil, err
</file context>

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

Labels

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