Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
c815bb9
feat(Throw): add ceiling flight projection app
kyleve Aug 25, 2026
e5f9390
fix(ThrowUI): unblock full-screen onboarding
kyleve Aug 25, 2026
3188121
feat(Throw): add device install command
kyleve Aug 25, 2026
58b352b
fix(ThrowUI): keep full-screen exit visible
kyleve Aug 25, 2026
69764e9
fix(ThrowUI): restore calibration row height
kyleve Aug 25, 2026
9dedbcd
chore(Throw): track bundle name localization
kyleve Aug 25, 2026
327808c
feat(Throw): add offline geography layer
kyleve Aug 25, 2026
e1fe1c4
fix(ThrowUI): keep geography visible in dark output
kyleve Aug 25, 2026
b6d0db5
feat(Throw): add detailed offline geography
kyleve Aug 25, 2026
ae9f7e1
fix(Throw): improve app icon legibility
kyleve Aug 25, 2026
4be72aa
fix(ThrowUI): reduce flight label prominence
kyleve Aug 25, 2026
9de3038
feat(Throw): differentiate aircraft silhouettes
kyleve Aug 25, 2026
6cd31fc
fix(Throw): verify install resource bundles
kyleve Aug 25, 2026
8b31a56
fix(ThrowUI): clarify aircraft silhouettes
kyleve Aug 25, 2026
8f02aca
fix(ThrowUI): fill aircraft silhouettes solidly
kyleve Aug 25, 2026
09693b1
feat(ThrowUI): fade projection mark presence
kyleve Aug 25, 2026
eaa1eae
feat(Throw): add flight route labels
kyleve Aug 25, 2026
dc0e164
fix(Throw): isolate flight route enrichment
kyleve Aug 25, 2026
150677f
fix(Throw): tie aircraft fade to poll failures
kyleve Aug 25, 2026
1b9fdff
fix(ThrowUI): animate projection presentation changes
kyleve Aug 25, 2026
edf6d5b
fix(ThrowCore): preserve aircraft heading after prediction
kyleve Aug 25, 2026
c68e111
feat(Throw): add ambient flight activity cues
kyleve Aug 25, 2026
d6e9308
Merge remote-tracking branch 'origin/main' into codex/throw-v1
kyleve Aug 25, 2026
9faee54
feat(Throw): add Flightradar24 aircraft source
kyleve Aug 26, 2026
352ca3a
fix(ThrowCore): restore FR24 airline accents
kyleve Aug 26, 2026
f958682
feat(Throw): estimate FR24 credit usage
kyleve Aug 26, 2026
33f6b1e
fix(Throw): handle empty FR24 usage reports
kyleve Aug 26, 2026
fcf7b33
fix(Throw): decode FR24 usage counters
kyleve Aug 26, 2026
c3374d8
feat(ThrowUI): move airline colors to flight labels
kyleve Aug 26, 2026
3506026
feat(Throw): support regional map centers
kyleve Aug 26, 2026
b6af13f
fix(ThrowUI): limit map center offsets
kyleve Aug 26, 2026
352e0ef
refine(ThrowUI): tighten flight route labels
kyleve Aug 26, 2026
94e558f
Improve Throw aircraft motion rendering
kyleve Aug 26, 2026
5c0f0df
feat(Throw): add projection views and rotation
kyleve Aug 26, 2026
04770a3
fix(ThrowCore): validate external identifiers safely
kyleve Aug 26, 2026
2ed4e23
fix(Throw): canonicalize projection identities
kyleve Aug 26, 2026
985a9ae
fix(ThrowUI): make source mutations failure atomic
kyleve Aug 27, 2026
8cd43df
fix(ThrowCore): reject invalid GPS altitude
kyleve Aug 27, 2026
9fa51a3
fix(ThrowUI): bound manual experience readiness
kyleve Aug 27, 2026
67b3e4e
refactor(Throw): type experience projection inputs
kyleve Aug 27, 2026
0717c5a
refactor(Throw): enforce module boundaries
kyleve Aug 27, 2026
7b74db7
fix(ThrowUI): bound static line projections
kyleve Aug 27, 2026
cb83188
fix(ThrowCore): split FR24 dateline queries
kyleve Aug 27, 2026
7009e3e
fix(ThrowCore): canonicalize map region edges
kyleve Aug 27, 2026
72fee2d
fix(ThrowCore): validate emitted runway count
kyleve Aug 27, 2026
a0821ec
Merge remote-tracking branch 'origin/main' into codex/throw-v1
kyleve Aug 27, 2026
37ec43e
fix(ThrowUI): restore saved View selection
kyleve Aug 27, 2026
72648c6
fix(ThrowUI): reject stale flight runtime lifecycle work
kyleve Aug 27, 2026
c1b9db3
fix(ThrowUI): order projection playlist updates
kyleve Aug 27, 2026
6465fd8
fix(ThrowCore): bound FR24 polar queries exactly
kyleve Aug 27, 2026
d4ad74d
docs(Throw): record runtime ordering invariants
kyleve Aug 27, 2026
9c8795c
test(ThrowCore): make retry grace check deterministic
kyleve Aug 27, 2026
e21fb71
fix(ThrowUI): make View coordination lossless
kyleve Aug 27, 2026
bdaa427
fix(ThrowUI): bind prepared Views to activations
kyleve Aug 27, 2026
602a3e0
refactor(Throw): close aircraft source invariants
kyleve Aug 27, 2026
9652343
refactor(ThrowCore): close projection identities
kyleve Aug 27, 2026
ccdf67c
fix(ThrowUI): order lifecycle state updates
kyleve Aug 27, 2026
7f3de49
build(Throw): enforce composition ownership
kyleve Aug 27, 2026
d19b9a9
docs(Throw): record hardened runtime contracts
kyleve Aug 27, 2026
8fe9bcb
fix(SnapshotKitTesting): sanitize review paths
kyleve Aug 27, 2026
fa17517
test(ThrowUI): refresh reviewed snapshots
kyleve Aug 27, 2026
9dd058e
fix(ThrowUI): bind rejection to request generation
kyleve Sep 1, 2026
0806488
refactor(ThrowCore): make horizontal motion typed
kyleve Sep 1, 2026
5191ff2
refactor(Throw): make setup lifecycle typed
kyleve Aug 26, 2026
be5c89b
Merge remote-tracking branch 'origin/main' into codex/throw-v1-review…
kyleve Sep 1, 2026
c7f3013
test(ThrowUI): refresh snapshots for Xcode 27 beta 6
kyleve Sep 1, 2026
fd79ac5
fix(ThrowUI): commit observer locations atomically
kyleve Sep 1, 2026
1270f42
fix(Throw): declare required UserDefaults reason
kyleve Sep 1, 2026
e4f4e66
fix(ThrowUI): serialize preference persistence
kyleve Sep 1, 2026
4205046
fix(Throw): derive foreground state from controller scenes
kyleve Sep 1, 2026
eda9549
fix(ThrowUI): bind teardown to activation leases
kyleve Sep 1, 2026
9962467
refactor(ThrowCore): make altitude availability typed
kyleve Sep 1, 2026
e84b71e
refactor(ThrowCore): pair observations with resolved motion
kyleve Sep 1, 2026
807a553
refactor(Throw): close source validation drafts
kyleve Sep 1, 2026
0236d07
refactor(Throw): type temporary quiet wakes
kyleve Sep 1, 2026
c24481d
refactor(ThrowUI): derive coordinator presentation state
kyleve Sep 1, 2026
b3fe553
fix(ThrowUI): preserve prepared transition frames
kyleve Sep 1, 2026
ad90113
fix(ThrowUI): retain validated quiet schedule
kyleve Sep 1, 2026
ac584a4
fix(ThrowUI): bind source apply to its draft
kyleve Sep 1, 2026
e052401
refactor(Throw): close projection experience identities
kyleve Sep 1, 2026
08bee0f
fix(ThrowCore): preserve route cancellation
kyleve Sep 1, 2026
d708b23
fix(ThrowCore): report partial provider decoding
kyleve Sep 1, 2026
da8f01a
fix(ThrowCore): warn on receiver cadence fallback
kyleve Sep 1, 2026
6b27784
fix(Throw): gate scenes on typed cold launch
kyleve Sep 1, 2026
c1a8318
refactor(ThrowCore): require snapshot diagnostics
kyleve Sep 1, 2026
8634a29
refactor(ThrowCore): close polling log event state
kyleve Sep 1, 2026
8d8d43a
feat(Throw): persist typed runtime diagnostics
kyleve Sep 1, 2026
28cbd8d
chore(Throw): require typed production logging
kyleve Sep 1, 2026
8d0b7e3
fix(Throw): present launch failures safely
kyleve Sep 1, 2026
4898674
refactor(Throw): type projected frames end to end
kyleve Sep 1, 2026
944c85c
refactor(Throw): keep session preferences typed
kyleve Sep 1, 2026
20a3b1a
fix(Throw): preserve software credit failures
kyleve Sep 1, 2026
6201aea
fix(Throw): isolate post-launch failures
kyleve Sep 1, 2026
8fd8e5a
refactor(ThrowUI): publish projection state atomically
kyleve Sep 1, 2026
79d685a
fix(Throw): reconcile preference transactions
kyleve Sep 1, 2026
413924e
Preserve launch failures before durable logging attaches
kyleve Sep 1, 2026
86ef869
test(ThrowUI): complete transition update fixture
kyleve Sep 1, 2026
65b42c9
refactor(ThrowCore): restrict polling clock failures
kyleve Sep 1, 2026
bc3a610
refactor(Throw): bind diagnostics to durable startup
kyleve Sep 1, 2026
769b576
refactor(ThrowUI): close onboarding source state
kyleve Sep 1, 2026
aacb6a0
refactor(ThrowUI): close setup mutation seams
kyleve Sep 1, 2026
e1a0323
fix(ThrowUI): require leases for rendered projections
kyleve Sep 1, 2026
98521ce
fix(ThrowUI): preserve committed preference mutations
kyleve Sep 1, 2026
d982fe8
test(ThrowCore): compare error attachment payloads
kyleve Sep 1, 2026
e1760e3
Retain quiescent background preference flushes
kyleve Sep 1, 2026
2862590
fix(ThrowUI): invalidate staged projection contexts
kyleve Sep 1, 2026
7e0ab81
refactor(TLA): discover specs across features
kyleve Sep 1, 2026
f035acc
fix(ThrowUI): hide stopped activation leases
kyleve Sep 1, 2026
58e15c3
Guard background preference flush producers
kyleve Sep 1, 2026
69fc5f2
fix(ThrowUI): tombstone runtime activation leases
kyleve Sep 1, 2026
27ff3f0
Make preference flush cancellation-aware
kyleve Sep 1, 2026
f4bd87e
verify(Throw): model projection context transitions
kyleve Sep 1, 2026
5f0c607
verify(Throw): model projection activation
kyleve Sep 1, 2026
ee83798
Verify Throw preference transactions
kyleve Sep 1, 2026
6492d2d
Bind polling updates to activation tokens
kyleve Sep 1, 2026
b53e578
Renew projection leases across context changes
kyleve Sep 1, 2026
0cd6849
Order polling publications within activations
kyleve Sep 1, 2026
89a521f
Prove polling publication ordering
kyleve Sep 1, 2026
9e32a01
Verify Throw background preference persistence
kyleve Sep 1, 2026
22e09ad
test(ThrowUI): make quiet-hours regression timezone-stable
kyleve Sep 1, 2026
6cd2fdc
refactor(ThrowCore): bind prepared transit networks
kyleve Sep 1, 2026
aea7695
Validate aircraft polling cadence
kyleve Sep 1, 2026
30b569d
Preserve experience leases during polling suspension
kyleve Sep 1, 2026
eec278e
Close runnable projection experience catalog
kyleve Sep 1, 2026
acbcf52
Enforce typed projection layer families
kyleve Sep 1, 2026
60c2540
Verify projection renewal and polling suspension
kyleve Sep 1, 2026
66903de
Verify preference lease handoff transactions
kyleve Sep 1, 2026
074dbde
docs(throw): refresh polling proof correspondence
kyleve Sep 1, 2026
10d0ac2
docs(throw): refresh background proof correspondence
kyleve Sep 1, 2026
e186a3a
Verify projection invalidation gate phases
kyleve Sep 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
72 changes: 62 additions & 10 deletions .bumper/RULES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Where Architecture Rules
# Application Architecture Rules

