Skip to content

Map the apps/web component layer #47

Description

@chrhicks

Purpose

Use this issue as the working map for the apps/web React module layer after the runtime deepening completed under #18. Track accepted decisions, the ordered implementation frontier, completed evidence, and unresolved design questions here.

The goal is a scannable application composition with local visual modules, closed workspace interfaces, explicit UI-state ownership, and cohesive workflow modules. The existing deep workspace runtime remains the source of application state and semantic intents.

Notes

  • WorkspaceRuntime.states + submit is the current deep runtime interface. This map does not move runtime or service authority into React.
  • The source under .gh/clone/nightbook-prototype is disposable material supplied for selecting the UI modules Astro Console wants. Its Gallery, demo, package build, generated output, documentation, and backlog are not ongoing product authorities or migration requirements.
  • The borrowed @nightbook/ui package has one application consumer. Its useful visual module interfaces can remain while its package seam disappears.
  • The project-local react-app-design skill now includes an authoritative composition-and-organization reference. It covers rendered and dependency trees, UI-state lifetimes, purpose-named Hooks, providers, HOCs, explicit variants, compound modules, source locality, package localization, and composition briefs.
  • App.tsx should become a scannable SPA composition outline through bounded later slices, not one broad file-splitting exercise.
  • Service authority, semantic runtime intents, URL ownership, client-only Process stage navigation, and read-only phone behavior remain unchanged unless a later accepted product issue says otherwise.

Decisions so far

  1. Astro Console will own the selected shared visual module source inside the web application rather than through @nightbook/ui.
  2. Only UI modules used by Astro Console and their required private dependencies will be copied. Unused prototype exports will not be retained for possible future use.
  3. The external checkout is throwaway input. No Gallery, demo, resetless consumer, generated distribution, package configuration, provenance workflow, or upstream synchronization will be preserved.
  4. The localized UI implementation will use neutral local identifiers rather than Nightbook package branding.
  5. Package localization and React module redesign are separate decisions. The first implementation slice preserves observable UI behavior and current workspace interfaces.
  6. Later composition work will design interfaces before moving files. It will use ownership, depth, locality, seam placement, and deletion tests rather than file size or a broad component taxonomy.
  7. Hooks, private providers, explicit wrappers, and HOCs are available mechanisms. Each must hide cohesive UI behavior or repeated adaptation without taking ownership from the runtime.
  8. Functional browser evidence and Designer evidence remain separate. Every UI-affecting slice requires wide, compact, and 390 px phone review.
  9. One issue represents one coherent outcome at one primary proof seam. Its workflow may use several small module-sized commits; each checkpoint should compile and pass relevant focused checks where practical.
  10. A task absorbs a discovered concern only when it blocks the accepted outcome, stays behind the same interface and proof seam, changes no product behavior, and adds little review uncertainty. Every other observed concern goes to Track evidenced component-layer findings #49.
  11. Current direct visual-module testing remains minimal. Record evidenced gaps in Track evidenced component-layer findings #49 and add focused tests when a later task changes the affected module.
  12. Remove retired presentation and runtime naming in two adjacent behavior-preserving tasks before publishing the detailed composition audit.
  13. The completed composition audit confirms the URL as navigation owner, the service as product-truth owner, WorkspaceRuntime.states + submit as the deep external-runtime interface, and each workspace as owner of its local drafts and interaction state.
  14. The first application-composition child is Adapt WorkspaceRuntime into React through a purpose Hook #55: one purpose Hook adapts WorkspaceRuntime into React and removes Effect runtime lifecycle knowledge from App without moving route or product authority.
  15. Provider, HOC, compound-module, generic wrapper, and broad route-adapter changes are not selected. Library and Process closed route interfaces, repeated phone projection, and active-only Tabs remain separate later decisions.

Composition audit result

Audit point: main at eb9f2c5, after #48, #50, and #51. Current V2 documents and active local source were the only authority.

Rendered tree

