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
| Part | Location | Role |
|---|---|---|
| Shell state machine | micyte/state_machine/portal_shell/ | Shell dataclasses, the surface catalog, the canonical query, tool eligibility. Pure: no I/O |
| Lenses | micyte/state_machine/lens/ | Encode and decode a datum value for display (81) |
| NIMM and AITAS | micyte/state_machine/nimm/, micyte/state_machine/aitas/ | The staged-mutation contract and its context model |
| Runtime | host 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 host | host application, instances/_shared/portal_host/app.py | Routes, the JS module manifest, page rendering |
| JS shell | host 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:
| Root | Route | Children |
|---|---|---|
Compendium (system.root) | /portal/compendium | system.tools.workbench_ui (/portal/system/tools/workbench-ui), which hosts every tool |
Network (network.root) | /portal/network | browser, p2p, inbox, profile |
Gadgets (gadgets.root) | /portal/gadgets | None |
Profile (profile.root) | /portal/profile | None |
Utilities (utilities.root) | /portal/utilities | apps, 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
- The page route calls
_render_surface, which embeds a bootstrap shell request and the JS module manifest (PORTAL_SHELL_MODULE_CONTRACTS) intoportal.html. v2_portal_shell.jsloads the declared modules in order.v2_portal_shell_core.jsposts the request toPOST /portal/api/v2/shell.run_portal_shell_entryresolves the instance scope from the store's portal-authority snapshot, resolves the surface (an unknown surface falls back tosystem.rootwithallowed=False), and builds the surface's bundle.build_shell_composition_payloadassembles two regions: the activity bar and the workbench. The envelope schema ismycite.v2.portal.runtime.envelope.v1.- 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) andv2_portal_workbench_renderers.js(everything else: the Compendium, the tool host, document tables, forms).
Navigation is query state
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.pyandshell_state.pyboth definePortalScope,PortalShellChrome,PortalFocusSegment,PortalShellState,PortalShellTransition,PortalShellRequest,PortalSurfaceCatalogEntryandPortalShellResolution.micyte/state_machine/mediation_surface/is an empty scaffold.- The read path renders a SQL projection, not WORKBOOK-YAML (10).