Skip to content

docs: align guides with 0.7.33 screen-process architecture + recent feature coverage - #105

Merged
GenericJam merged 7 commits into
masterfrom
docs/refresh-0733
Aug 30, 2026
Merged

docs: align guides with 0.7.33 screen-process architecture + recent feature coverage#105
GenericJam merged 7 commits into
masterfrom
docs/refresh-0733

Conversation

@GenericJam

@GenericJamGenericJam commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Audit of every guide, the README, and the public moduledocs against current master (0.7.34 + #103). The moduledocs written alongside MOB-108–114 were already accurate; the drift was concentrated in the guides and a few docstrings that predate the work. Sections marked rewrite replaced a wrong model; everything else is a surgical edit.

Per-doc changes

guides/navigation.md

  • Tab bar / Drawer sections (rewrite): claimed native chrome (UITabBarController / NavigationBar / ModalNavigationDrawer) that is not drawn — now describe the multi-stack runtime honestly, with the :tab_barwidget + switch_tab/2 as the interim chrome path.
  • New Tabs and multi-stack state section: lazy materialization, parking, independent histories, back-at-secondary-root, the orphan stack, MOB-115/116/117 gaps.
  • switch_tab/2 semantics (first visit mounts root, no-op cases, no animation); directional resets gain the ArgumentError validation (incl. why :none is rejected) and the transition-survives-coalescing behavior (feat(navigation): allow directional resets #100/fix(navigation): preserve initial transition #103).
  • Tap examples fixed from handle_event("tap", %{"tag" => ...}) to handle_info({:tap, tag}) — the shape a real tap delivers.

guides/screen_lifecycle.md (edits — the process-model intro was already updated by #101)

  • New Crashes and restarts section: per-screen isolation, restart cap (5/10s), re-mount + load_state/2, per-screen self() and message delivery.
  • terminate/2: when it actually runs, persisted-state dump, pop stops only the leaving screen.
  • System back: multi-stack semantics (secondary-stack root switches to the first stack; only the first stack's root exits).

guides/testing.md

  • New leading section on Mob.ScreenCase (Mob.ScreenCase: blessed in-BEAM screen testing (+ contract check, device backend) #44) — previously undocumented in any guide.
  • Removed Mob.Test.screen_pid/1 (does not exist) and the :sys.get_state(:mob_screen) sync-point advice (insufficient since MOB-110/112); replaced with Mob.Test.settle/2 and an explanation of the three processes it drains.
  • Unit-test examples corrected for the process model (synchronous dispatch/3 for navigation; get_socket/1 as the natural sync point after send).

guides/components.md

  • New :sheet section: Mob.UI.sheet/2 / <Sheet> (0.7.29), presence-is-presentation, intrinsic [:content] detents (0.7.32), exactly-once {:dismiss, tag}, iOS scrim limitation. Only the surface-matrix row covered sheets before.
  • New Handle limits section: 256 tap handles per frame (handler silently unwired past the cap, logged) and 256 native component slots ({:error, :component_slots_exhausted}) — 0.7.28 behavior.
  • :text gains the font prop row (named font tokens, 0.7.25).

guides/theming.md — fonts were absent entirely; adds the fonts: / font_fallback: token type (0.7.25) with a pointer to Styling → Custom fonts (which already covered the mechanics).

guides/agentic_coding.md (restructure into two halves, existing content order preserved)

  • Working with one agent: existing content plus verify-effects-not-exit-codes, the honesty contract (assert on state change; settle-window caveat), match-the-evidence-to-the-question, lifecycle-event simulation recipes (simctl push .apns, adb broadcast / cmd notification post), environment discipline (.tool-versions completeness, MOB_DIR/MOB_DEV_DIR/MOB_NEW_DIR). The standard loop gains a settle/2 step; the worked example's handle_event slip fixed.
  • Working with agent teams (new): one driver per device + lease discipline, unique node names (mob.connect --name), per-task worktrees, the mob.push/mob.watch fan-out hazard (verified: no device scoping — switches are --all/--cookie only), durable artifacts.

README.md — counter example handled taps in handle_event("tap", ...), which a device tap never reaches; now handle_info({:tap, :increment}) with a sentence on delivery. Diagram node updated to Mob.Screen.Server (one per live screen). Testing snippet moved to Mob.ScreenCase.

guides/device_capabilities.md — four handle_event("tap", ...) examples → handle_info({:tap, ...}).

guides/getting_started.md — referenced Mob.Nav.push/2, which does not exist; now Mob.Socket.push_screen/2,3.

guides/event_audit.md — list-select re-emitter is Mob.Screen.Server since MOB-113.

lib/mob/app.extab_bar/1/drawer/1 docstrings no longer claim chrome that is not drawn.

lib/mob/test.ex — moduledoc claimed tap/2 goes through handle_event/3; it sends {:tap, tag} to handle_info/2.

mix.exsMob.Router, Mob.Screen.Server, Mob.Listener, Mob.Sender, Mob.ScreenCase were shipping ungrouped in the hexdocs sidebar.

Deliberately not documented

Gates

🤖 Generated with Claude Code

GenericJamand others added 7 commits August 30, 2026 01:10
…emantics
navigation.md still described tab_bar/drawer as rendering native chrome
(UITabBarController / NavigationBar) — since 0.7.33 the runtime backs the
declaration with real per-stack state but draws no chrome; switching is
programmatic. New 'Tabs and multi-stack state' section documents lazy
materialization, parking, independent histories, back-at-secondary-root,
the orphan stack, and the MOB-115/116/117 gaps. Directional-reset docs
gain the ArgumentError validation and transition-survives-coalescing
behavior (#100/#103).
screen_lifecycle.md gains crash/restart semantics (per-screen isolation,
restart cap, re-mount + load_state), per-screen self() and message
delivery, terminate/2 reality (pop stops the leaving screen only), and
multi-stack system-back.
Mob.App.tab_bar/1 and drawer/1 docstrings no longer claim chrome that is
not drawn.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nt screen_pid/1
The testing guide never mentioned Mob.ScreenCase (#44), the blessed
in-BEAM unit-test path — it now leads the guide. The old sync-point
advice referenced Mob.Test.screen_pid/1, which does not exist, and
:sys.get_state on :mob_screen, which stopped being sufficient when
rendering moved to Mob.Sender (MOB-110) and :mob_screen became the
navigation owner (MOB-112); both are replaced with Mob.Test.settle/2
and an explanation of the three processes it drains. Unit-test examples
updated for the process model (dispatch is synchronous; get_socket is
the natural sync point after send).
Mob.Test's moduledoc claimed tap/2 goes through handle_event/3; it
sends {:tap, tag} to handle_info/2 like a real native tap.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
components.md had no coverage of Mob.UI.sheet/2 (0.7.29) or intrinsic
content detents (0.7.32) beyond the surface-matrix row — new ':sheet'
section documents presence-is-presentation, detents including
[:content] / [{:content, max_height: n}], exactly-once {:dismiss, tag},
and the iOS scrim limitation. New 'Handle limits' section covers the
256-handle tap pool and the 256-slot native component pool with
{:error, :component_slots_exhausted} (0.7.28 behavior). :text gains the
font prop (named font tokens, 0.7.25).
theming.md never mentioned fonts — adds the fonts:/font_fallback: token
type with a pointer to Styling → Custom fonts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
README and several guides showed UI taps handled by
handle_event("tap", %{"tag" => ...}) — a real tap delivers
{:tap, tag} to handle_info/2, so those example screens would never
respond on a device. README's diagram and testing snippet updated for
the per-screen process model and Mob.ScreenCase. getting_started
referenced Mob.Nav.push/2, which does not exist (Mob.Socket.push_screen
is the API). event_audit's list-select re-emitter is Mob.Screen.Server
since MOB-113.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ctices
Part 1 (Working with one agent) keeps the existing content in order and
adds: verify effects not exit codes (assert the app answers after a
deploy), the honesty contract (success = a handler ran — assert on state
change after a tap, settle-window caveat), match the evidence to the
question (frames for layout, screenshots-with-tolerance for appearance,
recordings for motion), lifecycle-event simulation recipes (simctl push
.apns, adb broadcast / cmd notification post), and environment
discipline (complete .tool-versions incl. zig/JDK, the
MOB_DIR/MOB_DEV_DIR/MOB_NEW_DIR override chain).
Part 2 (Working with agent teams) is new: one driver per device with
lease discipline (humans outrank agents), unique node names per session
(mob.connect --name), per-task git worktrees, the mob.push/mob.watch
fan-out hazard (they reach every live node, no device scoping — fleets
deploy per device or push over their own dist connection), and durable
artifacts as the handoff medium between context windows.
The standard agent loop gains a settle/2 step before native-side reads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mob.Router joins Navigation; Mob.Screen.Server, Mob.Listener and
Mob.Sender get a Runtime Processes group; Mob.ScreenCase joins
Testing & Debugging. All five were shipping ungrouped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Written minutes before #80 merged, the honesty-contract and
evidence-matching sections claimed no pixel-sampling API existed and
leaned solely on state-change assertions. Now that tap_xy/3 reports
observed effect, both guides document the contract: :ok only when an
event reached the BEAM within 300ms, else {:error, :no_view_at_point |
:no_element_at_point | :no_effect} — plus the platform limits that make
:no_effect legitimate (SwiftUI on_tap containers, physical-device
injection) and the serial-harness assumption the 300ms window shares
with state-change checks.
Evidence matching now splits exact-color decisions (sample_color/2:
real pixels, dominant/average as 0xAARRGGBB, iOS debug-build only) from
holistic visual parity (screenshots with tolerance). testing.md gains
matching sections.
No change needed for #77: push_notifications.md already described
tap-to-open from a killed app, which that fix made true.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@GenericJam
GenericJam merged commit 0483fd1 into masterAug 30, 2026
4 checks passed
@GenericJam

Copy link
Copy Markdown
OwnerAuthor

Review record: spot-verified the highest-consequence claims against master source (Mob.Nav is the state struct — no push/2 navigation API ever existed; screen_pid/1 absent; taps deliver {:tap, tag} to handle_info; tab_bar/1 layout draws no chrome while the :tab_bar widget path renders MobTabView — the guide's distinction is exactly right). Structure matches the requested single-agent/agent-teams split. Gates green on the rebased tree. Merged.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@GenericJam