Feature states
Introduction
Each state is a checkpoint in a feature’s integration with your product, from code on disk to routes the app serves. feature:status shows where each feature stands.
splent feature:status
migrations/ directory can become active from any earlier state.cached
The code is on disk and no product declares it. A working copy lives at the workspace root, and a snapshot in .splent_cache/features/<namespace>/<name>@<version>/.
| Reached by | Gives |
|---|---|
splent feature:create <ns>/<name> |
A working copy at the workspace root |
splent feature:clone <ns>/<name>@<version> |
A snapshot in the cache |
splent feature:fork <name> |
A fork on the forge, cloned into the cache and made writable |
feature:discard <name> deletes the working copy, and feature:delete <ns>/<name> <version> one snapshot. Neither touches a product.
declared
The feature is in your pyproject.toml with a symlink under features/. Nothing is installed yet.
| Reached by | Note |
|---|---|
splent feature:add <ns>/<name> |
Editable |
splent feature:attach <ns>/<name> <version> |
Pinned |
splent feature:install |
Clones and declares in one step |
splent product:resolve |
Gives every declared feature at least this state |
feature:remove takes it back to cached. feature:detach does too, and leaves the entry without its version, as an editable declaration.
installed
The package and its dependencies are installed, so its code imports. The 00_install_features.sh startup script reaches it with pip install -e when the product’s container starts. product:resolve only links features and records them as declared.
migrated
The feature’s tables exist. db:upgrade, db:reset and the 04_handle_migrations.sh startup script reach it. db:migrate does not, since it only writes a revision file.
A feature can go straight from declared to migrated, since a successful db:upgrade proves it imports. A feature without a migrations/ directory is recorded as migrated too. db:rollback takes it back to installed.
To remove a migrated feature, roll it back first with
splent db:rollback <feature> --steps 999.feature:removeandfeature:detachrefuse until then, unless you pass--force. See State guards.
active
The feature runs inside Flask, with its blueprints registered, its routes served and its hooks connected. It is the only state users can see.
The app advances each feature when it starts. A feature with migrations becomes active only once migrated, and one without migrations from any earlier state.
disabled
disabledis reserved. The manifest accepts it, but no command sets it, and the app loads every declared feature whatever its recorded state. To keep a feature out of a product, remove it frompyproject.toml, or move it tofeatures_devorfeatures_prod.
See also
- State guards, blocked operations and automatic transitions
- Feature state, the manifest’s format