Lumen/SPIKE-07-BOOTSTRAP.md
Lumen Stage1 c0bfd413ff Stage 1: project foundation (strict TS, lint boundaries B-1..B-7, directory structure, CI, boundary tests)
- dedicated git repo at /home/avi/Projects/Lumen (main)
- TypeScript strict (target ES2022, bundler, exactOptionalPropertyTypes, noUncheckedIndexedAccess)
- ESLint 9 + typescript-eslint strictTypeChecked + eslint-plugin-boundaries for B-1..B-7, no-restricted-globals/syntax for B-1/B-7
- Prettier 3.5
- Structure per IMPLEMENTATION-CONTRACT.md §4 (src/platform/idb|cache|sw, storage, data, sync/{transport,verifier}, domain/{emergency,schedule,map,festival,readiness,clock,favorites}, ui/{components,views,router,render}, app, emergency-baseline, assets, public, content, pipeline, tests, scripts)
- CI: .github/workflows/ci.yml (typecheck + lint + format + test)
- Boundary tests: tests/unit/boundaries.test.ts (4 tests) + scripts/check-boundaries.ts
- No feature code, no PWA/IDB/sync/mesh/accounts per contract Stage 1
2026-08-30 23:25:35 -05:00

5.9 KiB
Raw Permalink Blame History

SPIKE-07 — Installation & Bootstrap

  • Phase: Architecture Validation
  • Date: 2026-08-30
  • Decisions under test: ADR-002 (installed-first PWA) and the bootstrap design in ARCH §11/§12 (C-16, C-17).
  • Outcome: confirmed; introduces explicit preparation levels (L0–L2) and the Minimum Safe Experience definition.

1. Intended journey

flowchart TD
    A["Discovery: QR / link / poster / word of mouth"] --> B["First visit (online): shell loads ~1 MB, SW registers"]
    B --> C["Install coach (iOS manual steps; Android native prompt)"]
    C --> D["Preparation: 'Get festival data'"]
    D --> E["Data acquisition: pointer → manifest → sections (priority order) → assets; resumable"]
    E --> F["Validation: signature → hashes → schema → atomic activation"]
    F --> G["OFFLINE READY ✓ confirmation + status chip"]
    G --> H["Festival use: everything offline; sync opportunistic when online"]

    C -. skip/dismiss .-> D
    E -. interrupted .-> P["PARTIAL state; resume later"]
    P --> E

Stage persistence: after first visit the shell is cached (SW); after prep each section is staged/committed independently; favorites persist from first creation. No stage depends on completing later stages.

2. Preparation levels (new, normative)

Level Contents Meaning Chip state
L0 Shell + embedded emergency floor "Emergency works, nothing else" NOT_READY (or BASELINE_ONLY if storage blocked)
L1 — Minimum Safe L0 + dataset emergency section + schedule section Core festival survival: emergency detail + what's on when PARTIAL → "core ready" note
L2 — Full L1 + map + info + all required assets Complete promise READY

Download order is exactly emergency → schedule → info → map-base → assets, so an interrupted prep always yields the highest achievable level. The prep UI names the levels ("Emergency ready", "Schedule ready", "Map ready") so users always know what they have.

3. Failure-point analysis

# Failure Architecture behavior User experience
FP-1 User doesn't install (esp. iOS tab) Works while open; storage eviction risk after 7 days of tab inactivity (ITP); coach re-surfaces Coach + honest note: "install to keep your festival data"
FP-2 User closes browser mid-prep Staged files + progress persist; nothing activated prematurely Resume banner next open; prep continues where it stopped
FP-3 Internet lost during prep Downloads pause; partial staged data retained; app remains fully usable for installed levels "Paused — you have Emergency + Schedule so far"
FP-4 Insufficient storage storage.estimate() pre-check refuses staging if free < 2× package; QuotaExceeded handled Plain guidance: free space / reinstall; L0/L1 still possible if a full package can't fit — prep offers partial (sections only, skip heavy assets) as degraded option
FP-5 iOS install flow fails / user can't find Add to Home Screen Step-by-step coach with images; retry detection (still in tab after coach); fallback: continue in Safari with eviction warning No dead end: app works in tab, warns about persistence
FP-6 User arrives unprepared App boots to whatever exists (L0 floor minimum); honest status; one-tap prep if any connectivity appears; organizer physical fallback for critical info No blank screen; explicit "what's missing" list
FP-7 User clears browser data / uninstalls PWA Everything local is gone; floor returns only after shell reloads from network; RECOVERY state otherwise Re-prep path; nothing to do offline except reload shell when online
FP-8 Private browsing session Storage probes fail early → BASELINE_ONLY mode with explanation; no crash, no fake READY "Offline saving unavailable in this mode" + install/normal-mode guidance

Additional adjudications:

  • Prep before install (iOS tab) is allowed and valuable: data staged in tab storage survives until eviction; install later preserves it (same origin). The coach therefore offers "install first (recommended)" and "get data now".
  • First-visit ordering: shell precache completes before prep is offered, so L0 is guaranteed before any dataset work begins.
  • Leaving prep early is never punished: no state is invalidated by abandonment; the worst case is staying at the current level.

4. Minimum Safe Experience (normative)

For an attendee who never completed offline preparation, the app must still provide, in this order of guarantees:

  1. Always (after any successful shell load): the emergency floor — dial action, address/coordinates, security contact, muster points, core procedures (L0). This is Ring-0 and requires no storage.
  2. If any prep succeeded even partially: whatever levels completed, each fully functional (L1 core = emergency detail + schedule).
  3. Honest status at all times: the chip and status screen state exactly which levels are met and what to do about the rest.
  4. No feature silently pretends: map/info screens for missing sections show "not downloaded" cards with the prep action, not broken UI.

Product/ops corollary (cannot be solved by architecture alone): distribution before arrival (OQ-3) and physical fallback info at the venue remain necessary for the unprepared minority.

5. Cross-checks

  • Readiness mapping: L0↔NOT_READY/BASELINE_ONLY, L1↔PARTIAL, L2↔READY (SPIKE-05 taxonomy).
  • Emergency floor independence from storage (SPIKE-06) makes L0 unconditional.
  • Install-first persistence reality (SPIKE-01 §3.12) motivates the coach but tab usage is never blocked.

6. Verdict

ACCEPT WITH CHANGES. Bootstrap architecture stands; changes: formal L0–L2 levels with the fixed download order, Minimum Safe Experience definition, and the tab-install sequencing rule (allow prep before install). ADR-002 addendum records the levels; no direction change.