Prototype B: raw async/await launch — no LifecycleKit at all#118
Open
kyleve wants to merge 2 commits into
Open
Prototype B: raw async/await launch — no LifecycleKit at all#118kyleve wants to merge 2 commits into
kyleve wants to merge 2 commits into
Conversation
Plan steps: raw-strip + raw-launch (compile-coupled: deleting the kit targets breaks every consumer in the same build), tests included so the commit is green. - Both kit targets (LifecycleKit, LifecycleKitUI, their test bundles, schemes, and Stuff-iOS-Tests entries) are deleted from Package.swift/ Project.swift. The host smoke tests (ShowLifecycleTests, StuffTestHostSmokeTests) move to StuffCoreTests. - WhereLaunch.run is one raw async task per attempt, started by WhereLaunch.start from the app delegate. Promotion is a *park*, not a re-drive: the task awaits scene activation before its foreground tail (onboarding, the one-shot fix), so a headless wake is serviced above the park and simply never proceeds — no launch-reason enum, no buildsNoViewTree rule, no memoization (nothing ever runs twice; idempotence is the same state checks the model already has). The one ordering the park model must branch on explicitly: session configuration runs before the park for a headless-so-far attempt, but after the onboarding park when the scene is already active, so a reset can't resume GPS into the freshly-erased store while the user re-onboards. - App-owned remnants in WhereUI, per the modeling-state conventions: WhereLaunchState (one Phase enum — launching | onboarding(handle, session) | failed | ready(session) — plus the scene-activation signal and attempt/fan task ownership) and OnboardingHandle (the resolution token, cancellation-aware, stale-handle-safe). - Failure is terminal (no retry): launch failures log + park in .failed; the new LaunchFailureView offers no button — the recovery is relaunching the app. WhereLaunch.reset cancels and drains the in-flight attempt and its fan, erases, clears preferences, then begins a fresh attempt; a cancelled attempt never writes the phase. DetachedFailureReporter is deleted (the fan bodies are non-throwing session methods; there is no failure channel to mirror). - RootView absorbs the container: no view tree until a scene has been active, then a switch over the phase animated on surface identity with the same zoom-reveal; SettingsView drives the reset through the launch state in the environment. - Tests are Where-level behavior tests: headless wake serviced without passing the park, activation resumes the tail, onboarding parks/resolves (+ terminal failure via handle.fail), the onServicesReady hook re-fires on the reset relaunch, reset returns to onboarding over an empty store, and a reset while parked on onboarding drains the old attempt (its stale handle is a no-op). The kit's engine/fuzz suites die with the engine — an accepted loss recorded in the PR body.
Plan step: raw-tests-pr (docs half). Where/AGENTS and WhereUI README describe the raw launch (the park, the terminal failure, the conventions WhereLaunch now owns); the root AGENTS/README drop the kit from the target catalog and the double-link note; StuffTestHost/TestHostSupport docs point at the smoke tests' new home in StuffCoreTests. ./sync-agents run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
This is a prototype for comparison, not a default-merge candidate — the last rung of the ladder: shipped combinators (#116) → context-driven functions (#117, the base of this PR) → no kit at all. The question it answers: what does the app look like when launch is nothing but raw async/await, and what is the engine actually earning?
Changes
Both kit targets are deleted (
LifecycleKit,LifecycleKitUI, their test bundles and scheme entries; the host smoke tests move toStuffCoreTests). Launch is one raw async task per attempt:LifecycleReason/buildsNoViewTree, no run-once memoization (nothing ever runs twice), no re-drive semantics. The one cost: an ordering the memo used to handle uniformly must now be branched explicitly (session configuration runs before the park when headless, after the onboarding park when the scene is already active — so a reset can't resume GPS into a freshly-erased store mid-re-onboarding).WhereLaunchState(onePhaseenum —launching | onboarding(handle, session) | failed | ready(session)— plus the scene signal and attempt/fan task ownership) andOnboardingHandle(the cancellation-aware, stale-safe resolution token).RootViewabsorbs the container's surface switching with the same zoom-reveal..failed, no button — and the recovery is relaunching the app. Reset keeps its safety semantics without retry: cancel + drain the attempt and its fan, erase, then a fresh attempt; a failed erase parks terminal with preferences intact.DetachedFailureReporteris deleted: the fan bodies are non-throwing session methods, so there is no failure channel left to mirror.The three-way trade
WhereLaunchdocuments (one store open, effects-vs-park placement, no phase writes from a cancelled attempt)The honest summary: B is the leanest by far and the park model is genuinely elegant for this app's shape — but every guarantee became a convention, the seeded fuzz coverage died with the engine, and a second app (or a second gate, or resurrected retry) starts re-growing the kit by hand.
Testing
Where-level behavior tests with the scripted scene signal: a headless wake services tracking without passing the park (no capture, no
.ready), activation resumes the tail, onboarding parks/resolves and its failure is terminal,onServicesReadyre-fires on the reset relaunch, reset returns to onboarding over an empty store with preferences restored, and a reset while parked on onboarding drains the old attempt (its stale handle is a no-op). One accepted coverage loss vs. the base branch, named here: the reset-erase failure path (previously driven through the engine's failure-injection seam) is no longer unit-drivable —reset's catch is exercised only by reading. FullStuff-iOS-Testsscheme green;./swiftformat --lintclean.