Skip to content

πŸ“˜ Technical Design 021 β€” Application Entry Point and Bootstrap Orchestration

Field Value
ID TD-021
Title Application Entry Point and Bootstrap Orchestration
Status Completed
Owner Contributors
Audience Contributors, maintainers, DI system users
Created 2025-10-11
Last Updated 2025-10-12
Completion 2025-10-12
Reviewers TBD
Approvers TBD
Tracking Phase 7 of DI Roadmap
Related TD-013 (Module Scanning), TD-020 (Bootstrap Runtime), TD-012 (Enhanced Annotations)

🧭 1. Summary

This design introduces application-level orchestration for DI container bootstrap, providing a standardized entry point pattern for configuring and launching applications with automatic service discovery. Building on TD-013's scanning infrastructure and TD-020's bootstrap runtime, this design adds the @application decorator, an ApplicationRuntime coordinator, and an ApplicationBase contract that promotes constructor injection and a single run() lifecycle method.

At a glance:

  • @application decorator marks application entry points with declarative scanning configuration
  • ApplicationRuntime.launch("module:Class") bootstraps the container, resolves the application, and invokes run()
  • ApplicationBase defines the lifecycle contract (run(self) -> None) for DI-managed applications
  • Integration with TD-013 BootstrapPlanBuilder and TD-020 BootstrapRuntime for automatic service discovery and bootstrap execution
  • Observability currently relies on container/bootstrap metrics, with room to extend runtime-specific signals later

πŸ“š 2. Context and Problem Statement

With TD-013 providing module scanning and TD-020 externalizing bootstrap orchestration, the DI framework has the building blocks for automatic service discovery. However, there's no standardized way to configure and launch applications. Users must manually compose scanning, plan building, and bootstrap steps.

Phase 1-5 provides registration, bootstrapping, injection, annotations, and scanning, but application setup remains manual:

# Must manually compose scanning and bootstrap
scanner = DiPackageScanner(reflection)
plan_builder = BootstrapPlanBuilder()

# Manual scanning
plan = plan_builder.scan_packages(["myapp.services", "myapp.repositories"])

# Manual bootstrap
runtime = BootstrapRuntime()
container = DiContainer()
runtime.bootstrap(container, plan)

# Manual lifecycle
app = MyApplication()
app.run(container)

Key limitations:

  1. No Standardized Entry Point - No declarative way to mark application classes with configuration
  2. Manual Orchestration Required - Developers must manually wire scanning, planning, and bootstrap
  3. Container Exposure - Applications must accept the container to obtain dependencies, increasing coupling
  4. Limited Observability - Bootstrap and runtime metrics are scattershot across ad-hoc orchestration

2.1 Goals

  1. Declarative Entry Point - @application decorator for marking application classes with scanning configuration
  2. Automatic Orchestration - ApplicationRuntime coordinates the complete bootstrap workflow via module path resolution
  3. Lifecycle Simplicity - Standard run() method executed on a DI-managed ApplicationBase subclass (no container exposure)
  4. Integration with TD-013 - Leverage BootstrapPlanBuilder scanning methods for service discovery
  5. Integration with TD-020 - Use BootstrapRuntime for all bootstrap coordination
  6. Zero-Boilerplate Startup - Single function call launches fully configured application using "module:Class" path strings
  7. Embedded Observability - Capture bootstrap, resolution, and runtime metrics without additional user code

2.2 Non-Goals (Out of Scope)

  • Configuration file format or external configuration loading (future TD)
  • Profile-based configuration selection (e.g., dev/staging/prod profiles)
  • Application server integration (web frameworks, ASGI/WSGI servers)
  • Hot-reload or development mode features
  • Multi-container or distributed application patterns

2.3 Assumptions and Constraints

  • TD-013 BootstrapPlanBuilder with scanning methods is available
  • TD-020 BootstrapRuntime and BootstrapPlan are implemented
  • TD-012 annotation processing infrastructure is available
  • Applications have a single entry point class marked with @application
  • Scanning happens once at application startup (not runtime discovery)
  • Container lifecycle is owned by ApplicationRuntime, not the application class

🧩 3. Design Overview

The application entry point system provides standardized orchestration for DI container bootstrap, enabling "convention over configuration" application setup. The design introduces a declarative @application decorator, the ApplicationRuntime coordinator, and an ApplicationBase contract that relies on constructor injection and a single run() lifecycle method.

3.1 Key Components