App
└─ lazy route outlet
   ├─ PlanWorkspace
   │  ├─ CommandBar
   │  └─ PlanPhone | PlanDesktop(editor, review, confirmation)
   ├─ ObserveWorkspace
   │  ├─ CommandBar
   │  └─ ObservePhone | ObserveDesktop(target or normal workflow)
   ├─ LibraryWorkspace
   │  ├─ CommandBar
   │  └─ LibraryPhone | LibraryDesktop(catalog or asset detail Tabs)
   └─ ProcessWorkspace
      ├─ CommandBar
      └─ ProcessPhone | SourceIntake | ProjectList | ProjectWorkspace

Source and delivery tree

main.tsx → App
App
├─ browser route + history
├─ WorkspaceRuntime React lifecycle
├─ route-specific model/action adaptation
└─ lazy workspace modules

WorkspaceRuntime.states
  service/bootstrap/HTTP facts
  → loading, freshness, cancellation, reconciliation
  → App React snapshot
  → workspace props

workspace semantic action
  → App callback adapter
  → WorkspaceRuntime.submit(intent)
  → remote adapter
  → typed submission or reconciled state

WorkspaceRuntime, each workspace, and CommandBar pass the deletion test. Removing any one spreads substantial runtime coordination, workflow state, or shell/control knowledge across callers.

State-owner and lifetime map

Changing fact Accepted owner Lifetime and reset
Route, workspace, Asset, source, and Project identity URL and browser history Browser navigation; decoded once by App
Library query App client workflow App mount; not currently URL state
Confirmed facts, eligibility, revisions, health, and control Rig-local service Service truth and durable state
Loading, freshness, cancellation, route loads, comparison, and reconciliation WorkspaceRuntime Runtime mount; route/query generation resets
Delivered React snapshot and runtime readiness App before #55; selected React adapter after #55 Application mount; one-way publication only
Plan draft, sequence selection, review tab, pending confirmation Plan workflow Plan workspace; draft resets by Plan identity/revision
Observe and Acquire pending feedback Nearest Observe workflow Workflow mount; result resets by authoritative revision
Library review draft and preview interaction Library detail workflow Asset identity/review revision or resource identity
Library comparison selection Library comparison workflow plus runtime loader Asset/peer selection; duplicate ownership and hidden work remain in #43
Library intake selection and destination draft Library workspace workflow Current workspace mount; route/query reset policy is unresolved in #49
Process viewed stage and action feedback Process workspace Workspace mount; Project reset policy is unresolved in #49
Process source name and Develop stretch draft Keyed source/Project workflows Source Asset or Project plus draft revision
Shell control Flyout, pending action, and feedback CommandBar local interaction CommandBar route mount; Escape restores trigger focus
Phone projection Browser matchMedia publisher Workspace/simulation mount; five repeated adapters remain in #49
Active tab and keyboard focus Workspace caller plus Tabs visual module Caller workflow lifetime; inactive panels currently stay mounted
Development simulation snapshot and control draft Simulation endpoint plus simulation workflow Endpoint/cache lifetime and simulation surface mount
Labels, grouping, progress, disabled presentation Derived presentation Render only; no stored authority

Remote truth stays remote, runtime delivery stays in WorkspaceRuntime, URL identity stays in navigation, and local drafts remain in the nearest workflow. The audit does not move any of those owners.

Current interface findings

  • App mixes SPA composition with Effect runtime creation, Stream subscription, Fiber interruption, asynchronous disposal, seven stored command closures, browser navigation, Library query, and four route adapters.
  • Plan has 4 public props; Observe 8; Library 16; Process 9. Library and Process correlated optional route states remain later closed-interface candidates in Track evidenced component-layer findings #49.
  • Four lazy outlets own accessible loading fallbacks but not chunk failure or retry; this remains in Track evidenced component-layer findings #49.
  • CommandBar remains a deep interface. Its deletion spreads navigation, health, control, feedback, and simulation behavior.

Mechanism and deletion comparison