`BumperBowling.swift` turns the module boundaries already documented in
`Where/**/AGENTS.md` into source-level checks. It scans production sources only;
tests and generated files are outside the architecture graph.
`BumperBowling.swift` turns the module boundaries documented in the Where and
Throw `AGENTS.md` files into source-level checks. It scans production sources
only. Tests and generated files are outside the architecture graph.

## Layer boundaries

Expand All @@ -17,6 +17,12 @@ tests and generated files are outside the architecture graph.
| `WhereShareExtension` | `WhereCore`, `WhereUI` | Foundation, SwiftUI, UIKit |
| `RegionViewer` | `RegionKit`, `WhereCore`, `WhereUI` | Foundation, SwiftUI, UIKit |

| Throw component | Allowed Throw dependencies | Framework capabilities |
| --- | --- | --- |
| `ThrowCore` | none | Foundation |
| `ThrowUI` | `ThrowCore` | Foundation, SwiftUI, UIKit |
| `Throw` app | `ThrowUI` | Foundation, SwiftUI, UIKit |

An import of a declared Where module outside these edges is a
`component_boundary` error. An import of a known framework capability outside
the component's allow-list is a `forbidden_import` error. RegionKit and
Expand All @@ -31,10 +37,13 @@ Delete or reshape a boundary only when the corresponding module architecture
changes in its `AGENTS.md`, `Package.swift`, or `Project.swift`; update the
documentation and executable rule in the same change.