Component Purpose
@application Decorator marking application classes with scanning configuration and bootstrap options
ApplicationRuntime Coordinator that resolves "module:Class" paths, orchestrates bootstrap, and executes the application
ApplicationBase Minimal lifecycle contract (run(self) -> None) implemented by container-managed applications
ApplicationConfiguration Metadata captured by the decorator and consumed by the runtime

3.2 Architecture

graph TB
    subgraph Definition
        DEC["@application"] --> CFG[ApplicationConfiguration]
        DEC --> APP[ApplicationBase]
    end

    subgraph Runtime
        RT["ApplicationRuntime.launch()"] --> RES[Module Resolver]
        RES --> APP
        RT --> CFG
        RT --> BPB[BootstrapPlanBuilder]
        RT --> BR[BootstrapRuntime]
    end

    subgraph Execution
        BR --> CON[DiContainer]
        CON --> INST[Resolved Application]
        INST --> RUN["run()"]
    end

    classDef node fill:none,stroke:#1976D2,stroke-width:2px,color:#1976D2
    classDef exec fill:none,stroke:#1976D2,stroke-width:2px,color:#1976D2

    class DEC,CFG,APP,RT,RES,BPB,BR,CON node
    class INST,RUN exec

3.3 Observability

  • Existing ContainerMetrics and BootstrapMetrics (TD-020) already capture the critical timings exercised by the runtime.
  • Application-specific telemetry is deferred; future work may layer module/class identifiers if gaps remain.
  • Failures propagate module path and class context to enable logging/alerting without exposing the container.

3.4 Interface Impact (Before β†’ After)

Area Before (Manual) After (Application Entry Point)
Application Setup Manual scanning + plan building + bootstrap ApplicationRuntime.launch("myapp.entry:App")
Dependency Access .run(container) accepts container directly Constructor/autowired injection on ApplicationBase subclass
Lifecycle Control Custom bootstrap workflows Standard run() lifecycle method
Observability Ad-hoc logging Reuse ContainerMetrics/BootstrapMetrics; future runtime signals optional

3.5 Removal/Deprecation Policy

  • Alpha stage: No deprecation period for new features
  • Migration strategy: Manual bootstrap workflows remain supported; new entry point pattern is additive
  • Test updates: All new tests covering application startup will use the runtime-based entry point pattern
  • Documentation: User guides will demonstrate both manual and runtime entry point approaches

πŸ“ 4. Implementation Details

4.1 Application Contract

from dataclasses import dataclass
from typing import Callable, Sequence, TypeVar

from loryth.common.annotations import Annotation
from loryth.common.annotations import AnnotationContext

ApplicationT = TypeVar("ApplicationT", bound="ApplicationBase")


@dataclass(frozen=True)
class ApplicationConfiguration:
    """Configuration captured by @application decorator.

    :param scan_packages: Import paths to scan for annotated services.
    :type scan_packages: Sequence[str]
    :param exclude_packages: Packages to exclude during scanning.
    :type exclude_packages: Sequence[str]
    :param validate_dependencies: Whether dependency graphs are validated.
    :type validate_dependencies: bool
    :param eager_prepare: Whether singletons are eagerly prepared.
    :type eager_prepare: bool
    """

    scan_packages: Sequence[str]
    exclude_packages: Sequence[str] = ()
    validate_dependencies: bool = True
    eager_prepare: bool = True


class ApplicationError(Exception):
    """Raised when application orchestration fails."""


class ApplicationAnnotation(Annotation):
    """Annotation storing application configuration metadata."""

    def __init__(self, config: ApplicationConfiguration) -> None:
        """Initialize the application annotation.

        :param config: Application configuration extracted from the decorator.
        :type config: ApplicationConfiguration
        """
        super().__init__(name="application")
        self.config = config


class ApplicationBase:
    """Base class for DI-managed application entry points."""

    def run(self) -> None:
        """Start the application.

        Dependencies are provided via injection.

        :raises NotImplementedError: If a subclass does not implement the method.
        """
        raise NotImplementedError


