Lab 2 assignment · due August 15

Build the system behind the next slice.

Take MAL Local from a single app to a small, explainable product system: a customer mobile app, an admin website, concurrent workflows, modular boundaries, a local LLM, and production signals on mobile.

Customer mobile appAdmin management websiteConcurrency + modularityLocal LLM + Measure
One product · two surfaces

Different users. Shared state. Clear boundaries.

Both clients must work with the same domain concepts and demonstrate the same product state. The backend can be local, mocked, or minimal.

Customer mobile app

Browse and search nearby listings, open details, create or improve a listing, contact or close it, and see admin status changes after refresh or sync.

Admin website

See dashboard counts and activity, search listings, review flags, and change operational status to active, flagged, hidden, or closed.

Shared domainListing, category, neighborhood, IDs, and status transitions.
Shared data boundaryRepository, API, fixture, or local development service.
Replaceable servicesLocal LLM, persistence, and Measure behind interfaces.
Continue from MAL 1

Keep the local-first slice. Add system boundaries around it.

Lab 2 should grow from the MAL 1 marketplace work, not restart from a blank app unless the old slice cannot run.

Carry forward

  • Customer browse, search, create, save/contact/close workflows.
  • Local-first data model, seed data, validation, and reset path.
  • Lab 1 ADR, privacy assumptions, accessibility baseline, and local AI boundary.
  • Any working mobile UI, navigation, persistence, and local AI helper.

Evolve for Lab 2

  • Extract the product model into a shared contract for mobile and admin web.
  • Add the admin website as an operator surface for the same listings.
  • Make concurrency, module boundaries, local LLM fallback, and Measure visible.
  • Update the ADR with what changed, what stayed local-first, and why.
If MAL 1 is incomplete: continue from the smallest runnable slice: one listing list, one create flow, one persistence path, and one documented recovery path. Then add Lab 2 architecture around that slice.
Required implementation

Four signals reviewers should be able to find.

A smaller implementation with honest evidence is stronger than a wide feature list with hidden coupling.

01 · Concurrency

  • Implement two meaningful concurrent workflows.
  • Use structured tasks, actors, coroutines, workers, promises, or an equivalent primitive.
  • Show cancellation, stale-result handling, ownership of mutable state, and bounded work.
  • Test at least one race, ordering, cancellation, or failure case.

02 · Modular design

  • Separate customer mobile, admin web, shared domain/contracts, data, local AI, and observability.
  • UI does not own persistence, networking, or model-runtime code.
  • Product rules live outside views; vendor calls sit behind small interfaces.
  • Add docs/module-map.md with dependency direction and one replacement example.

03 · Local LLM

  • Choose listing assistant, search assistant, or safety assistant for mobile.
  • Run the expected flow with a local model/runtime.
  • Provide a deterministic fallback for missing, slow, or failed models.
  • Keep output editable; never silently publish or hide a listing.

04 · Measure on mobile

  • Use Measure for mobile observability, analytics, and product events.
  • Track app open, feed view, search, create, local LLM, and contact flows.
  • Capture failures, latency buckets, cancellation, and fallback reason.
  • Do not send descriptions, phone numbers, exact addresses, or precise coordinates.
Measure is mandatory on the mobile client. Document the final event taxonomy and privacy review in docs/observability-events.md. Carry forward Lab 1 accessibility, validation, local-data privacy, and recovery expectations. Verify the integration in Measure, or document the temporary local debug sink and the final path if setup is still in progress.
Mobile event baseline

Name the signals before you scatter calls.

Use stable names and safe properties. The exact SDK API depends on your chosen mobile stack; follow the current Measure integration guide.

EventTriggerSafe properties
customer_app_openedApp reaches usable stateversion, platform
listing_feed_viewedCustomer feed is visiblecoarse area, result count
listing_search_submittedSearch is submittedquery length, filter count
listing_create_completedValidated listing savescategory, duration bucket
local_llm_completedModel or fallback returnsfeature, local/fallback, latency bucket
listing_contactedContact action is selectedlisting category
14-day build plan

Make the architecture emerge in order.

Start August 2. Submit August 15, before Lab 3. Adjust the sequence to your stack, but keep the evidence trail.

DAY 01

Re-scope

Customer/admin workflow and non-goals.

DAY 02

Shared model

Entities, IDs, and status transitions.

DAY 03

Module map

Packages and dependency direction.

DAY 04

Mobile shell

Feed and navigation.

DAY 05

Admin shell

Dashboard and listing views.

DAY 06

Data boundary

Repository, API, or fixture.

DAY 07

Concurrent load

Parallel work and cancellation.

DAY 08

Race tests

Stale results and failures.

DAY 09

LLM boundary

Adapter and fallback.

DAY 10

LLM flow

Editable output and latency.

DAY 11

Measure

Events, errors, analytics.

DAY 12

Cross-client

Admin change in mobile.

DAY 13

Evidence

ADR and implementation notes.

DAY 14

Rehearse

Fresh setup and demo.

Review rubric · 20 points

Show the decisions, not just the screens.

Reviewers will run the core flows, inspect the boundaries, and check the evidence documents.

AreaPointsWhat good looks like
Customer mobile app3Browse/search/create/action loop is usable.
Admin website3Real listing management and status workflow works.
Concurrency4Parallel work, cancellation/ownership, and tests.
Modular design4Replaceable data, AI, and observability layers.
Local LLM3Local model path, deterministic fallback, safe editable output.
Measure2Mobile observability, analytics, and event privacy review.
Documentation1Fresh setup, ADR, and evidence docs are easy to find.
Architecture fixes

Turn the assessment into the next work plan.

Each team should leave review with two or three concrete architecture fixes, not only a score.

AreaWhat to look forWhat to fix or work on
Product boundaryCustomer and admin flows use different models, labels, or status meanings.Create one shared contract for listing, category, neighborhood, contact preference, and status transitions.
Module boundariesScreens directly call persistence, network, local model, or Measure APIs.Move those calls behind repository, LocalLlmService, and observability interfaces.
Dependency directionAdmin, mobile, shared data, and AI code import each other in both directions.Define allowed dependencies in docs/module-map.md and break cycles with interfaces or adapters.
Concurrency ownershipAsync work updates shared state from multiple places or survives after a screen/request ends.Add one owner for mutable state, cancellation rules, stale-result handling, and a race/cancellation test.
Cross-client consistencyAdmin changes are not visible in mobile, or the sync path is undocumented.Make both clients use the same repository/API/fixture and document refresh or sync behavior.
Local LLM boundaryPrompting, parsing, fallback, or model-runtime code lives inside UI components.Move AI behavior into a service with typed input/output, editable results, fallback, and failure events.
Observability boundaryMeasure calls are scattered across screens or include sensitive payloads.Route events through one analytics boundary and document safe properties.
Evidence qualityReviewers cannot understand decisions without reading all the code.Tighten the ADR, module map, concurrency notes, and demo script.
Required docs: docs/product-slice.md, docs/concurrency-notes.md, docs/module-map.md, docs/local-llm-note.md, docs/observability-events.md, docs/success-metrics.md, and docs/adr/0002-two-client-concurrent-local-llm-architecture.md.
Three-minute demo

One path through the system.

The demo should work from a clean state and be repeatable twice.

01 · Customer

Open the mobile app, show Measure-backed app-open/feed signals, search, and open a listing.

02 · Local AI

Improve a listing with the local LLM, disable it, and show the deterministic fallback and event.

03 · Operator

Hide the same listing in the admin website, refresh or sync mobile, and show the status change.