Skip to content

Add API groups with generated documentation and Rust marker traits - #11

Merged
koehlma merged 3 commits into
mainfrom
work/agents/api-groups
Oct 17, 2026
Merged

koehlma merged 3 commits into
mainfrom
work/agents/api-groups

Conversation

@koehlma

@koehlma koehlma commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Adds groups: named sets of definitions that share a compatibility promise.

  • A bundle declares groups in sidex.toml:
    [groups.mobile]
    description = "Used by released mobile apps. Keep changes backward compatible for at least 12 months."
  • #[group(name = "mobile")] assigns a definition to a group. A definition also belongs to the groups of every definition of the same bundle that uses it, through field types, variant payloads, wrapped and aliased types, type arguments, and #[request] responses. Naming an undeclared group is an error.
  • The Rust, TypeScript, Python, and JSON Schema generators start a member's documentation with **Group mobile:** <description>.
  • The IR records each bundle's declared groups and each definition's resolved groups.
  • The Rust backend setting group_traits = ["mobile"] generates a MobileGroupMarker marker trait at the bundle root. [backend.rust.group_trait_names] can override the name, for example mobile = "MobileApi". The group's records, variants, and wrappers implement the trait, so code can use it as a bound to accept only types of the group.
  • New guide page guides/api-groups.md, plus a "Group Marker Traits" section in the Rust generation docs and updates to the attribute and manifest references.

Rationale

An API often serves consumers that update on different schedules. For example, deployed devices or installed apps keep using old releases long after a web console has been updated. The definitions those consumers depend on need stronger compatibility promises than the rest. Groups make this visible in schemas and generated code. In Rust, the marker traits also let the compiler enforce it, for example by accepting only types of a device group in code that serves device clients.

Membership extends through use because a promise about a request must also cover the types it sends and returns. Compatibility checks against a group's promise are intentionally out of scope for now.

Notes for Reviewers

  • Each IR definition's span now holds the span of its name. Before, definition spans were never set. As a result, existing lifecycle and JSON attribute diagnostics now show source locations too.
  • Membership is computed once during IR construction (sidex_attrs_api::assign_groups). Generators read Def.groups.
  • Invalid trait settings are Sidex errors: an undeclared group in group_traits, a group_trait_names entry for an unselected group, a name that is not a Rust identifier, and two groups with the same trait name.
  • tests/json gained a small groups schema. sidex-serde-tests uses it to check that the generated traits compile as bounds. The Python and TypeScript test suites also generate from this bundle.
  • New mise run regenerate:api-attrs task for the API attribute types, matching the existing regenerate tasks.

Created on behalf of @koehlma by Claude Code / claude-opus-5-5 · Task

@koehlma
koehlma merged commit a43b2b7 into main Oct 17, 2026
12 checks passed
@koehlma koehlma mentioned this pull request Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant