feature:contract
Infer the feature contract from source code at any time — no release required.
Usage
splent feature:contract <feature_ref> [--write]
Examples
Preview what the contract would look like (dry-run):
splent feature:contract splent_feature_notes
With org and version:
splent feature:contract splent-io/splent_feature_auth@v1.2.7
Without version (auto-detects the latest cached version):
splent feature:contract splent_feature_auth
Infer and write to pyproject.toml:
splent feature:contract splent_feature_notes --write
Options
| Option | Description |
|---|---|
--write |
Write the inferred contract to pyproject.toml. Without this flag the command is read-only. |
Description
feature:contract scans a feature’s source code and infers its contract — the same logic used by feature:release, but available independently at any point.
The command:
- Scans the feature source code (routes, models, hooks, services, imports, env vars).
- Shows the full inferred contract.
- Highlights any differences from what is currently written in
pyproject.toml. - If
--writeis passed, rewrites[tool.splent.contract]inpyproject.toml.
No version bump. No git tag. No publish.
After writing the contract, the command checks if config.py is missing or stale and offers to run feature:inject-config to regenerate it.
Feature resolution
The command accepts features in multiple formats:
| Input | Resolves to |
|---|---|
splent_feature_auth |
Latest cached version (e.g., splent_feature_auth@v1.2.7) |
splent-io/splent_feature_auth |
Same, with explicit org |
splent-io/splent_feature_auth@v1.2.7 |
Exact version in cache |
splent_feature_notes |
Editable (unversioned) feature in cache |
Shared logic with feature:release
feature:release delegates contract updates to the same update_contract() function used by this command. This ensures contracts are always inferred consistently, whether during development or at release time.
Example output
feature:contract — splent_feature_auth
────────────────────────────────────────────────────
🔍 Scanning source code…
Inferred contract:
[tool.splent.contract.provides]
routes = ["/login", "/logout", "/signup/"]
blueprints = ["auth_bp"]
models = ["User"]
commands = []
hooks = ["layout.anonymous_sidebar", "layout.authenticated_sidebar"]
services = ["AuthenticationService"]
docker = []
signals = ["user_registered", "user_logged_in"]
translations = ["en", "es"]
[tool.splent.contract.requires]
features = []
env_vars = []
signals = ["profile_updated"]
[tool.splent.contract.extensible]
hooks = true
signals = true
✅ Contract is already up to date.
When changes are detected:
Changes detected:
+ hooks: layout.sidebar
+ requires.features: auth
Dry-run — run with --write to update pyproject.toml.
What is scanned
| Field | Source |
|---|---|
provides.routes |
@<bp>.route(...) decorators in routes.py |
provides.blueprints |
Blueprint variable names in __init__.py |
provides.models |
class <Name>(db.Model) in models.py |
provides.commands |
@click.command("name") decorators in commands.py |
provides.hooks |
register_template_hook("slot", func) calls in hooks.py |
provides.services |
class <Name>(BaseService) definitions in services.py |
provides.docker |
docker-compose*.yml files at the feature root |
provides.signals |
define_signal() calls in signals.py |
provides.translations |
Locale directories in translations/ |
requires.features |
import / from statements referencing other splent_feature_* packages (comments and docstrings are ignored) |
requires.env_vars |
os.getenv(...) and os.environ[...] calls |
requires.signals |
connect_signal() calls in signals.py |
When to use it
| Situation | Command |
|---|---|
| You added a new route and want other features to see it | feature:contract --write |
| You registered a new hook slot | feature:contract --write |
| You added a dependency on another feature | feature:contract --write |
| You want to preview the contract before releasing | feature:contract (dry-run) |
You are about to run product:validate and want accurate contracts |
feature:contract --write on each feature |
Requirements
- The feature must exist in
.splent_cache/features/(cloned or synced).
See also
feature:release— full release pipeline (delegates toupdate_contract())product:validate— compare contracts between featuresfeature:hooks— list registered hooksexport:puml— generate diagrams from contracts- Feature contract — contract format reference