Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 47 additions & 52 deletions MODULE_AUDIT.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Shared/SnapshotKitTesting/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Read the root [`AGENTS.md`](../../AGENTS.md) first.
- **Immediate measurement never shortens final capture settling.** It skips only the intrinsic-sizing probe's settle for synchronously sized fixtures.
- **The final `.settled` / `.settledAtLeast` policy still runs.** Guards: `AsyncContentCaptureTests`.
- **A settle phase costs its floor, not its passes.**
- **Measured 2026-07-28 with `SNAPSHOT_TIMING=1` over 260 references of the time.** The suite holds 484 as of 2026-09-06. Re-measure before acting on the split below.
- **Measured 2026-07-28 with `SNAPSHOT_TIMING=1` over 260 references of the time.** The suite holds 490 as of 2026-09-06. Re-measure before acting on the split below.
- **The conclusion (the floor dominates) is what to rely on, not the seconds.**
- **192 captures sat at 0.25-0.35s — the `minDuration` floor plus a pass or two.** The floor accounts for ~70s of the ~84s of settle time.
- **The render passes themselves are ~14s across the whole suite.** Making passes cheaper is worth ~11%. Removing floors is worth ~54%.
Expand All @@ -118,7 +118,7 @@ Read the root [`AGENTS.md`](../../AGENTS.md) first.
- **Quiescence cannot replace the pixel digest.**
- **`SNAPSHOT_SETTLE` selects `pixel` (default), `quiescence`, or `both`.** Quiescence uses a `beforeWaiting` run-loop observer plus a recursive `needsLayout`/`needsDisplay`/`animationKeys` walk.
- **`both` runs them together and reports disagreements.**
- **Run in `both` mode (2026-07-28) over 260 references of the time — 484 as of 2026-09-06.** The counts below are that run's, not current.
- **Run in `both` mode (2026-07-28) over 260 references of the time — 490 as of 2026-09-06.** The counts below are that run's, not current.
- **That run had 226 settle phases, 134 with some disagreement.**
- **8 cases had quiescence declare settled *earlier* than the digest.** Every one was a `Loaded_*` case whose content arrives late.
- **That is the one dangerous direction.** It would capture a frame no reference recorded.
Expand Down
2 changes: 1 addition & 1 deletion TODOs.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ inbox rather than here.
## P2s (Nice to have)
- perf(CI) [needs-design]: Re-evaluate caching Git LFS snapshot objects without
fighting CircleCI's checkout hydration — at the time of that measurement the built-in checkout
downloaded all 377 then-current objects (358.58 MiB; the tree holds 484
downloaded all 377 then-current objects (358.58 MiB; the tree holds 490
reference images as of 2026-09-06, so re-measure before retrying) before
[`.circleci/config.yml:20-32`](.circleci/config.yml), while PR #245's first
cache attempt encountered a cold miss and then made `git lfs prune
Expand Down
8 changes: 5 additions & 3 deletions Where/TODOs.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions Where/WhereUI/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ the feature [`Where/AGENTS.md`](../AGENTS.md) and this module's

- **`OnboardingView` / `OnboardingFlowModel`** — the rendered first-run flow and its view-scoped
observable coordinator, registered for the launch's
`OnboardingGate` and handed its `LifecycleGateHandle`. The gate roots the
trunk, so there is no session behind it: a paged intro,
`OnboardingGate` and handed its `LifecycleGateHandle`. The gate follows the
side-effect-free demo preflight and precedes every world-building step, so
there is no session behind it: a paged intro,
then picking up to five primary US regions (map or searchable list) and
giving each a look, then verifying this installation's automatic-recording
choice. The final page opens the real store in a dormant state to inspect recent synced advisory
Expand Down
6 changes: 3 additions & 3 deletions Where/WhereUI/Sources/Launch/WhereLaunchSteps.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ struct ActivateLaunchDemoStep: BudgetedLaunchStep {
}

/// First-run onboarding and this installation's recording choice.
/// Rooted at the trunk's head so that an install whose user hasn't chosen yet
/// builds nothing: no store is opened, no CloudKit is contacted, and no session
/// exists behind this.
/// Placed after the side-effect-free demo preflight and before every step that
/// builds the user's world: no store is opened, no CloudKit is contacted, and no
/// session exists behind this while the user has not chosen.
///
/// Unlike most gates it applies to **all** launch reasons rather than the
/// foreground-only default. Parking a headless launch is the point here — the
Expand Down
7 changes: 4 additions & 3 deletions Where/WhereUI/Sources/Onboarding/OnboardingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import SwiftUI
import UniformTypeIdentifiers
@_spi(Testing) import WhereCore

/// First-run onboarding, run as the launch's opening gate. A short paged
/// First-run onboarding, run as the launch's user-facing gate. A short paged
/// intro to the passport concept, then picking the primary regions you spend
/// time in and giving each a look, then confirming whether this device should
/// record automatically. Enabling it requests background-location permission
/// here, rather than burying that decision in Settings.
///
/// No session exists behind this screen: the gate roots the trunk. The final choice may prepare
/// and retain the real store solely to discover synced authority; services and GPS remain dormant.
/// No session exists behind this screen: the gate precedes every step that builds
/// the user's world. The final choice may prepare and retain the real store solely
/// to discover synced authority; services and GPS remain dormant.
/// Onboarding is what brings the
/// user's world into being — restoring a backup or finishing the flow logs in
/// to the real scope (`WhereModel.resolveScope()`, which performs the app's one
Expand Down
6 changes: 3 additions & 3 deletions Where/WhereUI/Sources/RootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ public struct RootView: View {
},
failure: { WhereLifecycleFailureView(failure: $0) },
gates: {
// The gate roots the trunk, so there is no session (and no
// open store) behind it yet — onboarding builds the scope
// it commits regions with, through the model.
// The gate precedes every world-building step, so there is
// no session (and no open store) behind it yet — onboarding
// builds the scope it commits regions with, through the model.
GateView(for: OnboardingGate.self) { handle, _ in
OnboardingView(
gate: handle,
Expand Down
4 changes: 2 additions & 2 deletions Where/WhereUI/Tests/WhereLaunchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ struct WhereLaunchTests {

@Test func planNodesRunInStartParityOrder() throws {
// The work steps mirror WhereSession.start()'s order; the only
// insertions are the onboarding gate at the head and the
// resolve-scope / start-session promotions behind it.
// insertions are the demo preflight and onboarding gate ahead of the
// resolve-scope / start-session promotions.
let model = try makeModel(preferences: makePreferences())
let ids = WhereLaunch.plan(for: model).nodeIDs
#expect(ids == [
Expand Down
Loading