Furth FortuneM9 reference

Assurance fabric / System overview

Operational Debug Views

One debug model for scenes and services

Systems publish typed state, events, timing, and boundaries. Rendered applications show overlays; background services show the same facts in service views.

Inside the system

Architecture plates

Each plate preserves the internal layout, paths, boundaries, and highlighted decisions. Use the short label first, then follow the lines through the system.

Plate 01

The system exposes data; C and Glint draw it

inert verb · pure builder · one shared product

1 · THE PRODUCER · INERT C AND HOST VERBS 2 · THE BUILDER · PURE TRIDENT 3 · THE PRODUCT · ONE PER SPACE t.runtime.debug() host supervisor · th_runtime_debug_dict t.spatial.overlay(handle, bounds) occupied octree cells for the region t.phys.world.overlay(world) contact manifolds in solver order t.phys.world.diagnostics(world) keel · phys_world_diagnostics t.db.entity.debugView(section) merdb · engine, tables, postings t.gfx.glintInspect(query) read-only · thalassa_glint_debug.h Each verb copies state into a caller buffer and returns. None of them draws. None of them holds a debug policy or a scenario value. The core keeps hooks. pure gizmo libs spatial_gizmo.tri cells to wire boxes and a line physics_gizmo.tri manifolds to markers and a line merdb_gizmo.tri scalars to formatted table rows pipeline_gizmo.tri passes to inspector rows client_substrate_gizmo.tri declared rows to a summary A builder takes a snapshot and returns surfaces and nodes. It calls no host verb. debug_stage.tri the one t.ui.overlay caller in the client libs output root: uiOverlay debug_geom.tri t.gfx.scene(nodes, layer overlay) output root: geometryOverlay ThRenderer · Glint backends draws both products after the primary scene an empty product clears the last one WHAT THE SEAM PREVENTS A subsystem that draws its own view puts render policy in the pure core. That view then works on one backend only, and it composes with nothing.
Plate 02

Two additive products, one visibility predicate

the last-writer defect · two compositors · the proofs that exist

1 · THE DEFECT · ui.overlay SETS THE ROOT, IT DOES NOT ACCUMULATE stage Acalls t.ui.overlay stage Bcalls t.ui.overlay stage Ccalls t.ui.overlay output root uiOverlay only the last caller survives; A and B leave nothing behind THE FAILURE THIS PREVENTS One overlay cannot be open beside another. A world-space publish is worse: it clears the Application scene along with the other gizmos. 2 · TWO ADDITIVE PRODUCTS, ONE VISIBILITY PREDICATE debug_stage_publish() walk debug_stage_names in registration order keep each VISIBLE stage's surfaces t.math.listConcatMany(parts) one t.ui.overlay({ surfaces }) → uiOverlay, beside ui.root debug_geom_publish_host() resolve the host-entered view walk contributors in declared order keep each VISIBLE, MATCHING batch t.gfx.scene(nodes, layer overlay) → geometryOverlay, beside the Application render root ONE SHARED PREDICATE debug_stage_visible(name) enabled AND capability granted Both compositors ask it before they include anything, so a stage's panel and its gizmos appear together and hide together. Registration sets enabled to 0. 3 · THE PROOFS THAT EXIST, AND THE ONE THAT DOES NOT debug-geom · order, refusals, retained change tracking debug-geom-multiview · 5 declared view contexts debug-geom-embed-runtime · two isolated child runtimes debug-geom-portal-runtime · two real aperture screens debug-monitor-gizmos · rendered pixels change NOT PERFORMED BY THE FULL PROFILE Every rendered proof beside this box is a software render. 3 of the 19 automatic leaves declare renderPolicy soft-oracle, 16 declare none, and not one declares a GPU policy. thalassa.tests.debug-monitor · lane device The WebGPU host proof carries no gates.d leaf, so an operator runs it by hand on a Windows box.
Plate 03

Anatomy of a stage: one file, no edit to a shared lib

the declarations in one stage file · the seam · the tier gate · the keys

native/thalassa/lib/client/debug/spatial_overlay_stage.tri the shipped worked example 1 · CLAIM A TOGGLE KEY debug_stage_bind_toggle("spatial", "f3", "spatial.overlay.toggle") the claim is granted first, then the bind happens 2 · REGISTER THE STAGE debug_stage_register("spatial", "Spatial") enabled 0, surfaces empty, summary denied 3 · DECLARE TYPED SETTINGS debug_stage_setting_declare_bool("spatial", "boxes", 1) debug_stage_setting_declare_enum("spatial", "tier", [all, static, dynamic], 0) debug_stage_setting_declare_range("spatial", "maxCells", 256, 64, 4096, 256) 4 · READ THE LIVE SNAPSHOT t.spatial.overlay(spatial_stage_handle, { min, max }) 5 · BUILD WITH A PURE LIB spatial_gizmo_summary(ov) · spatial_gizmo_boxes(cells, mvp, tier, maxn, …) 6 · PUSH INTO BOTH PRODUCTS debug_stage_push("spatial", [ panel ]) debug_geom_overlay_begin/submit/end("spatial", 300, "world") the census row spells that same order and camera THE REGISTRATION SEAM A new system adds its OWN file and calls the generic register verb. It never edits debug_stage.tri, and it never adds a tab to ui_debug_views.tri or debug_overlay.tri. A missing seam is built once, as a platform primitive. THE TIER GATE · FAIL CLOSED An ungated stage is the app-HUD baseline and is always shown. A gated stage names a capability id, and t.capability.resolve must answer "available". Anything else hides it, toggle row included. KEYS ARE SCARCE, SO THEY ARE CLAIMED 59 claims across 24 keys, f1 through f24. Two stages in one scene cannot both bind one key. The seam grants the first claim, refuses the second, and logs a warning. The refused stage stays fully operable. WHAT EVERY ENTERED SCENE CONTEXT LOADS BY ITSELF F1 and Control+Esc bound by debug_overlay.tri, which scene_context_boot.tri always loads F11 bound by profiler_overlay.tri, which the context boot does NOT load 7 registered, every one off runtime, routeEvents, merdb, windows, pipelineInspector, renderMatrix, clientSubstrate
Plate 04