Option Decision Reason
Purpose Hook Select #55 Hides a real React-to-Effect lifecycle seam and removes non-composition knowledge from App
Explicit route adapter Defer Valuable, but Library and Process route/state lifetimes need separate decisions
Direct wrapper Reject now Would mainly move JSX or forward broad props without hiding policy
Provider / Context Reject Direct delivery is short-range; no coherent distant subtree needs implicit access
HOC Reject No repeated wrapper-time policy across independently useful modules
Compound module Reject Callers do not need to arrange shell or workspace roles; fixed composition should remain private
Collapse Keep current deep seams Collapsing WorkspaceRuntime, workspaces, or CommandBar spreads knowledge; no selected shallow alias blocks #55
Phone projection Hook Defer Real repeated browser seam, but lower leverage than removing the complete runtime lifecycle from App
No change Reject for App lifecycle App currently owns Effect mechanics outside its SPA composition job

Selected child and proof seam

#55 adds one private useWorkspaceRuntime adapter with an explicit Starting | Ready binding. It owns one runtime per App mount, ordered state delivery, submit adaptation, unsubscribe, late-publication protection, and disposal. It does not interpret intents, infer eligibility, move route/query authority, change workspace props, or change presentation.

The primary proof seam is a mounted Hook with a private deterministic runtime source. It must prove readiness, ordered publication, one submission, unmount disposal, late-event rejection, and independent setup → cleanup → setup lifetimes. The full web check and functional route smoke remain required.

All other evidenced concerns are recorded in #49 or remain in #43. Exactly one child is ready.

Ordered frontier

Only the first unblocked, ready child is accepted implementation work. Blocked ready tasks expose the horizon but must not run in parallel. Do not create the rest of the frontier as a component-sized refactoring backlog.

Verification direction

Each child defines its focused proof. Prefer the highest existing seam:

  • workspace and application interfaces for functional React behavior;
  • WorkspaceRuntime.states + submit for runtime delivery and semantic intents;
  • rendered routes for keyboard, focus, overflow, console, and responsive behavior;
  • Designer review for visual and usability quality.

Tests should observe caller-visible behavior and survive private composition and file movement.

Finish line

Close #47 when:

  1. shared visual modules are locally owned and the borrowed package is gone;
  2. active application source and current documentation no longer use retired prototype ownership language;
  3. the application root is a scannable SPA composition outline;
  4. each workspace receives a closed model and semantic actions instead of correlated optional wiring;
  5. consequential local UI state has an explicit owner, lifetime, and reset identity;
  6. inactive tab workflows perform no hidden work and retain state only by an explicit decision;
  7. selected shallow aliases and accidental exports are removed;
  8. Track evidenced component-layer findings #49 contains no unresolved correctness or high-leverage locality finding;
  9. lower-value improvements are explicitly rejected or deferred; and
  10. current functional and Designer evidence is green.

This finish line does not require splitting every large workspace, adding direct tests for every visual module, extracting every possible Hook or HOC, or producing a perfect component taxonomy.

Fog

  • Local shared UI uses a shallow visual-module layout with shared foundations. The audit keeps those visual interfaces and current workspace composition unchanged while Adapt WorkspaceRuntime into React through a purpose Hook #55 removes external-runtime lifecycle mechanics from the root.
  • The React runtime-adapter seam is fixed in Adapt WorkspaceRuntime into React through a purpose Hook #55. Later Library and Process route-adapter boundaries remain to be designed from caller knowledge and state lifetime.
  • The first workspace to deepen after the application composition is not selected. Library remains a strong candidate because it combines catalog/detail routes, Tabs, comparison work, review drafts, Processing Project intake, and phone behavior.
  • Presentation and runtime naming scopes are fixed in Retire Nightbook presentation naming #50 and Retire Nightbook workspace runtime naming #51. Any name that requires an ownership decision rather than a direct purpose replacement goes to Track evidenced component-layer findings #49 instead of expanding those mechanical tasks.
  • HOCs are not selected for any current seam. They remain an option only where several independently useful modules need the same wrapper-time adaptation and a Hook, provider, or explicit wrapper is less clear.

Relationships

Metadata

Metadata

Assignees

No one assigned

    Labels

    wayfinder:mapDurable decision map; entries are not accepted work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions