MiCyte

← The wiki

30 — L3 shell, runtime and UI

BuiltRendered from 30-l3-shell-runtime-ui.md in the public repository. Edits belong there.

The portal page is described by the shell state machine in micyte/state_machine/, composed per request by the host runtime, and rendered by the JavaScript shell.

Parts

PartLocationRole
Shell state machinemicyte/state_machine/portal_shell/Shell dataclasses, the surface catalog, the canonical query, tool eligibility. Pure: no I/O
Lensesmicyte/state_machine/lens/Encode and decode a datum value for display (81)
NIMM and AITASmicyte/state_machine/nimm/, micyte/state_machine/aitas/The staged-mutation contract and its context model
Runtimehost application, instances/_shared/runtime/Composes the page bundle for a request (portal_shell_runtime.py), the palette endpoints (portal_palette_runtime.py), the mutation lifecycle (portal_datum_workbench_mutation_runtime.py)
Flask hosthost application, instances/_shared/portal_host/app.pyRoutes, the JS module manifest, page rendering
JS shellhost application, instances/_shared/portal_host/static/Loads modules, posts to the runtime, validates the envelope, renders regions

Surfaces

build_portal_surface_catalog() in shell_registry.py lists 21 surfaces under five roots:

RootRouteChildren
Compendium (system.root)/portal/compendiumsystem.tools.workbench_ui (/portal/system/tools/workbench-ui), which hosts every tool
Network (network.root)/portal/networkbrowser, p2p, inbox, profile
Gadgets (gadgets.root)/portal/gadgetsNone
Profile (profile.root)/portal/profileNone
Utilities (utilities.root)/portal/utilitiesapps, marketplace, contracts, published, tools, ports, peripherals, wallet, extensions, grantee_profile, tool_exposure

/portal/system redirects (302) to /portal/compendium with the query preserved.

A request

  1. The page route calls _render_surface, which embeds a bootstrap shell request and the JS module manifest (PORTAL_SHELL_MODULE_CONTRACTS) into portal.html.
  2. v2_portal_shell.js loads the declared modules in order. v2_portal_shell_core.js posts the request to POST /portal/api/v2/shell.
  3. run_portal_shell_entry resolves the instance scope from the store's portal-authority snapshot, resolves the surface (an unknown surface falls back to system.root with allowed=False), and builds the surface's bundle.
  4. build_shell_composition_payload assembles two regions: the activity bar and the workbench. The envelope schema is mycite.v2.portal.runtime.envelope.v1.
  5. The client validates the envelope and dispatches each region to its renderer: v2_portal_shell_region_renderers.js (the activity bar: surface items, pinned tools, the Profile slot) and v2_portal_workbench_renderers.js (everything else: the Compendium, the tool host, document tables, forms).

Selection travels as surface_query. canonical_query_for_surface_query in shell.py keeps only the keys each surface names and always adds msn_filter, the instance the page is on. On the Compendium and the tool host the keys include document, mode, sandbox_filter (inferred from an lv. document id when absent), tools (a comma-separated list of open tool ids), view and doc_view.

The reducer (reduce_portal_shell_state) and its transitions are still in the tree but are not used: REDUCER_OWNED_SURFACE_IDS is empty, so no surface is reducer-owned and the client's dispatchTransition does nothing.

Tool palette

The menubar search lists tools that apply to the current selection. It calls GET /portal/api/tools/eligible for a selected datum and GET /portal/api/visualizers/for-sandbox for a sandbox. recognize_applicable_tools in tool_eligibility.py matches a document's archetype and source kind (widened by its hyphae chain) against each tool's applies_to_archetype and applies_to_source_kind. Whether a tool is offered on a sandbox at all is instance_can_use (46).

Writes

POST /portal/api/v2/mutations/<action> runs the mutation lifecycle (stage, validate, preview, apply, discard) for datum workbench and datum document targets. A workbook apply decodes the edited WORKBOOK-YAML, compiles it to ops, plans the migration and applies it (10). Tools post to their own declared routes, and each write is checked against the write policy (micyte/ports/datum_write_policy/).

micyte/state_machine/nimm/ defines the same lifecycle as a contract (StagingArea, NimmDirectiveEnvelope, MutationContractRuntimeHandler). The live mutation runtime implements the lifecycle directly and does not subclass the handler.

Known gaps

  • shell.py and shell_state.py both define PortalScope, PortalShellChrome, PortalFocusSegment, PortalShellState, PortalShellTransition, PortalShellRequest, PortalSurfaceCatalogEntry and PortalShellResolution.
  • micyte/state_machine/mediation_surface/ is an empty scaffold.
  • The read path renders a SQL projection, not WORKBOOK-YAML (10).