Skip to content

Capability Projection

Capabilities in Legato are not static feature flags. They are runtime projections of what operations are currently supported.

Capability is a shared contract union ('play', 'pause', 'stop', 'seek', 'skip-next', 'skip-previous'). It defines the allowed vocabulary.

getCapabilities() returns the current runtime projection:

  • Capability answers: “Which capability names exist in the model?”
  • getCapabilities().supported answers: “Which of those are supported now?”

This distinction matters because support can vary with runtime state and media context.

Capability is the vocabulary. getCapabilities() is the current projection.

A capability name being valid in the contract does not mean it is always available in runtime.

Product implication: UI should represent controls as conditional affordances that follow runtime projection, not as permanently enabled features.

Operational implication: integrations should re-read capability projection when playback context changes, instead of assuming setup-time support remains valid.

The contract explicitly documents seek as projector-owned runtime semantics, not queue-only inference.

Also, PlaybackSnapshot.duration explicitly says that a finite duration is evidence of media length, not a seekability guarantee by itself.

That means:

  • finite duration does not imply seek,
  • and seek should be enabled only when supported.includes('seek') is true.

In short: timeline metadata and action permissions are related but distinct signals.

The Capacitor and contract docs do not expose a deterministic mapping from track fields or playback states to capability outcomes.

What is explicitly guaranteed:

  • capabilities are read from getCapabilities() at runtime,
  • remote-seek is emitted only when projected seek capability is enabled.

So integrations should consume the projection directly instead of deriving capability support from inferred media traits.

Without assuming a public deterministic matrix, these are valid projection patterns:

  • A control is available for one active context and not available after a track/context transition.
  • A capability appears after runtime setup settles, then changes again when queue selection changes.
  • Two sessions with similar media metadata can still expose different projected support.

Your integration logic should stay correct under all three by treating projection as authoritative each time it is read.

  • Enabling controls from duration, state, or queue shape alone.
  • Caching capabilities once at app boot and never refreshing.
  • Interpreting absence of remote-seek emissions as proof that seek is globally unsupported.
  • Using indirect heuristics (track fields, guessed platform rules) instead of getCapabilities().supported.