Exploring your product

Use SPLENT’s inspection tools to understand how features are composed, ordered, and validated.


Table of contents

  1. Prerequisites
  2. Feature status
  3. Feature load order
  4. Dependency impact
  5. Composition map (xray)
  6. Infrastructure check
  7. Product validation
  8. SPL queries
  9. Full diagnostic
  10. Where things live
  11. What you learned
  12. Next

Prerequisites

You completed Tutorial 1. my_first_app is selected and has auth, public, theme, settings, redis, session_redis and profile.

Tutorial 1 stopped the product. Start it again, which is much faster now that the images are built and the features cached.

splent product:select my_first_app
splent product:derive --dev

Feature status

splent feature:status

Every feature and its lifecycle state.

  Feature status — my_first_app
  ──────────────────────────────────────────────────────────────────
  Feature                                         Mode      Progress   State
  ──────────────────────────────────────────────────────────────────────────────
  splent_io/splent_feature_auth@v1.19.4           pinned    ●─●─●─●   active
  splent_io/splent_feature_profile@v1.5.7         pinned    ●─●─●─●   active
  splent_io/splent_feature_public@v1.8.0          pinned    ●─●─○─●   active
  splent_io/splent_feature_redis@v1.5.7           pinned    ●─●─○─●   active
  splent_io/splent_feature_session_redis@v1.1.2   pinned    ●─●─○─●   active
  splent_io/splent_feature_settings@v0.4.3        pinned    ●─●─●─●   active
  splent_io/splent_feature_theme@v0.13.4          pinned    ●─●─○─●   active

  ──────────────────────────────────────────────────────────────────────────────
  Progress: declared → installed → migrated → active
  Modes:    pinned = versioned release   editable = local development

  Last updated: <timestamp>

The lifecycle runs declared (in pyproject.toml) → installed (pip-installed) → migrated (tables created) → active (registered in Flask). All seven features are active because product:derive ran the whole pipeline. public, redis, session_redis and theme show ○ for the migrated step because they have no tables.


Feature load order

splent feature:order --short
  Feature load order — my_first_app
  ──────────────────────────────────────────────
  #    Feature                            Requires
  ──────────────────────────────────────────────
  1    splent_feature_auth                —
  2    splent_feature_profile             splent_feature_auth
  3    splent_feature_redis               —
  4    splent_feature_session_redis       splent_feature_redis
  5    splent_feature_settings            —
  6    splent_feature_theme               splent_feature_settings
  7    splent_feature_public              splent_feature_theme

  UVL: sample_splent_spl.uvl

Features depend on each other’s models, templates and hooks, so the order comes from the constraints of the UVL model. profile => auth loads profile after auth, session_redis => redis loads the session backend after Redis, and public => theme => settings loads the public pages after the site shell they are drawn in. Migrations run in the same order, so a feature’s tables are created after the tables they reference.


Dependency impact

feature:impact answers what happens if you remove a feature.

splent feature:impact auth
  feature:impact — auth
  Product: my_first_app
  UVL:     sample_splent_spl.uvl

  Depends on
    (none) — this feature is independent

  Depended on by
    ← profile  (direct)

  Removing auth would break 1 feature(s).

It reads the UVL constraints, but only for the features in this product. Depends on is what the feature needs, and Depended on by is what would break without it. Only profile depends on auth here. admin, confirmemail and reset also require auth, but they are not in this product. Each dependency is direct (declared in the UVL) or transitive (through another feature).

Try it with a leaf feature.

splent feature:impact profile
  feature:impact — profile
  Product: my_first_app
  UVL:     sample_splent_spl.uvl

  Depends on
    → auth  (direct)

  Depended on by
    (none) — safe to remove

  Removing profile has no impact on other features.

Nothing depends on profile, so it can be removed safely. Run this before feature:remove, or when you plan a new product.


Composition map (xray)

splent feature:xray

It prints the composition of your product. Product layout lists which hooks of base_template.html are filled and by which features, Features lists the hooks each feature shares with others, and Refinements lists what refinement features override (none yet).

  Feature X-Ray — my_first_app

  my_first_app (product layout)
      template: base_template.html
          hook: layout.sidebar.top  ← splent_feature_public
          hook: layout.anonymous_sidebar  ← splent_feature_auth
          hook: layout.authenticated_sidebar  ← splent_feature_auth, splent_feature_settings, splent_feature_theme
          hook: layout.sidebar.authenticated.items  ← splent_feature_profile
          hook: layout.navbar.anonymous  ← splent_feature_auth
          hook: layout.navbar.authenticated  ← splent_feature_auth, splent_feature_profile
          hook: layout.footer  ← splent_feature_auth
          hook: layout.scripts  ← splent_feature_auth, splent_feature_profile
                1 unused: layout.head.css

  splent_feature_auth
          hook: layout.authenticated_sidebar  ← splent_feature_settings, splent_feature_theme
          hook: layout.navbar.authenticated  ← splent_feature_profile
          hook: layout.scripts  ← splent_feature_profile

  splent_feature_profile
          hook: layout.navbar.authenticated  ← splent_feature_auth
          hook: layout.scripts  ← splent_feature_auth

  splent_feature_settings
          hook: layout.authenticated_sidebar  ← splent_feature_auth, splent_feature_theme

  splent_feature_theme
          hook: layout.authenticated_sidebar  ← splent_feature_auth, splent_feature_settings
          hook: layout.footer  ← splent_feature_auth
          hook: layout.nav.end  ← splent_feature_auth
          hook: layout.scripts  ← splent_feature_auth, splent_feature_profile

  splent_feature_public, splent_feature_redis, splent_feature_session_redis — no active refinements

  No refinements declared.

