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
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ accepted the prerequisite order `E3-06 -> E3-01 -> E0-07` in `D-42`. `E3-01` is
`E0-07`, the walking skeleton, `E1-02`, the Vehicle domain story, `E1-03`, the Vehicle data story,
`E1-04`, the Fuel Entry domain story, and `E1-05`, the human-gated consumption calculation story,
`E1-06`, Fuel Entry data, `E1-07`, Android Vehicle UI, `E1-08`, Android Fuel Entry UI, and
`E1-09`, iOS UI: Vehicles and Fuel Entries, `E1-10`, Settings, and `E1-11`, the Vehicle outbox
payload `entityType` fix, are complete. `E1-13` owns the
`E1-09`, iOS UI: Vehicles and Fuel Entries, `E1-10`, Settings, `E1-11`, the Vehicle outbox
payload `entityType` fix, and `E1-12`, the shared-test graph-close race fix, are complete. `E1-13` owns the
executable iOS locale-provider behavior coverage gap recorded by the E1-10 review.

### Delivery status and remaining work

- **Completed:** all Phase 0 stories; `E1-01` through `E1-10`; the pulled-forward `E3-06` and
- **Completed:** all Phase 0 stories; `E1-01` through `E1-12`; the pulled-forward `E3-06` and
`E3-01` prerequisites; and the `E0-07` walking-skeleton gate, including D-73 cleanup evidence.
- **Next:** `E1-12`, `FuelEntryStateHolderTest` Kotlin/Native SIGSEGV on graph close.
- **Remaining Phase 1:** `E1-12`, `E1-13`.
- **Next:** `E1-13`, executable iOS locale-provider behavior coverage.
- **Remaining Phase 1:** `E1-13`.
- **Remaining Phase 2:** `E2-01`, `E2-02`, `E2-03`, `E2-06`, `E2-04`, `E2-07` and `E2-05`.
- **Remaining Phase 3:** `E3-10`, `E3-11`, `E3-02`, `E3-03`, `E3-08`, `E3-04`, `E3-12`,
`E3-05`, `E3-07` and `E3-09`. `E3-01` and `E3-06` are already complete.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Cross-platform mobile app for Android and iOS to track vehicle costs.

The MVP is intentionally limited to **fuel expenses**: users can create vehicles, log refueling events, review their history, and calculate real-world fuel consumption in **L/100 km**. Later phases may add maintenance, insurance, taxes, and other expense types, but they are out of scope for the MVP.

> **Project status:** **Phase 1 open.** `E1-01` through `E1-08`, `E3-06`, `E3-01` and `E0-07` have delivered the SQLDelight database, complete local Vehicle and Fuel Entry repositories, Fuel Entry validation, reviewed full-to-full consumption, executable provider decoupling, reviewed Firestore rules, the native walking skeleton and the Android Vehicle and Fuel Entry flows. `E1-09`, iOS UI, is next. The project builds on both platforms and `main` is protected by ten required CI checks.
> **Project status:** **Phase 1 open.** `E1-01` through `E1-12`, `E3-06`, `E3-01` and `E0-07` have delivered the SQLDelight database, complete local Vehicle and Fuel Entry repositories, Fuel Entry validation, reviewed full-to-full consumption, executable provider decoupling, reviewed Firestore rules, the native walking skeleton, both native Vehicle and Fuel Entry flows, device-local settings, and deterministic shared graph-test teardown. `E1-13`, executable iOS locale-provider behavior coverage, is next. The project builds on both platforms and `main` is protected by ten required CI checks.

## Start here

Expand Down Expand Up @@ -177,7 +177,7 @@ document wins and the discrepancy is escalated.
| Phase | Goal | Main gate |
|-------|------|-----------|
| 0 - Foundations **(complete)** | Owner decisions closed, KMP skeleton, convention plugins, core modules, quality tooling, CI, ADRs | Android and iOS build in CI; architecture rules fail correctly |
| 1 - Local persistence **(active)** | `E1-01` through `E1-11` and the `E0-07` gate are complete; `E1-12` and `E1-13` remain | The walking skeleton proves the native local/remote path, both native Vehicle and Fuel Entry flows are executable, device-local settings are persistent, and the Vehicle outbox payload `entityType` contract compliance is restored |
| 1 - Local persistence **(active)** | `E1-01` through `E1-12` and the `E0-07` gate are complete; `E1-13` remains | The walking skeleton proves the native local/remote path, both native Vehicle and Fuel Entry flows are executable, device-local settings are persistent, Vehicle outbox payload `entityType` compliance is restored, and shared graph tests tear down deterministically |
| 2 - Authentication **(planned)** | E2-01 through E2-07 remain | Adoption and normal linking preserve data; confirmed collisions preserve the current anonymous snapshot |
| 3 - Backend and backup **(partially complete)** | E3-06 and E3-01 are complete; the remaining backend, cleanup, sync and recovery stories are open | Recovery and provider decoupling are executable checks |
| 4 - MVP hardening **(planned)** | E4-01 through E4-04 remain | Store-readiness checklist complete |
Expand Down
7 changes: 4 additions & 3 deletions docs/BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,8 @@ Blocks: E2-06.

### E1-12 - `FuelEntryStateHolderTest` Kotlin/Native SIGSEGV on Graph Close - S