Declared settings, and the state a stage reports

the settings schema · generic render · the state cascade

1 · A SETTING IS DECLARED DATA, WITH A DEFAULT debug_stage_setting_declare_* KIND WHAT IT CARRIES RENDERED AS bool on or off on / off range value, lo, hi, step rounded number enum options list, index option text The id is stage + "/" + key, so two stages never collide on a setting name. An undeclared setting reads 0, and a set on it does nothing. THE OVERLAY RENDERS THEM, NOT THE STAGE debug_stage_settings_rows(stage, x, y0, w, h) builds one clickable row per declared key, in declare order. debug_stage_settings_hit(…) uses the SAME layout formula, so the drawn row and the hit box cannot drift apart. A click cycles the value: a bool flips, a range steps and wraps at its top, an enum advances and wraps. thalassa.tests.debug-settings clicks each kind and reads the new text back. No rebuild, no redeploy. 2 · WHAT THE STAGE REPORTS · debug_stage_state, FIRST MATCH WINS unsupported not registered, or its scope is not active denied names a capability the tier does not grant off registered and granted, but not enabled empty enabled, but no live sample has arrived degraded the stage reports degraded or partial stale its snapshot is older than the cadence allows throttled the stage dropped samples ok enabled, granted, fresh, and complete THE SUMMARY EVERY STAGE CARRIES debug_stage_register installs the contract, so even an unfed stage answers: health "denied", lastUpdatedFrame -1, sampleCadence 1, ladder metadataOnly. The panel then draws an explicit refusal instead of a blank row. A non-empty push stamps health "ok" and a fresh frame. The 4 health values are ok, degraded, partial, denied. debug_catalog_validate · 11 FINDING KINDS duplicateId · missingOwner · invalidVersion · invalidScope incompatibleSchema · unavailableCapability · staleProducer danglingDependency · orphanSetting · orphanMeta cyclicDependency · one finding makes the report refuse
Plate 05

A service has no scene, so its debug view is typed data

declared stream · generic reader · authority · the streams that exist

1 · DECLARE · READ · AUTHORIZE serviceDebugDeclareStream entity · the backing MerDB entity index · the declared enumeration index search, keyField · optional prefix summaryFields · compact, projected artifactFields · heavy, by key only healthField, updatedField · optional An empty id, entity, index, or summary list refuses. No field is both. trt_service_debug.tri the one generic reader THREE ENDPOINTS service.debug.listStreams service.debug.summary service.debug.artifact a summary read uses the DECLARED index or prefix, never a scan a heavy artifact is fetched by key THE AUTHORITY SEAM mertekioDebugDispatch wraps the generic reader in MerTek.io's own admin guard. A caller presents a principal and a secret, and needs the scope debug.read. Any deny verdict returns call.error and reads nothing. Only "ok" reaches the reader. 2 · THE 11 DECLARED STREAMS, BY OWNER Fathom fathom.telemetry fathom.renderJob fathom.substrate fathom.substrate.exclusion MerTek.io mertekio.audit mertekio.denial mertekio.authAttempt admin-gated, see above MerTekStak mertekstak.telemetry declared by the shared servicedebug Application Product package product.package.closure product.package.module product.package.refusal THE READER IS AN APPLICATION, NOT A NEW INSPECTOR native/apps/servicedebug is config plus .tri. It builds a catalog panel over every declared stream and a detail table over the compact summary rows, and it fetches a heavy payload only when an operator asks for that key.

Key parts

What the system does

These are the main boundaries, inputs, outputs, and failure rules. The examples show a specific use of each part.

Shared operating facts

Systems report declared state, events, and settings. Views present that data without changing the mission behavior.

Specific example

A maintainer can inspect sensor state and timing while the application continues under the same approved logic.

Visual overlays

Rendered applications can show selected stages, boundaries, and measurements through a common overlay model.

Specific example

A rehearsal team can display route inputs, object bounds, and decision timing while reviewing a scenario.

Service views

Background services expose typed data even when they do not have a visual scene. Operators still receive a consistent support surface.

Specific example

A data service can show queue health and last accepted change beside the application that depends on it.

Uses

Example uses

Pilot questions

What the team must decide

Which operating facts each role may see

What diagnostic views must work offline

How support data is retained without exposing sensitive content

Request a technical briefing