def application(
    *,
    scan_packages: Sequence[str],
    exclude_packages: Sequence[str] = (),
    validate_dependencies: bool = True,
    eager_prepare: bool = True,
) -> Callable[[type[ApplicationT]], type[ApplicationT]]:
    """Decorator capturing application configuration metadata.

    :param scan_packages: Packages to include during discovery.
    :type scan_packages: Sequence[str]
    :param exclude_packages: Packages removed from discovery.
    :type exclude_packages: Sequence[str]
    :param validate_dependencies: Toggle for dependency validation.
    :type validate_dependencies: bool
    :param eager_prepare: Toggle for eager singleton preparation.
    :type eager_prepare: bool
    :return: Decorated application class.
    :rtype: type[ApplicationT]
    """

    def decorator(cls: type[ApplicationT]) -> type[ApplicationT]:
        """Attach application configuration metadata to the decorated class.

        :param cls: Application class being decorated.
        :type cls: type[ApplicationT]
        :return: Annotated application class.
        :rtype: type[ApplicationT]
        """
        config = ApplicationConfiguration(
            scan_packages=scan_packages,
            exclude_packages=exclude_packages,
            validate_dependencies=validate_dependencies,
            eager_prepare=eager_prepare,
        )
        AnnotationContext.annotate(cls, ApplicationAnnotation(config))
        return cls

    return decorator
  • ApplicationBase provides a minimal interface: applications override run() and rely on constructor or autowired injection (the container itself is never passed).
  • ApplicationConfiguration holds decorator metadata; we continue to assume a single decorated class per module and resolve it by convention.
  • The @application decorator reuses loryth.common.annotations (same infrastructure as @service) to attach metadata via ApplicationAnnotation.

4.2 Runtime Orchestration

from importlib import import_module

from loryth.common.annotations import find_annotation
from loryth.common.di.bootstrap import BootstrapPlanBuilder, BootstrapRuntime
from loryth.common.di.container import Container


class ApplicationRuntime:
    """Coordinates bootstrap runtime and application execution."""

    def __init__(self, bootstrap_runtime: BootstrapRuntime | None = None) -> None:
        """Create an application runtime coordinator.

        :param bootstrap_runtime: Optional runtime used to execute bootstrap stages.
        :type bootstrap_runtime: BootstrapRuntime | None
        """
        self._bootstrap_runtime = bootstrap_runtime or BootstrapRuntime()

    @classmethod
    def launch(cls, path: str, *, bootstrap_runtime: BootstrapRuntime | None = None) -> None:
        """Convenience helper that creates a runtime and executes the application.

        :param path: Dotted module path in ``module:Class`` format.
        :type path: str
        :param bootstrap_runtime: Optional runtime used for bootstrap orchestration.
        :type bootstrap_runtime: BootstrapRuntime | None
        :raises ApplicationError: If the application cannot be resolved or started.
        """
        runtime = cls(bootstrap_runtime=bootstrap_runtime)
        runtime.run(path)

    def run(self, path: str) -> None:
        """Bootstrap, resolve, and execute an application entry point.

        :param path: Dotted module path in ``module:Class`` format.
        :type path: str
        :raises ApplicationError: If resolution or execution fails.
        """
        application_type = self._resolve_application(path)
        config = self._read_configuration(application_type)
        container = self._bootstrap_container(config)

        application = container.resolve(application_type)
        application.run()

    def _resolve_application(self, path: str) -> type[ApplicationBase]:
        """Load the application class from a module path.

        :param path: Dotted module path in ``module:Class`` format.
        :type path: str
        :raises ApplicationError: If the module or class cannot be located.
        :return: Application class that inherits from ``ApplicationBase``.
        :rtype: type[ApplicationBase]
        """
        try:
            module_path, class_name = path.split(":")
            module = import_module(module_path)
            application = getattr(module, class_name)
        except (ValueError, AttributeError, ModuleNotFoundError) as exc:
            raise ApplicationError(f"Cannot resolve application entry point '{path}': {exc}") from exc

        if not issubclass(application, ApplicationBase):
            raise ApplicationError(f"Application '{path}' must inherit from ApplicationBase")

        return application

    def _read_configuration(self, application_type: type[ApplicationBase]) -> ApplicationConfiguration:
        """Read configuration metadata attached by @application.

        :param application_type: Application class being resolved.
        :type application_type: type[ApplicationBase]
        :raises ApplicationError: If the application annotation is missing.
        :return: Configuration declared via the ``@application`` decorator.
        :rtype: ApplicationConfiguration
        """
        annotation = find_annotation(application_type, ApplicationAnnotation)
        if annotation is None:
            raise ApplicationError(
                f"Application '{application_type.__module__}:{application_type.__name__}' is missing @application metadata",
            )
        return annotation.config

    def _bootstrap_container(self, config: ApplicationConfiguration) -> Container:
        """Execute bootstrap plan based on decorator metadata.

        :param config: Application configuration extracted from annotations.
        :type config: ApplicationConfiguration
        :return: Container prepared with all discovered services.
        :rtype: Container
        """
        plan_builder = BootstrapPlanBuilder.create()
        plan = plan_builder.scan_packages(
            config.scan_packages,
            exclude=config.exclude_packages,
        ).build()

        container = Container()
        self._bootstrap_runtime.bootstrap(
            container,
            plan,
            validate_dependencies=config.validate_dependencies,
            eager_prepare=config.eager_prepare,
        )

        return container
  • ApplicationRuntime.launch("test.service.app:Application") resolves the class, reads decorator metadata via annotations, bootstraps the container, and executes run().
  • Advanced scenarios can still instantiate ApplicationRuntime directly to supply custom bootstrap runtimes or instrumentation.
  • Package scanning remains declarative through @application; runtime does not keep an explicit reference to the container once execution starts.
  • Long-running behavior (e.g., schedulers, HTTP servers) is delegated to injected services; threading/async orchestration will arrive in a future TD.