ThrowCore and ThrowUI also forbid LifecycleKit. Throw is a retryable runtime,
not a terminal launch sequence. The Throw app cannot import ThrowCore directly.

## Graph integrity

- `duplicate_ownership` keeps every source path and module in one component.
- `declared_dependency_cycle` keeps the Where layer graph acyclic.
- `declared_dependency_cycle` keeps each application layer graph acyclic.

The mutation tests in `.bumper/Tests` prove that a valid downward import passes
and that representative upward/framework imports fail with the expected rule.
Expand Down Expand Up @@ -92,6 +101,20 @@ These use Bumper's standard `constructionOwnership` shaper. TheButtonHeist's
as the analogous lower-level ownership check and retained; the standard shaper
fully expresses Where's constructor facts.

Throw has matching ownership and typed-projection guards:

- `throw.session_composition_ownership` permits `ThrowSession` construction only in `ThrowSession+Composition.swift`.
- `throw.live_dependency_composition_ownership` keeps live stores, durable logging, sources, and polling dependencies in that same file.
- `throw.runtime_composition_ownership` permits `ThrowRuntime` construction only in `ThrowRuntime.swift`.
- `throw.layer_frame_erasure_ownership` permits raw DEBUG Testing `LayerFrame` construction only in `ProjectionModels.swift`.
- `throw.projected_frame_erasure_ownership` permits raw `ProjectionFrame` and `ProjectedLayer` construction only at the ThrowUI presentation boundary.
- `throw.typed_projection_families` preserves each layer kind's element or style
family, keeps airport identity in its glyph descriptor, and rejects erased
mark-array replacement at the presentation boundary.

