diff --git a/.github/release-notes/README.md b/.github/release-notes/README.md new file mode 100644 index 0000000..dbbd692 --- /dev/null +++ b/.github/release-notes/README.md @@ -0,0 +1,29 @@ +# Curated release notes + +`tag-release.yml` generates the GitHub release body from a Claude-written +changelog of the changes since the last tag. That framing suits routine +releases but reads poorly for a milestone, where the story is what the version +_is_ rather than what changed since last Tuesday. + +To override it, commit the notes here as `v.md` **before** dispatching +`create-release.yml`. The file has to exist at the tagged ref, so it belongs in +release prep alongside the version bump — not added afterwards. When the file is +present the workflow uses it verbatim and skips the generated changelog, the +release-statistics section, and the generated-with footer. + +No file, no change: the release falls back to the generated changelog. Skipping +a release is a normal outcome, not a failure. + +## Writing a new one + +Write the body only. The workflow supplies the `# RoboSystems Python SDK +v` heading and the links section, so don't repeat them here — start at +the first line of prose. + +The filename is version-specific on purpose: a leftover file can never be picked +up by a later release. + +For this SDK, curated notes are **mandatory for majors and for any minor that +deprecates surface** — post-1.0, those notes are the compatibility contract: +they list what changed in the public surface, what is deprecated (and its +earliest removal major), and what was removed. diff --git a/.github/release-notes/v1.0.0.md b/.github/release-notes/v1.0.0.md new file mode 100644 index 0000000..a8a8a56 --- /dev/null +++ b/.github/release-notes/v1.0.0.md @@ -0,0 +1,56 @@ +The RoboSystems Python SDK is stable. + +1.0.0 is a compatibility promise, not a feature release. From this version +forward: patches are fixes, minors are strictly additive, and anything that +would break your code — a removed method, a changed return shape, a renamed +parameter — costs a major and arrives only after a deprecation cycle +(deprecated surface warns for at least one further minor and 90 days before +removal). + +**The headline guarantee: the SDK is typed end to end.** Every facade read +returns a Pydantic v2 model generated from the platform's GraphQL schema — +`dict[str, Any]` is gone from the public surface. The generated models are +regenerated against the checked-in schema on every CI run, so the SDK cannot +silently drift from the API: if the platform changes shape, this package fails +its own build before it can mislead yours. + +## The stable surface + +Covered by the promise: + +- **`LedgerClient`** — the event-driven ledger: entities, accounts, + transactions, journal entries, event blocks and agents, trial balances, + mappings and mapping candidates, information blocks (including forecast + scenarios and windowed series), fiscal close, live statements, metrics, + reports and publish lists +- **`InvestorClient`** — portfolios, securities, positions, holdings +- **`LibraryClient`** — taxonomy browsing, structures, element search, + classifications, arcs and equivalents +- **`QueryClient` / `OperationClient` / `SSEClient` / `OperatorClient`** — + Cypher queries (sync, async, queued, batch), operation envelopes with SSE + monitoring, the AI operator +- **Table / File / Document / Graph clients** — staging tables, uploads, + document search, graph lifecycle +- **Auth** — API keys and JWTs with automatic header routing, per-request + `token_provider` for rotating credentials, `TokenManager`, and the + `AuthenticatedClients` helpers; `GraphQLError` and the queued-work error + classes +- Package-root imports: `RoboSystemsClients`, `get_clients()`, the facade + classes, and `GraphQLError` + +Generated internals (`robosystems_client.api.*`, `robosystems_client.models.*`) +are implementation detail — import facades. + +## Breaking changes since 0.6 + +- All GraphQL reads return typed models: attribute access replaces dict access + (`summary["account_count"]` → `summary.account_count`) +- The import-time `clients` singleton is replaced by lazy `get_clients()` +- `create_report` defaults to the platform's canonical `rs-gaap` taxonomy +- `AuthenticatedClients` routes each credential to exactly one auth header + +## Build on it + +Start an integration from the template: +https://github.com/RoboFinSystems/robosystems-integration-template — pin +`robosystems-client>=1,<2`.