TaskTonic Lifecycle Architecture

This document details the lifecycle management, hierarchy, and initialization protocols of the TaskTonic framework. At the core of this architecture is ttLiquid, the base class for all active components.
The framework utilizes an explicit state machine (ttLC - TaskTonic Life Cycle) to guarantee deterministic initialization, thread-safe service resolution, and secure memory cleanup, even when dealing with complex Multiple Inheritance (MRO) and C++ bindings like PySide.
1. Core Parameters & Hierarchy
Every TaskTonic component is automatically embedded into the TaskTonic hierarchy by the ttLiquid class and receives three fundamental parameters upon creation:
id(Integer): A unique identifier guaranteed by the centralttLedger.name(String): A human-readable identifier. If not explicitly provided, the framework generates one based on theidand class name (e.g.,01.MyComponent). Names are reserved in thettLedger.life_cycle(ttLC Enum): The current state of the object (e.g.,NEW,CREATE,STATIC,FINISHED).
The Hierarchy (Bases and Infusions)
TaskTonic operates on a contextual hierarchy. When a liquid is created, it automatically detects its calling context via the ttSparkleStack.
base: The parent liquid that instantiated this component.infusions: A list of child components (subjects) created by this liquid. When a base finishes, it cascades the finish command to all its infusions.
2. Configuration Flags (_tt_...)
Developers can control the initialization behavior of a ttLiquid declaratively by setting class-level flags. The framework strongly prefers these explicit flags over dynamic parameter injection via super().__init__().
Service & Hierarchy Flags
_tt_is_service(bool | str): Marks the class as a Singleton Service. IfTrue, a generic service is created (requiresnameupon instantiation). If a string is provided, the service is rigidly bound to that name._tt_base_liquid(bool): IfTrue, this component refuses to attach to abase(parent context) and acts as an independent root liquid in the hierarchy.
Forcing Attributes (Fail-Fast Configuration)
_tt_force_name(str): Hardcodes the name of the component. If a developer attempts to pass a different name during instantiation, the framework raises aRuntimeError._tt_force_log_mode(ttLog): Hardcodes the logging level. Bypasses inherited log modes and prevents modifications viakwargs._tt_force_stealth_logging(bool): A convenience flag to permanently lock the logger toSTEALTHmode (no output), overriding all other settings.
3. Phase 1: Creation (NEW -> CREATE -> STATIC)
The creation phase is highly secured by the __ttLiquidMeta metaclass and the _tt_route_init router. This ensures that the framework infrastructure is fully operational before any user code is executed.
- Metaclass Interception (
NEW): The metaclass captures the instantiation and forces the execution through_tt_route_init. - Bootstrap (
CREATE): The router executes_bootstrap(). This is a one-time operation that: - Claims the
nameandidfrom the ledger. - Binds the object to its
base. - Initializes the
ttLoggerbased on the provided parameters or_tt_flags. - Inherits service dependencies.
- The
__init__Chain: The router triggers the Pythonsuper()chain. - Security: To protect against C++ MRO quirks (like PySide executing
__init__multiple times), the router tracks executed initializations in a_tt_executed_initsset. - Immutability: The router monitors
kwargs(nameandlog_mode). If a subclass attempts to alter these core parameters dynamically via a nestedsuper()call, aRuntimeErroris raised. - Finalization (
STATIC): The router cleans up temporary tracking variables, logs the creation phase, and transitions the state toSTATIC.
4. Phase 2: Services (STATIC & SPARKLING)
When a developer requests a component flagged with _tt_is_service, the ttLedger checks if it already exists.
If it exists, the __new__ method intercepts the creation and returns the existing instance. The router detects that the object is already STATIC (or active) and executes _tt_handle_existing_service() instead of rebooting the object.
- The existing service registers the calling liquid as a new contextual base (added to
service_bases). - It fires the
_tt_init_service_basehook, allowing the service to react to the new context.
5. Phase 3 & 4: Finish and Detachment
(Note: The full cascading finish logic for asynchronous tonics is currently under development. The following applies to the core synchronous liquid destruction).
When a liquid is done, it calls finish().
- Cascading: The liquid commands all its
infusions(children) to finish. - Unregistering: Once all infusions are completed, the liquid detaches from its
baseand unregisters itsidfrom thettLedger. - The Shell (
ttFinishedLiquid): To prevent dangling references and memory leaks (especially critical for large data or UI components), the object undergoes a forced mutation.
The ttFinishedLiquid Security Shell
Upon completion, the framework replaces the object's class with ttFinishedLiquid and clears its internal __dict__. The object transitions to the DETACHED state.
This has strict consequences:
- Memory Cleared: All internal variables (dataframes, widget references) are instantly garbage-collected.
- Fail-Fast Data Access: Any attempt to read or write attributes (e.g.,
my_liquid.some_data = 5) raises a hardAttributeError. - Safe Sparkle Blocking: If an external system (like an async timer or a UI event) attempts to fire a method registered in the
sparkleswhitelist, the shell intercepts it. Instead of crashing the application, it: - Returns a harmless
_noop(No Operation). - Logs a
WARNING. - Safely triggers the
ttse__on_system_errorhook in the calling tonic to gracefully handle the stale event. - Idempotency: Requesting the
idof a finished liquid will safely and permanently return-1.