Repair a violation by injecting the existing object or by using a typed layer
or experience frame. Change an owner only when the matching Throw module contract changes.

## Gregorian calendar

`where.gregorian_calendar` rejects `Calendar.current` throughout Where's
Expand Down Expand Up @@ -125,7 +148,11 @@ conformance only in the Where app component.
Where production sources. Production logging uses the typed `WhereLog` or
`RegionLog` Periscope facades.

This complements `where.logging_type_ownership`, which controls where the
`throw.logging_facade` rejects direct system-log imports and raw diagnostic
output calls in Throw production sources. Production logging uses typed
`ThrowLog` events.

This complements `repository.logging_type_ownership`, which controls where the
typed event declarations live.

## Preview coverage
Expand All @@ -141,13 +168,38 @@ WhereIntents and WhereWidgets explicitly forbid direct `BroadwayCore` and

## Logging vocabulary ownership

`where.logging_type_ownership` keeps every nominal type ending in `Log` under a
module's `Sources/Logging` directory. This preserves the existing convention
that collaborators and their typed Periscope event vocabulary do not accrete in
the same files.
`repository.logging_type_ownership` keeps every nominal type ending in `Log`
under a Where or Throw module's `Sources/Logging` directory. This keeps typed
Periscope event vocabulary separate from collaborators.