--full also lists every service, model, template and hook each feature declares as overridable. --validate checks the composition.

splent feature:xray --validate

It prints the same tree, then a summary.

  ── Validation ──

  ✅ All 8 checks passed.  (3 shared hook(s), 1 unused layout hook(s))

The eight checks cover service, model, route, blueprint, command and signal collisions, hook sharing and layout coverage. Shared hooks such as layout.navbar.authenticated, filled by both auth and profile, are fine, since hooks add up.


Infrastructure check

splent check:infra
  Infrastructure check

  Ports
  [OK] No port conflicts (4 ports declared)
  [OK] No conflicts with running containers

  Services
  [OK] No service name collisions (6 services)
  [OK] No container name collisions (5 named containers)

  Isolation
  [OK] 1 feature stack(s) isolate per product

  Networks
  [OK] Network 'my_first_app_network' exists

  Build contexts
  [OK] my_first_app/my_first_app_web: Dockerfile found

  Health checks
  [OK] 2 service(s) with health checks

  Volumes
  [OK] No volume name conflicts (3 volumes)

  All 9 checks passed.

It checks the product’s Docker setup without starting anything. It looks for port conflicts between the product and its features, ports taken by containers of other products, duplicate service and container names, networks, build contexts, health checks and volumes. Run it when you add a feature that brings Docker services of its own.


Product validation

splent product:validate
  Validating my_first_app...

  1. Configuration  (UVL — splent product:validate --only config)
     ✅ Feature selection is satisfiable (9 features)

  2. Compatibility  (contracts — splent product:validate --only compat)
     ✅ No collisions detected
     ℹ️  4 informational note(s)

  3. Dependencies  (imports — splent product:validate --only deps)
     ✅ All imports respect UVL constraints (7 checks)

  ✅ Product is valid.

Each check can run alone with --only.

  1. Configuration. The selection satisfies every constraint of the SPL (mandatory features present, profile => auth, exactly one session backend). The count of 9 includes the SPL root and the session_type group
  2. Compatibility. No two contracts claim the same route, model or service
  3. Dependencies. Every import from one feature into another is backed by a UVL constraint
  4. Refinement. No two features that modify another one (refiners, the topic of Tutorial 6) collide. Your product has none yet, so it reports No refiners in this product

SPL queries

These commands work on the SPL’s model, not on your product, so they need detached mode.

splent product:deselect

List all features defined in the SPL.

splent spl:features sample_splent_spl
SPL features
SPL      : sample_splent_spl
UVL      : /workspace/.splent_cache/spls/sample_splent_spl@v4/sample_splent_spl.uvl
Features : 17

- admin
- auth
- confirmemail
- mail
- mailhog
- nginx
- phpmyadmin
- profile
- public
- redis
- reset
- sample_splent_spl  (root)
- session_filesystem
- session_redis
- session_type
- settings
- theme

(root) is the SPL itself and session_type is the group of session backends. Neither is a feature you install.

Check what a feature depends on.

splent spl:deps profile sample_splent_spl
SPL deps
SPL      : sample_splent_spl
UVL      : /workspace/.splent_cache/spls/sample_splent_spl@v4/sample_splent_spl.uvl
Features : 17

Dependencies of 'profile' (features it requires):
- auth

See who depends on a feature (reverse lookup).

splent spl:deps auth sample_splent_spl --reverse
SPL deps
SPL      : sample_splent_spl
UVL      : /workspace/.splent_cache/spls/sample_splent_spl@v4/sample_splent_spl.uvl
Features : 17

Reverse dependencies of 'auth' (features that require it):
- admin
- confirmemail
- profile
- reset

spl:info sample_splent_spl tells you where the model is read from, its DOI and version on UVLHub, and which products pin it.

Select the product again.

splent product:select my_first_app

Full diagnostic

splent doctor --fast

It runs every health check in four groups and ends with a summary.

  • Environment. check:env (versions, .env, credentials), check:pyproject, check:docker, check:infra
  • Product. check:product (environment variables, links, configuration overrides, blueprints), check:features, feature:status
  • Services. product:containers and db:status
  • Credentials. check:forge and check:pypi

--fast skips the database and credential checks, which need the network. The two credential warnings of check:env (forge and PyPI tokens not set) are expected until you publish a feature for real, which Tutorial 5 makes optional. Run doctor whenever something feels off.


Where things live

File Purpose
my_first_app/pyproject.toml Feature declarations, SPL reference and its DOI, layout hooks
.splent_cache/spls/ UVL models downloaded on demand from UVLHub by DOI
splent_spl_sample_splent/ Your working copy of sample_splent_spl, which wins over the cache. The directory drops the _spl suffix of the model name. spl:add-feature creates it the first time you edit the model, in Tutorial 3, Step 7
my_first_app/splent.manifest.json Lifecycle state of every feature
.splent_cache/features/ Read-only clones of pinned feature versions
my_first_app/features/splent_io/ Symlinks to cached or editable features
my_first_app/docker/ Docker Compose files, Dockerfiles, .env files

What you learned

Tool Purpose
feature:status Lifecycle state of every feature
feature:order UVL-resolved load order
feature:impact Dependency impact analysis (what breaks if removed)
feature:xray Full composition map
feature:xray --validate Validate extensibility (collisions, hooks, refinements)
check:infra Docker port/container/network validation
product:validate Check configuration, contracts and imports against the SPL
spl:features / spl:deps / spl:info Query the SPL model
doctor Comprehensive health check

Next

Continue with Tutorial 3, Create a feature, to build a note-taking feature from scratch.


Back to top

splent. Distributed by an LGPL license v3. Contact us: drorganvidez@us.es