4.3 Lifecycle Flow

@application(scan_packages=["orders.services"])
class OrderApplication(ApplicationBase):
    """Launch order-processing services."""

    def __init__(
        self,
        http_server: HttpServer,
        scheduler: JobScheduler,
        consumer: MessageConsumer,
    ) -> None:
        """Store injected services required by the application.

        :param http_server: HTTP server responsible for serving APIs.
        :type http_server: HttpServer
        :param scheduler: Scheduler that manages background jobs.
        :type scheduler: JobScheduler
        :param consumer: Message consumer handling inbound events.
        :type consumer: MessageConsumer
        """
        self._http_server = http_server
        self._scheduler = scheduler
        self._consumer = consumer

    def run(self) -> None:
        """Start all long-running services."""
        self._consumer.start()       # RabbitMQ consumer owns its thread
        self._scheduler.start()      # Scheduler manages its own worker pool
        self._http_server.start()    # Web server blocks the main thread
  1. @application persists metadata for runtime consumption.
  2. ApplicationRuntime.launch() bootstraps and resolves OrderApplication.
  3. Dependencies arrive through constructor injection; run() coordinates service startup without container access.

4.4 Error Handling

class SafeApplication(ApplicationBase):
    """Fails fast when startup prerequisites are missing."""

    def __init__(self, health_check: StartupHealthCheck) -> None:
        """Store the injected health check dependency.

        :param health_check: Service that validates environment readiness.
        :type health_check: StartupHealthCheck
        """
        self._health_check = health_check

    def run(self) -> None:
        """Verify readiness and emit clear diagnostics.

        :raises ApplicationError: If the application fails to start.
        """
        if not self._health_check.is_ready():
            raise ApplicationError("Startup health check failed")

        try:
            self._start_components()
        except Exception as exc:  # noqa: BLE001 - surfaced via ApplicationError
            raise ApplicationError(f"Application startup failed: {exc}") from exc

    def _start_components(self) -> None:
        """Private helper invoked during run().

        :raises ApplicationError: If a component fails during startup.
        """
        ...
  • Decorator or module resolution failures raise ApplicationError before bootstrapping begins.
  • Exceptions from BootstrapRuntime propagate with application context for debugging.
  • Applications can raise ApplicationError directly to surface startup issues with clear messaging.

4.5 Observability

  • ApplicationRuntime leans on ContainerMetrics and BootstrapMetrics; no new counters are introduced in this phase.
  • Additional runtime-specific measurements (e.g., resolution or run() duration) are deferred until concrete needs surface.

βš™οΈ 5. Semantics

5.1 Parameter Ordering Conventions

  • @application parameters follow scan_packages β†’ additional_config pattern
  • run() is parameterless; dependencies are delivered by DI construction
  • Error messages include application class name for context

5.2 Error Handling Strategies

  • Failures during scanning or bootstrap are fatal and terminate startup
  • Exceptions escaping run() are wrapped with module path and application class context
  • All errors include the application class name for debugging

5.3 Threading Behavior

  • Application bootstrap is synchronous and single-threaded
  • Lifecycle methods should handle their own threading requirements
  • Container is thread-safe after bootstrap completion

5.4 Observability Considerations

  • ApplicationRuntime emits bootstrap, resolution, and run timings to the shared metrics pipeline
  • Metric payloads include module path and application class name for correlation
  • Error events capture phase information to aid alert routing