Status: open. Registered as GitHub issue #42. Tracked as a follow-up of `E1-08` introduced by
Status: completed on 2026-09-02. See `docs/handoff-E1-12.md`. Registered as GitHub issue #42.
Tracked as a follow-up of `E1-08` introduced by
commits `a5150d4`, `87abdd0`, `ba8823a`. This story is a test-infrastructure defect, not a
production defect: no production code path closes an `AppGraph` while its state holders are still
collecting.
Expand Down Expand Up @@ -1090,8 +1091,8 @@ proof after E3-04.
| E1-08 Android UI fuel entries (completed) | 1 | L | — |
| E1-09 iOS UI (completed) | 1 | L | — |
| E1-10 Settings persistence (completed) | 1 | S | — |
| E1-11 `:feature:vehicle` outbox payload entityType fix | 1 | S | — |
| E1-12 `FuelEntryStateHolderTest` Kotlin/Native SIGSEGV on graph close (issue #42) | 1 | S | Yes |
| E1-11 `:feature:vehicle` outbox payload entityType fix (completed) | 1 | S | — |
| E1-12 `FuelEntryStateHolderTest` Kotlin/Native SIGSEGV on graph close (completed; issue #42) | 1 | S | Yes |
| E1-13 Executable iOS locale-provider behavior coverage | 1 | S | Yes |
| E2-01 `:core:auth` | 2 | S | — |
| E2-02 Firebase Auth integration | 2 | L | Yes |
Expand Down
53 changes: 53 additions & 0 deletions docs/PROJECT_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,59 @@

## Entries

### 2026-09-02 — E1-12 review corrections: orphaned harness Job and exception-safe teardown

- **Type:** correction
- **Story / Decision:** `E1-12` / —
- **Author:** opencode (GLM), on behalf of David Ruiz
- **What changed:** corrects the E1-12 story entry above on two points. First, `AppGraphTestHarness`
created `scopeJob` before validating that `parentScope` contained a `TestCoroutineScheduler`, so a
failed construction left an orphaned child `Job` on the parent; the scheduler is now resolved and
validated first, and the constructor test proves no child remains attached. Second, the harness
test teardowns now use nested `try/finally` so `owningFactory.close()` always runs, and the
obsolete `DatabaseFactory` / `DatabaseHandle` imports were removed from `AppGraphCloseTest.kt`.
- **Why:** the PR #49 review round found that a failed harness construction leaked a `Job` into the
parent scope and that a throwing `harness.close()` or `graph.close()` could skip the owning
factory close. Both are test-infrastructure defects inside E1-12 scope; production D-89 behavior
is untouched.
- **Correction of record:** the original E1-12 entry reports 30 `:shared` tests per target, which
was accurate at its time. The two harness tests added by the review rounds raise the final count
to 32 tests, 0 failures, 0 skipped on each of `:shared:testAndroidHostTest` and
`:shared:iosSimulatorArm64Test`. The original entry is otherwise unchanged.
- **Documents touched:** `docs/handoff-E1-12.md`, this log, and the E1-12 `:shared` common-test
files listed in the handoff.
- **Verification:** extended constructor test RED against the old implementation
(`[SupervisorJobImpl{Active}]` attached to the parent), GREEN after the fix; focused shared
verification passed 32 tests per target; the complete non-instrumented command passed;
`contractCheck` reports no unresolved decisions and no `PENDING` assertions; `git diff --check`
clean; the `backgroundScope` source audit still finds no direct state-holder collector launch.
- **Follow-ups / risks:** none new. PR #49 still requires human review and must not be merged by
an agent.

### 2026-09-02 — E1-12 shared graph-test teardown made deterministic

- **Type:** story
- **Story / Decision:** `E1-12` / —
- **Author:** Codex, on behalf of David Ruiz
- **What changed:** added a reusable `AppGraphTestHarness` that owns a child coroutine scope,
launches state-holder collectors eagerly and cancels and joins the complete scope before closing
its graph. Migrated every Kotlin caller-owned graph holder scope in `:shared` tests, removed all
direct `backgroundScope.launch` state-holder collectors and audited every test class that mounts
an `AppGraph`.
- **Why:** `runTest` cancels `backgroundScope` after the test body returns, so closing the graph in a
`finally` block could release the native SQLite driver while test-owned collectors were still
subscribed. Kotlin/Native could then abort with signal 11 instead of reporting a test result.
- **Documents touched:** `AGENTS.md`, `README.md`, `docs/BACKLOG.md`,
`docs/handoff-E1-12.md`, this log, and the E1-12 `:shared` common-test files listed in the handoff.
- **Verification:** deterministic RED proved the missing ordering; all 30 `:shared` tests pass on
Android host and `iosSimulatorArm64`; the Native suite passed 10/10 consecutive forced local runs
on Apple silicon; the complete non-instrumented command from `AGENTS.md` passed with 627
actionable tasks; `contractCheck` reports 111 aligned decisions and ADRs with no unresolved or
pending assertions.
- **Follow-ups / risks:** the PR requires human review and repeated macOS CI evidence before merge.
Production hardening of `AppGraph.close()` against live external subscribers remains explicitly
deferred to a separate story because it would change D-89 and touch gated `core/database/**`.

### 2026-09-02 — E1-11 parity test corrected: it proved cascade-then-cascade, not cascade-then-direct

- **Type:** correction
Expand Down
Loading
Loading