Repository navigation
Runtime Lifecycle
The runtime lifecycle is owned by ForsettiRuntime and ModuleManager. ForsettiRuntime is the host-facing orchestrator. ModuleManager is the activation authority for discovery, compatibility, entitlement, module identity, UI surface state, and activation persistence.
sequenceDiagram
participant Host as Host application
participant Runtime as ForsettiRuntime
participant Manager as ModuleManager
participant Loader as ManifestLoader
participant Registration as ModuleRegistrationService
participant Requirements as ModuleRequirementValidator
participant Store as ActivationStore
Host->>Runtime: boot()
Runtime->>Manager: discoverManifests(manifestDirectory)
Manager->>Loader: loadManifests(directory)
Loader-->>Manager: validated manifests by moduleID
Manager->>Registration: confirm discovered manifests
Runtime->>Manager: restorePersistedActivation()
Manager->>Store: loadState()
Store-->>Manager: ActivationState
Manager->>Manager: restore service modules
Manager->>Manager: restore selected UI/app module last
Manager->>Store: save reconciled state
Runtime-->>Host: booted
Boot does not invent modules. It loads manifests, restores persisted activation state when possible, and records restore failures for diagnostics.
stateDiagram-v2
[*] --> Discovered
Discovered --> Registered: canonical manifest confirmed
Registered --> Compatible: schema/platform/version/policy pass
Compatible --> Entitled: moduleID or product ID unlocked
Entitled --> RequirementsSatisfied: runtime requirements pass
RequirementsSatisfied --> Resolved: registry factory returns module
Resolved --> Validated: descriptor and bundled manifest match
Validated --> ActiveService: service start succeeds
Validated --> ActiveUI: UI/app surface setup and start succeed
ActiveService --> Inactive: deactivate
ActiveUI --> Inactive: deactivate or replacement
Discovered --> Rejected: missing or stale registration
Compatible --> Rejected: compatibility error
Entitled --> Rejected: entitlement missing
RequirementsSatisfied --> Rejected: required service/default role/UI declaration failure
Resolved --> Rejected: missing factory
Validated --> Rejected: identity/type/version/manifest mismatch
ActiveUI --> Rejected: start or surface failure rollback
Activation proceeds in a fixed order:
| Step | Check | Failure Result |
|---|---|---|
| Manifest lookup |
moduleID exists in discovered manifests |
ModuleNotFound |
| Registration confirmation | Canonical manifest hash and registration record match | registration mismatch error |
| Compatibility | schema version, platform, framework version, capability policy | IncompatibleModule |
| Entitlement | unlocked by moduleID or iapProductID
|
EntitlementRequired |
| Runtime requirements | Required I/O, default roles, UI declarations, and data-isolation requirements are satisfiable | requirement validation error |
| Active state | module is not already loaded | AlreadyActive |
| Factory lookup |
entryPoint resolves in ModuleRegistry
|
ModuleNotFound |
| Descriptor validation | descriptor module ID, type, and version match activation manifest | identity/type/version errors |
| Bundled manifest validation | module-provided manifest matches activation manifest field-by-field | ModuleManifestMismatch |
| Runtime contract | UI/app manifests produce UI-capable modules; app manifests also satisfy the app marker | ModuleTypeMismatch |
| UI contribution validation | contributions match granted capabilities and declared schema 1.1 UI IDs |
CapabilityDenied or UI declaration error |
UI and app modules share one active surface slot. Activating a new UI/app module replaces the previous one only after the incoming surface and module start path succeeds.
sequenceDiagram
participant Manager as ModuleManager
participant Incoming as Incoming UI/app module
participant Previous as Previous UI/app module
participant Surface as UISurfaceManager
participant Store as ActivationStore
Manager->>Incoming: uiContributions()
Manager->>Manager: validate capabilities
Manager->>Manager: validate declared UI IDs and policy-approved theme masks
opt previous active module
Manager->>Surface: remove previous contributions
end
Manager->>Surface: add incoming contributions
Manager->>Surface: rebuildSurfaceState()
Manager->>Incoming: start(scoped context)
opt previous active module
Manager->>Previous: stop(previous context)
Manager->>Manager: unload previous module
end
Manager->>Manager: activeUIModuleID = incoming
Manager->>Store: saveState()
If surface setup, incoming start, or previous stop fails, the manager attempts to stop the incoming module and restore the previous surface state. The previously active UI/app module remains the selected active module when rollback succeeds.
Service modules are simpler:
- Validate manifest and entitlement.
- Resolve and validate the module instance.
- Validate required runtime requirements.
- Create a capability-scoped module context.
- Call
start(context). - Add the module ID to
enabledServiceModuleIDs. - Persist state.
Service modules can run concurrently without a fixed upper limit.
flowchart TD
Start["deactivateModule(moduleID)"]
Loaded{"loaded?"}
Stop["module.stop(context)"]
RemoveSets["remove from enabled sets"]
UI{"active UI/app?"}
Surface["remove UI contributions\nrebuild surface"]
Unload["erase module and context"]
Persist["save activation state"]
Error["throw NotActive"]
Start --> Loaded
Loaded -- no --> Error
Loaded -- yes --> Stop
Stop --> RemoveSets
RemoveSets --> UI
UI -- yes --> Surface
UI -- no --> Unload
Surface --> Unload
Unload --> Persist
restorePersistedActivation() returns an ActivationRestoreResult:
| Field | Meaning |
|---|---|
restoredModuleIDs |
Modules successfully restored. |
failures |
Module IDs and diagnostic messages for restore failures. |
succeeded() |
true when no failures were recorded. |
Restore behavior is intentionally reconciliatory: modules that cannot be restored are omitted from the newly persisted activation state.
When entitlements change, ForsettiRuntime::reconcileActiveModulesWithEntitlements() deactivates active modules that no longer satisfy entitlement requirements. This prevents a previously unlocked module from remaining active after access is revoked.
Forsetti Framework - Windows. Proprietary. Patent Pending. Repository: https://github.com/flynn33/Forsetti-Framework-Windows