Feature states
Each feature passes through a series of states from creation to runtime. Each state represents a checkpoint in the feature’s integration with the product.
State machine
feature:create
feature:clone
feature:fork
(absent) ──────────────────→ [cached]
│
feature:add │ feature:discard
feature:attach ▼ feature:delete
[declared] ─────────────────→ (absent)
│ ▲
product:resolve / │ │ feature:remove
pip install │ │ feature:detach
▼ │
[installed]
│ ▲
splent db:upgrade │ │ splent db:rollback
splent db:migrate │ │
▼ │
[migrated]
│
Flask startup │
(FeatureManager │
.register_features) │
▼
[active]
│ ▲
feature:disable │ │ feature:enable
▼ │
[disabled]
absent
The feature does not exist in the workspace. No cache entry, no product reference.
cached
The feature exists in .splent_cache/features/<namespace>/<name>/ but has not been linked to any product.
Reached by the following commands.
splent feature:create <ns>/<name>splent feature:clone <ns>/<name>splent feature:fork <ns>/<name>
declared
The feature is registered in the product’s pyproject.toml and a symlink exists under features/. No Python installation has occurred yet.
Reached by the following commands.
splent feature:add <ns>/<name>(editable)splent feature:attach <ns>/<name> <version>(pinned)splent feature:install(does both clone + declare)splent product:resolve(ensures all features have at least “declared”)
Reversed by the following commands.
splent feature:remove(returns to cached)splent feature:detach(returns to cached)
At this stage, pyproject.toml has the entry and splent.manifest.json records state: declared. No code is imported, no routes are active.
installed
The feature’s Python package and dependencies are installed. The feature is importable.
Reached by either of the following.
- The
00_install_features.shstartup script (pip install -e) - Manual
pip install -e .
At this stage, sys.path includes the feature source. Models, services, forms are importable. No Flask app context exists yet.
migrated
The feature’s database schema is applied. All its models have corresponding tables.
Reached by the following.
splent db:upgradesplent db:migrate- The
03_initialize_migrations.shand04_handle_migrations.shstartup scripts
Reversed by the following commands.
splent db:rollback(returns to installed)splent db:reset(drops all tables and re-applies)
Removing a migrated feature requires splent db:rollback <feature> first. The CLI blocks feature:remove, feature:detach, feature:unlock, and feature:upgrade on migrated features unless --force is used.
active
The feature is running inside Flask. Blueprints registered, routes exposed, templates and hooks connected.
Reached at Flask startup, when FeatureManager(app).register_features() advances each feature automatically.
This is the only state observable by end users.
disabled
Installed (and possibly migrated) but not activated at runtime. Blueprints are not registered.
Useful for gradual rollout, feature flags, or experimental functionality.
See also
- State guards. Blocked operations and automatic transitions
- Manifest. How state is persisted