Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ uv for environments and locking, hatchling for the build, pytest, mypy --strict,
| Generate `src/didit/types`, `src/didit/resources`, `tests/generated` from `openapi/` | `uv run python codegen/generate.py` |
| Check the committed generated code is current (CI) | `uv run python codegen/generate.py --check` |
| Sync `openapi/` with docs.didit.me (spec-sync workflow) | `uv run python codegen/spec_sync.py --summary spec-sync-summary.md` |
| Regenerate `openapi/breaking-vectors.json` (the shared breaking-change cases, DESIGN.md 3.1) | `uv run python codegen/breaking_vectors.py` |
| Test (unit, generated, contract, webhooks, Authentication, codegen) | `uv run pytest` |
| Test with the core coverage gate | `uv run pytest --cov --cov-report=term-missing --cov-fail-under=90` |
| Live sandbox smoke tests (only with `DIDIT_SANDBOX_API_KEY`) | `uv run pytest -m live` |
Expand All @@ -31,6 +32,7 @@ uv for environments and locking, hatchling for the build, pytest, mypy --strict,

- Generated (never edit by hand): `src/didit/types/`, `src/didit/resources/`, `tests/generated/`. The generator is `codegen/didit_codegen/`; its tests are in `codegen/tests/`.
- Core (hand-written): everything else in `src/didit/` (`_base_client.py` transport and retries, `_client.py` options, `_exceptions.py`, `_pagination.py`, `_files.py`, `_response.py`, `_models.py`), `src/didit/webhooks/` and `src/didit/authentication/`.
- `openapi/breaking-vectors.json` (written by `codegen/breaking_vectors.py`, never by hand) holds the breaking-change rules of DESIGN.md 3.1 as cases. The other six server SDKs copy it byte for byte, so a rule change lands here first: change DESIGN.md 3.1, `codegen/spec_sync.py` and the cases together, regenerate, then copy the file to the other six.
- `openapi/deprecated-operations.json` (written by `codegen/spec_sync.py`) keeps methods whose operation was removed or renamed upstream as deprecated methods until `remove_in` (the next minor version); `tests/test_contract.py` fails once that version is reached, and the entry is then deleted.

## Rules
Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ uv for environments and locking, hatchling for the build, pytest, mypy --strict,
| Generate `src/didit/types`, `src/didit/resources`, `tests/generated` from `openapi/` | `uv run python codegen/generate.py` |
| Check the committed generated code is current (CI) | `uv run python codegen/generate.py --check` |
| Sync `openapi/` with docs.didit.me (spec-sync workflow) | `uv run python codegen/spec_sync.py --summary spec-sync-summary.md` |
| Regenerate `openapi/breaking-vectors.json` (the shared breaking-change cases, DESIGN.md 3.1) | `uv run python codegen/breaking_vectors.py` |
| Test (unit, generated, contract, webhooks, Authentication, codegen) | `uv run pytest` |
| Test with the core coverage gate | `uv run pytest --cov --cov-report=term-missing --cov-fail-under=90` |
| Live sandbox smoke tests (only with `DIDIT_SANDBOX_API_KEY`) | `uv run pytest -m live` |
Expand All @@ -31,6 +32,7 @@ uv for environments and locking, hatchling for the build, pytest, mypy --strict,

- Generated (never edit by hand): `src/didit/types/`, `src/didit/resources/`, `tests/generated/`. The generator is `codegen/didit_codegen/`; its tests are in `codegen/tests/`.
- Core (hand-written): everything else in `src/didit/` (`_base_client.py` transport and retries, `_client.py` options, `_exceptions.py`, `_pagination.py`, `_files.py`, `_response.py`, `_models.py`), `src/didit/webhooks/` and `src/didit/authentication/`.
- `openapi/breaking-vectors.json` (written by `codegen/breaking_vectors.py`, never by hand) holds the breaking-change rules of DESIGN.md 3.1 as cases. The other six server SDKs copy it byte for byte, so a rule change lands here first: change DESIGN.md 3.1, `codegen/spec_sync.py` and the cases together, regenerate, then copy the file to the other six.
- `openapi/deprecated-operations.json` (written by `codegen/spec_sync.py`) keeps methods whose operation was removed or renamed upstream as deprecated methods until `remove_in` (the next minor version); `tests/test_contract.py` fails once that version is reached, and the entry is then deleted.

## Rules
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ CI runs `uv run python codegen/generate.py --check`, which regenerates into a te

The spec sync runs daily. When upstream changed, it regenerates the code, runs the checks and opens a pull request titled `<type>(spec): sync API spec YYYY-MM-DD`. The type is `feat(spec)` when a caller can observe the change (a minor release, even when it can break typed code) and `chore(spec)` when only descriptions, examples or other documentation changed (no release on its own); never `!` or a `BREAKING CHANGE:` footer (DESIGN sections 3.1 and 13). A download that is not an OpenAPI 3 document with paths is refused and nothing is written.

The body opens with "Breaking changes", or "None detected": every field or parameter whose type changed or that can now be null, removed operation, field or enum value, and newly required parameter or request field, in parameters, request bodies and 2xx responses, following `$ref`s and array items. Then it lists added, removed, renamed and changed operations and schemas. It ends with a `BEGIN_COMMIT_OVERRIDE` block that release-please reads instead of the merged commit: the sync line plus one nested `api(spec):` commit per breaking change, which `release-please-config.json` lists under "API changes that can break typed code". Merge sync pull requests with **Squash and merge** and keep that block: after a merge commit release-please reads it once per commit and every line appears twice. When the lines do not fit in a pull request description (hundreds of breaking changes), the description says so and leaves the block out; then squash with the sync commit's message, which holds every line.
The body opens with "Breaking changes", or "None detected": every change the rules of DESIGN section 3.1 count, in parameters, request bodies and 2xx responses, following `$ref`s and array items. Then it lists added, removed, renamed and changed operations and schemas. It ends with a `BEGIN_COMMIT_OVERRIDE` block that release-please reads instead of the merged commit: the sync line plus one nested `api(spec):` commit per breaking change, which `release-please-config.json` lists under "API changes that can break typed code". Merge sync pull requests with **Squash and merge** and keep that block: after a merge commit release-please reads it once per commit and every line appears twice. When the lines do not fit in a pull request description (hundreds of breaking changes), the description says so and leaves the block out; then squash with the sync commit's message, which holds every line.

The rules are held by `openapi/breaking-vectors.json`, which the other six server SDKs copy byte for byte and run through their own detectors. `codegen/breaking_vectors.py` writes it from hand-written cases: two minimal documents, before and after, with the expected commit type and the counted changes, each reviewed against DESIGN section 3.1. It refuses to write the file while `codegen/spec_sync.py` disagrees with a case, and `codegen/tests/test_breaking_vectors.py` fails while the committed file is not what it writes. To change a rule, change DESIGN section 3.1, the detector and the cases in one pull request, run `uv run python codegen/breaking_vectors.py`, and then copy the file to the other six repositories.

`openapi/authentication.json` is synced like the others, but the `didit.authentication` module stays hand-written (DESIGN section 10). When a sync adds, removes or renames one of its server operations, the body lists it under "Authentication module" and `tests/test_authentication_contract.py` fails until the module follows on the sync branch.

Expand Down
Loading
Loading