πŸ§ͺ 6. Examples

6.1 Constructor and Autowired Injection

from typing import Protocol

from loryth.common.di.application import ApplicationBase, ApplicationRuntime, application
from loryth.common.di.injection import autowired


class InventoryApi(Protocol):
    """Protocol for the inventory HTTP API."""

    def start(self) -> None: ...


class LoggerProtocol(Protocol):
    """Protocol for structured logging."""

    def info(self, message: str) -> None: ...


@application(scan_packages=["myapp.services"])
class InventoryApplication(ApplicationBase):
    """Launches the inventory API with injected dependencies."""

    def __init__(self, api: InventoryApi) -> None:
        self._api = api
        self._logger: Annotated[LoggerProtocol, Autowired("inventory")]

    def run(self) -> None:
        """Start the API service."""
        self._logger.info("Starting inventory service")
        self._api.start()


if __name__ == "__main__":
    ApplicationRuntime.launch("myapp.entry:InventoryApplication")
  • Constructor injection provides the primary API dependency.
  • Autowired property resolves a qualified logger without exposing the container.
  • The runtime loads the class from its module path and invokes run().

6.2 Coordinating Long-Running Services

from loryth.common.di.application import ApplicationBase, ApplicationRuntime, application


@application(scan_packages=["payments.services"])
class PaymentApplication(ApplicationBase):
    """Coordinates background services that manage their own threads."""

    def __init__(
        self,
        consumer: PaymentConsumer,
        scheduler: ReconciliationScheduler,
        api: PaymentsApi,
    ) -> None:
        self._consumer = consumer
        self._scheduler = scheduler
        self._api = api

    def run(self) -> None:
        """Launch long-running components."""
        self._consumer.start()       # RabbitMQ consumer owns its thread
        self._scheduler.start()      # Scheduler manages its worker pool
        self._api.serve_forever()    # Blocking HTTP server call


if __name__ == "__main__":
    ApplicationRuntime.launch("payments.app:PaymentApplication")
  • Each injected dependency owns its concurrency model.
  • run() simply coordinates startup order, aligning with the design’s β€œapplication spins up services” guidance.

6.3 CLI-Oriented Application

import argparse

from loryth.common.di.application import ApplicationBase, ApplicationRuntime, application


@application(scan_packages=["reports.services"])
class ReportCli(ApplicationBase):
    """Generates reports from the command line."""

    def __init__(self, generator: ReportGenerator) -> None:
        self._generator = generator

    def run(self) -> None:
        """Parse CLI arguments and execute the command."""
        parser = argparse.ArgumentParser()
        parser.add_argument("--output", required=True)
        options = parser.parse_args()

        self._generator.generate(output_path=options.output)


if __name__ == "__main__":
    ApplicationRuntime.launch("reports.cli:ReportCli")
  • CLI applications still return None; exit codes remain the responsibility of the entry script.
  • Dependencies (e.g., ReportGenerator) are injected, enabling focused unit tests of run().

πŸ§ͺ 7. Test Matrix

7.1 Unit Coverage

tests/unit/di/application/
β”œβ”€β”€ test_application_decorator.py        # @application metadata capture
β”œβ”€β”€ test_application_runtime.py          # launch() error handling and flow control
└── test_application_configuration.py    # Validation of ApplicationConfiguration defaults

Unit Test Focus: - Decorator metadata storage and validation (including missing config failures) - Module-path resolution and error propagation within ApplicationRuntime - Container bootstrap delegation (mocks/stubs for TD-013 and TD-020 components) - Static launch helper delegating to instance runtime

7.2 Integration Coverage

tests/integration/di/
β”œβ”€β”€ test_application_launch.py      # End-to-end launch via runtime helper
β”œβ”€β”€ test_application_injection.py   # Constructor + autowired injection flows
└── test_runtime_container_bridge.py   # Coordination with bootstrap/container components

Integration Test Focus: - Complete application startup via "module:Class" paths - Interaction between runtime, BootstrapPlanBuilder, and BootstrapRuntime - Validation that container/bootstrap metrics remain available for instrumentation - Compatibility with long-running services (simulated asynchronous components)

7.3 Regression Coverage

tests/regression/di/
β”œβ”€β”€ test_manual_bootstrap_compat.py  # Manual bootstrap remains functional
└── test_entrypoint_migration.py    # Migration from manual to runtime entry points

