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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
268 changes: 255 additions & 13 deletions .local/public-api-surface-improvements.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ repos:
stages: [pre-push]

- repo: https://github.com/psf/black
rev: 25.12.0
rev: 26.3.1
hooks:
- id: black
stages: [pre-commit]
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project will follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
after its first published distribution.

## [Unreleased]

### Added

- Public API stability policy for tier-1 modules.
- README Python API example coverage through a contract test.
- Changelog discipline before first publish.

### Changed

- README Python API guidance now directs workflow users to `ser.api`.

[Unreleased]: https://github.com/jsugg/ser/compare/HEAD...HEAD
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,31 @@ Profile selection during predict is strict: use an artifact trained for the same
When running from a source checkout without activating an environment, prefix commands with `uv run`.

## Python API
`ser.api` is the sole supported Python entry point. Everything else — including
modules under public-looking paths that are not exported from `ser`, `ser.api`,
`ser.domain`, `ser.config`, or `ser.utils` — is implementation detail and may
change without notice.
`ser.api` is the sole supported Python workflow entry point. Import package
metadata from `ser`, but call inference, training, dataset, profile, and
diagnostics operations through `ser.api`. Everything else — including modules
under public-looking paths that are not exported from `ser`, `ser.api`,
`ser.config`, `ser.domain`, `ser.profiles`, or `ser.utils` — is implementation
detail and may change without notice.

Minimal inference example:

```python
import ser
import ser.api

print(ser.__version__)

execution = ser.api.infer("sample.wav", profile="fast")
for segment in execution.emotions:
print(segment.emotion, segment.start_seconds, segment.end_seconds)
```

Stability promise: symbols exported from `ser.api` (see `ser.api.__all__`),
the domain types re-exported from `ser`/`ser.domain`, the trimmed `ser.config`
surface, and the helpers in `ser.utils` follow semantic versioning from `1.0.0`
onward. Anything not exported there carries no compatibility guarantee.
Stability promise: after the first published distribution, symbols exported
from `ser.api` (see `ser.api.__all__`), the domain types re-exported from
`ser`/`ser.domain`, the curated `ser.config`, `ser.profiles`, and `ser.utils`
surfaces follow semantic versioning. Anything not exported there carries no
compatibility guarantee. See [docs/api-stability.md](docs/api-stability.md).

## Boundary Checks (Contributors)
If your change touches `ser/api.py`, `ser/_internal/api/*`, or `ser/__main__.py`, run:
Expand All @@ -136,6 +142,7 @@ uv run pytest -q \
- Architecture guide: [docs/architecture.md](https://github.com/jsugg/ser/blob/main/docs/architecture.md)
- Contributor guide: [CONTRIBUTING.md](https://github.com/jsugg/ser/blob/main/CONTRIBUTING.md)
- Compatibility details: [docs/compatibility-matrix.md](https://github.com/jsugg/ser/blob/main/docs/compatibility-matrix.md)
- Public API stability: [docs/api-stability.md](docs/api-stability.md)
- Hardware validation workflows: [docs/ci/hardware-validation.md](https://github.com/jsugg/ser/blob/main/docs/ci/hardware-validation.md)
- Release and rollback runbook: [docs/release-and-rollback.md](https://github.com/jsugg/ser/blob/main/docs/release-and-rollback.md)
- Security policy: [SECURITY.md](https://github.com/jsugg/ser/blob/main/SECURITY.md)
Expand Down
56 changes: 2 additions & 54 deletions boundary_policy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,5 @@ path = "ser/config.py"
reason = "Public facade over internal config/bootstrap owners."

[[public_internal_import]]
path = "ser/data/application.py"
reason = "Public data application surface over internal data services."

[[public_internal_import]]
path = "ser/diagnostics/service.py"
reason = "Public diagnostics surface over internal diagnostics services."

[[public_internal_import]]
path = "ser/models/emotion_model.py"
reason = "Public model facade over internal runtime/model support seams."

[[public_internal_import]]
path = "ser/models/profile_runtime.py"
reason = "Public profile-runtime facade over internal model/runtime owners."

[[public_internal_import]]
path = "ser/models/training_entrypoints.py"
reason = "Public training facade over internal model workflow owners."

[[public_internal_import]]
path = "ser/repr/emotion2vec.py"
reason = "Public representation adapter requiring internal runtime/config support."

[[public_internal_import]]
path = "ser/runtime/accurate_inference.py"
reason = "Accurate profile wrapper over internal runtime owners."

[[public_internal_import]]
path = "ser/runtime/fast_inference.py"
reason = "Fast profile wrapper over internal runtime owner modules."

[[public_internal_import]]
path = "ser/runtime/medium_inference.py"
reason = "Medium profile wrapper over internal runtime owners."

[[public_internal_import]]
path = "ser/runtime/pipeline.py"
reason = "Public runtime orchestration surface over internal workflow owners."

[[public_internal_import]]
path = "ser/runtime/profile_quality_gate.py"
reason = "Public quality-gate surface over internal runtime/report owners."

[[public_internal_import]]
path = "ser/transcript/backends/stable_whisper.py"
reason = "Public backend adapter over internal transcription owners."

[[public_internal_import]]
path = "ser/transcript/profiling.py"
reason = "Public transcription profiling surface over internal transcription owners."

[[public_internal_import]]
path = "ser/transcript/transcript_extractor.py"
reason = "Public transcription boundary wrapper over internal transcription owners."
path = "ser/utils/__init__.py"
reason = "Tier-1 utility facade delegates curated helpers to internal owners."
53 changes: 53 additions & 0 deletions docs/api-stability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Public API stability

This project keeps a small tier-1 Python surface. Consumers should build workflows
through these modules only:

- `ser`
- `ser.api`
- `ser.config`
- `ser.domain`
- `ser.profiles`
- `ser.utils`

`ser.api` is the supported workflow entry point for inference, training, dataset,
profile, and diagnostics operations. The other tier-1 modules provide package
metadata, domain types, configuration objects, profile discovery, and curated utility
helpers used by that workflow surface.

## Stability promise

The SemVer compatibility promise starts with the first published distribution. From
that point, symbols exported by tier-1 `__all__` declarations will not be removed or
changed incompatibly without a major-version release.

Before first publish, the same surfaces are still governed as if they were stable so
that review catches compatibility drift early. Anything outside tier-1 is not a
compatibility contract.

## Internal modules

Modules below `ser._internal` are private implementation details. Public-looking
subpackage paths that are not tier-1 exports are also implementation details unless
they are declared as facade exceptions in [`boundary_policy.toml`](../boundary_policy.toml).

`ser.runtime.contracts`, `ser.runtime.schema`, and `ser.diagnostics.domain` are
implementation-owned contract leaves whose types are re-exported by `ser.api`.
They exist to preserve lightweight type ownership, not as additional workflow entry
points; consumers should import their vocabulary from `ser.api`.

Facade exceptions may import private owners only when the policy file records a
specific reason. Contributors should move implementation code under `ser._internal`
and keep public facades thin.

## API change governance

Tier-1 API drift is machine-reviewed by the checked-in public snapshot at
[`tests/suites/integration/architecture/public_api_snapshot.json`](../tests/suites/integration/architecture/public_api_snapshot.json).
The contract test
[`test_public_api_snapshot.py`](../tests/suites/integration/architecture/test_public_api_snapshot.py)
regenerates that snapshot in memory and fails on unreviewed differences.

Intentional public API changes must update the snapshot with
[`scripts/dump_public_api.py`](../scripts/dump_public_api.py), review the diff, and keep
the import-boundary policy aligned.
Loading
Loading