Repair a violation by moving the logging type into the owning module's Logging
directory. Delete or reshape the rule if the repository deliberately adopts a
different logging vocabulary layout. Bumper's standard
`singleNominalSpelling` shaper expresses the invariant; no custom syntax rule
is needed.

## Throw concrete view boundaries

`throw.no_any_view` rejects `AnyView` in Throw production sources. Controller
and projection scenes compose concrete ThrowUI roots. Runtime handoff exposes
the shared session instead of erasing the view type.

## Throw provider boundary

`throw.provider_implementation_boundary` rejects concrete aircraft provider
sources and decoders in ThrowUI. Source setup and provider capabilities go
through `AircraftSourceOperationServing`, whose production implementation is
owned by ThrowCore.

## Throw checked concurrency boundaries

`throw.checked_concurrency_boundaries` rejects `@preconcurrency` and
`nonisolated(unsafe)` in all Throw production sources. Repair a violation with
checked isolation. Do not add an exception without first documenting and
testing the synchronization boundary.

## Throw controller-scene lifecycle

`throw.controller_scene_lifecycle` rejects app-delegate background and
foreground callbacks in the Throw app. Controller roots deliver their exact
scene identities and lifecycle transitions to the process runtime instead.
21 changes: 21 additions & 0 deletions .bumper/Sources/RepositoryProjectRules.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import BumperBowlingCore

let repositoryProjectRules = RuleSet {
Rules.singleNominalSpelling(
suffix: "Log",
owner: loggingScope,
id: "repository.logging_type_ownership",
)
}

private let loggingScope = RuleScope
.under("Where/RegionKit/Sources/Logging")
.union(.under("Where/Where/Sources/Logging"))
.union(.under("Where/WhereCore/Sources/Logging"))
.union(.under("Where/WhereUI/Sources/Logging"))
.union(.under("Where/WhereIntents/Sources/Logging"))
.union(.under("Where/WhereWidgets/Sources/Logging"))
.union(.under("Where/WhereShareExtension/Sources/Logging"))
.union(.under("Throw/Throw/Sources/Logging"))
.union(.under("Throw/ThrowCore/Sources/Logging"))
.union(.under("Throw/ThrowUI/Sources/Logging"))
23 changes: 23 additions & 0 deletions .bumper/Sources/ThrowArchitecture.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import BumperBowlingCore

extension ComponentShape {
static let throwCoreLayer = ComponentShape {
MayUse(.foundation)
}

static let throwPresentationLayer = ComponentShape {
MayUse(.foundation, .swiftUI, .uiKit)
}

static let throwHostLayer = ComponentShape {
MayUse(.foundation, .swiftUI, .uiKit)
}
}

extension AssertionShape {
static let throwArchitecture = AssertionShape {
DependencyBoundaries(.error)
SingleOwner(.error)
AcyclicDeclaredDependencies(.error)
}
}
Loading
Loading