Regression Test Focus: - Ensuring manual bootstrap paths remain untouched - Validating migration guides and mixed usage scenarios - Guarding against breaking changes in decorator metadata format - Sustaining compatibility with TD-013 scanning behavior

Testing Notes: - Unit tests isolate runtime components via fakes for plan builders and bootstrap runtime. - Integration tests rely on full implementations to verify discovery and injection. - Regression tests blend manual and runtime flows to confirm interoperability.

βœ… 8. Acceptance Criteria

Note: Use this checklist to verify conformance when reviewing PRs.

  • @application decorator persists ApplicationConfiguration metadata on the class
  • ApplicationRuntime.launch(path: str) resolves the decorated class and executes run()
  • Applications inherit from ApplicationBase and expose only run(self) -> None
  • Runtime integrates with TD-013 scanning and TD-020 bootstrap execution
  • Validation errors (missing metadata, bad module path) raise ApplicationError
  • Annotation metadata is attached/retrieved via loryth.common.annotations utilities
  • Comprehensive test coverage (unit, integration, regression) exercises constructor + autowired injection
  • Migration and user documentation demonstrate "module:Class" launch semantics
  • Manual bootstrap workflows remain supported and tested

πŸš€ 9. Rollout and Migration

9.1 Implementation Phases

Phase 1: Core Contracts - Define ApplicationBase, ApplicationConfiguration, ApplicationError, and ApplicationAnnotation - Implement @application decorator using AnnotationContext for metadata storage - Validate annotated classes inherit from ApplicationBase - Outcome: Application contract and decorator established

Phase 2: Runtime Orchestration - Implement ApplicationRuntime.run() instance workflow with module resolution, configuration lookup, and bootstrap integration - Provide class-level ApplicationRuntime.launch() helper that instantiates the runtime - Harden error propagation for resolution and annotation failures - Outcome: Runtime orchestrates container bootstrap and application execution

Phase 3: Integration & Hardening - Wire runtime with TD-013 scanning and TD-020 bootstrap metrics - Confirm compatibility with existing container/bootstrap observability - Deliver documentation updates and example entry scripts - Outcome: Runtime ready for adoption with clear guidance

⚠️ 10. Risks and Mitigations

Risk Mitigation
Performance impact from additional abstraction layers Profile startup time; optimize critical paths; maintain O(1) container operations
Migration complexity for existing users Provide comprehensive migration guide with before/after examples; maintain backward compatibility
Integration issues with TD-013/TD-020 Extensive integration testing; phased rollout; fallback to manual patterns
Learning curve for new application pattern Clear documentation with progressive examples; starter templates
Error diagnosis complexity in orchestration Comprehensive error wrapping with application context; detailed logging

πŸ“ˆ 11. Progress

Legend: ⏳ Pending Β· 🚧 In Progress Β· βœ… Completed

Phase 1 β€” Core Contracts - [x] ApplicationBase, ApplicationConfiguration, and ApplicationError - [x] ApplicationAnnotation leveraging AnnotationContext - [x] @application decorator validation for inheritance and configuration

Phase 2 β€” Runtime Orchestration - [x] Module-path resolution and container bootstrap coordination - [x] Class-level ApplicationRuntime.launch() helper - [x] Error propagation for annotation/lookup failures

Phase 3 β€” Integration & Documentation - [x] TD-013/TD-020 wiring confirmed with runtime workflow - [x] Guidance and examples refreshed across docs - [x] Test matrix (unit/integration/regression) implemented

πŸ“ 12. Changelog

  • 2025-10-12 β€” Restructured to highlight ApplicationRuntime, runtime observability, and simplified lifecycle
  • 2025-10-11 β€” Initial draft created with summary and context sections

πŸ“– 13. Glossary

Term Definition
ApplicationBase Abstract base class implemented by application entry points exposing run()
ApplicationConfiguration Decorator metadata describing scanning scope and bootstrap options
ApplicationError Exception hierarchy raised for runtime orchestration failures
ApplicationRuntime Coordinator that resolves module paths, bootstraps the container, and executes applications
ApplicationDecorator The @application decorator that attaches configuration metadata to classes
Entry Point Module path string ("module:Class") identifying the application to launch
Bootstrap Plan Immutable specification of registration steps (TD-013)
Bootstrap Runtime External orchestrator executing bootstrap plans (TD-020)
Runtime Observability Future enhancements layering application identifiers atop existing container/bootstrap metrics