[!IMPORTANT] Strategy Clarification (2026-02-15):
- v1.5+ introduces breaking changes — The Control Plane architecture (originally planned as “v2”) is now released as v1.5 to avoid
go.modmigration overhead. See MIGRATION.md for upgrade guidance.- Roadmap is work-driven, not date-driven — Organized by iterative releases (v1.6, v1.7) instead of fixed timelines.
- Working solo with AI partners — Planning reflects single-maintainer capacity with agent collaboration.
[!IMPORTANT] v1.5 Stabilization Complete: All architectural split work and baseline test coverage milestones have been achieved. The v1.5 Control Plane foundation is stable and ready for production use.
Breaking Changes: v1.5 introduces the Event-Driven Control Plane, which includes breaking API changes from v1.4. See MIGRATION.md for details.
OSSignalSource (SIGINT, SIGTERM)WebhookSource (Admin HTTP endpoints)HealthCheckSource (Promoted from Backlog)FileWatchSource (Integration with Loam?)ctx.Progress(0.5) or lifecycle.Tick(ctx) to drive UI/LoadersShutdown (Current behavior)HotReload (Cross-platform config reload via FileWatchSource, see examples/reload/)Suspend/Resume (Verified with examples/suspend)lifecycle.Go(ctx, fn) pattern
pkg/runtimeSupervisor for services, Go for taskspath.Match, partial regex)Routes() for visualization)InputSource (detached readers, Windows-resilient)NewInteractiveRouter presetQuiescenceGate (context-aware pause primitive)Always, OnFailure, Never)RECIPES.md cookbook[!NOTE] Architectural Split Completed (v1.5): The
core/eventssplit has been successfully implemented:
- Clean separation between Foundation (
pkg/core) and Control Plane (pkg/events)- Facade API design (
lifecycle.goas unified entry point)- All examples updated to use new structure
- Zero breaking changes for basic
import "github.com/aretw0/lifecycle"usage
pkg/* packagescore/ package structure.events/ package structure.lifecycle.go as facade.import "github.com/aretw0/lifecycle" users.[!IMPORTANT] Refactoring Objective: We have successfully extracted the core process and I/O primitives into procio. This reduces the dependency footprint and elevates these primitives to first-class status.
go.work (Dev Mode).proc, termio, scan to procio.lifecycle now depends on procio v0.1.2.proc & termio Ecosystem:
procio repo.lifecycle acts as the “Policy Engine” over procio “Mechanics”.[!IMPORTANT] Refactoring Objective: We have successfully extracted generic visualization primitives into introspection. This decouples domain logic from presentation logic and enables broader adoption of
lifecycle’s introspection patterns.
pkg/core/introspection package (~1500 lines).TreeDiagram, StateMachineDiagram, ComponentDiagram).lifecycle now depends on introspection v0.1.2.diagram_config.go (centralized configuration).NodeStyler/NodeLabeler to pkg/core/worker.PrimaryStyler/PrimaryLabeler to pkg/core/signal.SystemDiagram to use introspection.ComponentDiagram.RenderTreeFragment from worker/diagram.go.RenderFragment from signal/diagram.go.See TESTING.md for our “Honest Coverage” policy and exclusions.
supervisor and router.pkg/core/supervisor: Backoff & State Testspkg/events/router: Introspection Testspkg/events/suspend: Robustness Testsmetrics, termio) are documented.lifecycle.Go() only logs the panic value. To diagnose root causes, stack traces are essential, but not in production (log noise vs. disk I/O cost).runtime/debug.Stack() only when debug logging is enabled (slog.LevelDebug).pkg/core/runtime/task.go panic handler to check logger level before capturing stack.import "runtime/debug" for stack extraction.docs/MIGRATION.md with v1.5 upgrade guide and patterns.Focus: Extensible panic observability and a clean migration entry point.
Context: v1.5.2 introduced conditional stack traces (Nivel 1). Now extend this with full customization via the Observer pattern and formalize gradual adoption.
[!IMPORTANT] v1.6.0 Completed (2026-02-16): All items below have been implemented, tested, and documented. Ready for release.
- Core feature:
Observer.OnGoroutinePanicked(any, []byte)hook with stack capture control- Migration entry point:
lifecycle.Context()for gradual adoption- Documentation: TECHNICAL.md (§8.1 cleanup pattern + §14 observability), MIGRATION.md condensed
- Examples:
context/main.go(new),observability/main.go(enhanced)- Tests: All 15 tests passing, 3 stack-capture scenarios covered
OnGoroutinePanicked(recovered any, stack []byte) method to pkg/core/observe.Observer.WithStackCapture(bool) option to lifecycle.Go().Example:
lifecycle.Go(ctx, criticalTask, lifecycle.WithStackCapture(true)) // Always capture
lifecycle.Go(ctx, debugTask, lifecycle.WithStackCapture(false)) // Never capture
lifecycle.Go(ctx, normalTask) // Auto-detect
watchWorker) can leverage the same pattern.examples/ showing panic recovery + stack capture for custom workers.debouncer.closed = true)sync.WaitGroup to track in-flight callbacks, wait before proceedingstopAndWait(timeout) helper pattern / examplepkg/adapters/fs can migrate from custom panic handling to WithStackCapture(true).OnGoroutinePanicked hook for operational dashboards.Implement lifecycle.Context() for manual setup:
func main() {
ctx := lifecycle.Context() // returns signal context
defer lifecycle.Shutdown(ctx)
myExistingApp(ctx) // just swap context.Background() → lifecycle.Context()
}
docs/MIGRATION.md:
lifecycle.Run (zero config, recommended)lifecycle.Context (manual, for gradual migration)[!IMPORTANT] v1.6.1 Completed (2026-02-16): Technical debt has been mapped and documented. This patch focuses on Transparency & API Clarity, not on performance measurement or new tests. Benchmarks and comprehensive testing of router limitations are planned for v1.6.2.
TODO, FIXME, HACK comments (1 TODO found: router.go:192 “Optimize if many routes”)path.Match: Glob only, not full regexlifecycle.Go callpkg/core/observe/observe.go: Observer marked Stable (v1.6.0)pkg/events/router.go: Glob-only pattern syntax documentedpkg/core/runtime/task.go: Three-mode stack capture explainedlifecycle.go: APIs Context() and WithStackCapture() stabilizedFocus: Measure actual overhead, consolidate multi-source documentation, provide optimization path.
[!IMPORTANT] v1.6.2 Completed (2026-02-17): All benchmarking and documentation consolidation work has been implemented.
- Comprehensive benchmarks:
pkg/core/runtime/benchmark_test.goandpkg/events/router_benchmark_test.go- Real performance data: Measured overhead for
lifecycle.Go, router patterns, supervisor introspection- Documentation consolidated: Single source of truth in LIMITATIONS.md with cross-references
- Automation:
make benchmarktarget and platform-specific scripts ready
lifecycle.Go vs go func() + manual WaitGroupscripts/run_benchmarks.ps1 (Windows)scripts/run_benchmarks.sh (Unix)make benchmark target to MakefilewithLock and withLockResult for atomic reads.Note: The exceptions and limitations of the
withLock/withLockResultpattern are now documented in docs/LIMITATIONS.md to centralize technical knowledge and facilitate maintenance. See there for updated details.
signal.Context where the monitor loop would consume 100% CPU after context cancellation.
Done channel case is now disabled after cancellation while keeping signal monitoring active for “Force Exit” logic.Focus: Critical security fixes and test stability for immediate production reliability.
http.MaxBytesReader in pkg/events/webhook.go.WithMaxPayloadBytes option.time.Sleep in pkg/events/filewatch_test.go with deterministic synchronization.PLANNING.md and TECHNICAL.md to remove “Skeleton” labels from functional components.lifecycle.StopAndWait(ctx, worker) to atomically stop and wait for worker termination.Stop returns before stdout/stderr buffers are closed or background routines finish (discovered in Trellis usage).lifecycle.go to never leak internal types (e.g., signal.Context, worker.BaseWorker).Focus: Evolve the Control Plane with robust watching patterns, generic event utilities, and event broker responsibilities to offload downstream projects (like Loam).
[!IMPORTANT] v1.7.0 Completed (2026-02-21): All advanced watching and delegation items below have been implemented, tested, and documented.
events.Notify(ch)pattern implemented for Pub/Sub and safe external channel integration.events.DebounceHandlerimplemented to throttle high-frequency burst events.FileWatchSourceexpanded withWithRecursive(true)andWithFilteroptions for deep, targeted file monitoring.RECIPES.mdupdated with the new “Inhibition Pattern” recipe.
events.Notify(c chan<- Event) (inspired by signal.Notify).<-chan Event) instead of only pushing via callbacks, enabling synchronous iteration for clients.events.DebounceHandler(handler, window time.Duration, mergeFunc)).FileWatchSource to support deep monitoring.WithRecursive(true) and WithFilter(func(path string) bool) support.index.lock git-pause filtering natively without maintaining deep fsnotify boilerplate.Focus: Evolve control plane self-healing, scaling, and coordinated lifecycle guarantees.
Prober interface to workers to go beyond simple “Process Alive” check.Focus: Make lifecycle discoverable, understandable, and compelling.
Lead with The Problem (concrete pain points):
## The Problem
**Ever had your Go CLI hang on Windows when you press Ctrl+C?**
**Or found zombie child processes after your app crashes?**
**Or struggled with goroutines that never shut down cleanly?**
lifecycle.Run) — 15 linesNewInteractiveRouter) — 30 linesSupervisor) — 50 linesgo run)EOF instead of graceful shutdownBefore/After comparison:
Without lifecycle: [screenshot of hang]
With lifecycle: [screenshot of clean exit]
path.Match is glob, not full regexdocs/BENCHMARKS.md:
lifecycle.Go vs go func() + manual WaitGrouplifecycle.Group vs errgroup.Groupdocs/CASE_STUDY_TRELLIS.md:
Focus: Maximize visibility and initial adoption.
CHANGELOG.md (v1.0 → v1.5 → v1.8)bug, feature, question, docs, good first issueFocus: Evolve based on community feedback and adoption patterns.
pkg/metricstime.Sleep hacks in testsx/term Raw Mode enter/restoresuture)
ergo)
PeriodicWorker (Ticker-based)StreamWorker (Producer/Consumer with backpressure)StatefulWorker (Standard state machine template)Introspectable interface (State() any)[!TIP] Reality Check (v1.6.4): Much of the early technical debt (coverage, performance unknowns) has been resolved. The focus now shifts to Hardening and CI Reliability.
LIMITATIONS.md.MIGRATION.md and LIMITATIONS.md created; TECHNICAL.md updated.FileWatchSource and Supervisor) still use time.Sleep for synchronization.WebhookSource lacks request body limits (OOM risk).http.MaxBytesReader (Target: v1.6.5).suspend, webhook, and health are functional but need explicit // Experimental or // Stable tags in code to match LIMITATIONS.md.LIMITATIONS.md for every Minor release.From original planning:
Context propagation, but enjoy DefaultRouter convenience.CONIN$ handling is a first-class citizen, not an afterthought.pkg/metrics interfaces.