Feature lifecycle

In SPLENT, a feature is not just a Python module or a folder inside a product.
It is a first-class unit in the product line, with an explicit lifecycle that spans configuration, installation, database evolution, and runtime activation.

This section describes the complete lifecycle of a feature within a SPLENT product.

Table of contents

  1. Overview
  2. 1. Declared
  3. 2. Selected
  4. 3. Resolved
  5. 4. Installed
  6. 5. Migrated
  7. 6. Active
  8. Optional states
    1. Disabled
    2. Removed
  9. Conceptual model

Overview

A feature in SPLENT moves through a series of well-defined states:

Declared → Selected → Resolved → Installed → Migrated → Active

Some transitions are reversible (e.g., disabling a feature), while others may require careful rollback (e.g., database changes).


1. Declared

A feature is declared when it is defined in the product’s pyproject.toml under the [features] section.

At this stage:

  • The feature exists conceptually.
  • It has a namespace.
  • It may define dependencies on other features.
  • It is not yet part of the product build.

No code is installed. No migrations are executed.
This is a configuration-level state.


2. Selected

A feature becomes selected when it is explicitly enabled for a specific product.

This typically happens by:

  • Adding it to the product configuration.
  • Synchronizing with splent product:sync.

At this stage:

  • The feature is part of the desired product configuration.
  • Dependency resolution has not yet been applied.
  • The system still needs to compute the final feature set.

3. Resolved

During resolution, SPLENT:

  • Expands transitive dependencies.
  • Validates constraints.
  • Detects conflicts.
  • Computes the final closed set of features for the product.

This state ensures structural consistency before any installation or execution occurs.

No runtime effects happen yet.


4. Installed

A feature becomes installed when its technical artifacts are integrated into the environment.

This may include:

  • Installing Python dependencies.
  • Downloading the feature into .splent_cache.
  • Preparing assets.
  • Preparing migrations.
  • Generating environment variables.

This state is typically reached after:

splent product:sync
splent product:env --generate
splent product:up

At this point, the feature exists physically in the product environment.


5. Migrated

If a feature defines database models, it includes migrations.

When:

splent product:run

or the migration step is executed, the feature reaches the migrated state:

  • Tables are created.
  • Schema changes are applied.
  • Persistent storage reflects the feature’s presence.

This state affects data and must be handled carefully when removing features.


6. Active

A feature is active at runtime when:

  • Its blueprints are registered.
  • Its routes are exposed.
  • Its templates participate in overrides.
  • Its signals and hooks are connected.
  • Its configuration is loaded.

At this stage, the feature influences the observable behaviour of the product.

This is the only state visible to end users.


Optional states

Disabled

A feature may be installed but not activated at runtime.

This allows:

  • Gradual rollout.
  • Experimental features.
  • Controlled activation strategies.

The database may still contain its schema.


Removed

When a feature is removed:

  • It is deleted from the configuration.
  • Its dependencies may be recalculated.
  • Its migrations may need rollback.
  • Its data may require manual handling.

This is the most delicate operation in the lifecycle.


Conceptual model

The lifecycle can be understood as a layered progression:

Configuration → Resolution → Installation → Persistence → Runtime

This explicit lifecycle is what differentiates SPLENT from a conventional web framework with plugins.
In SPLENT, features are managed as structured variability units rather than simple importable modules.