Furth FortuneM9 reference

Platform product / System overview

MerTek.io

Identity and capability routing for applications

MerTek.io signs in a user, resolves allowed applications, and routes the user to them. Each application remains responsible for its own data and action permissions.

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

One identity, N per-app lenses, and a link that is all MerTek.io keeps

global identity · the link and the consent · the app's own store

ONE GLOBAL IDENTITY WHAT MERTEK.IO KEEPS WHAT THE APPLICATION KEEPS mer_identity one row for one person anonOrigin marks an anon row holds no app profile data identity_alias key appUid:type:value declared-unique, app-relative credential local_secret_hash only salted HMAC, never the raw text consent_grant key identityId:appUid:scope the user revokes in one place no embedder input reaches it profile_link key appUid:identityId link metadata only, no data app_registration the relying party and its policy authMode, anonPolicy, lifetime Application A, a relying party the profile DATA sits in its own MerDB keyed by the same appUid:identityId Application B its own users, schema, handlers, scenes Application C a fresh profile and a fresh consent MerTek.io never reads or holds these rows. The link is the whole of what it keeps. THE PER-APP LENS · SYSTEM-RESOLVED, NEVER EMBEDDER-SUPPLIED FIRST PARTY the user authed to THIS app consent on the reserved scope app the profile materializes NEVER CONSENTED, OR REVOKED mertekioMaterializeProfile refuses deny_no_consent, in denial_event the scene sees an anon observer GLOBALLY ANON device-persistent or ephemeral declared per app; none refuses first auth claims it in place Identity is target-app-relative: a resolution, a consent and a token are always scoped to (identity, target app).
Plate 02

A capability is (mechanism, tenant, tier, policy)

four selectors · bundle resolution · the ten ranks · the recursion

A CAPABILITY IS (MECHANISM, TENANT, TIER, POLICY) MECHANISM core C or a platform lib tenant-agnostic tier-parameterized TENANT the appUid one Application per row appUid 0 is the baseline TIER a role bundle plus a rank per Application, not global a scope set is its content POLICY declared data, no default the app declares it an undeclared case refuses RESOLUTION · THE TENANT OVERRIDES, THE BASELINE ANSWERS mertekioResolveBundle reads the key appUid:name first, then falls back to 0:name, the platform baseline. mertekioHasScope walks the ENABLED role grants in THIS app only. TEN BASELINE BUNDLES, RANKED RANK BUNDLE WHAT THE SCOPE SET ADDS 100sys.devopsall scopes 90sys.adminall scopes 80app.ownerapp.owner, app.config, billing 70app.adminapp.config 60app.moderatorcontent.moderate 50app.contentcontent.publish 40developerapp.register.self, app.provision.mint 30user.verifiedwrite.content 20userread.public, profile.self 10anonread.public THE RECURSION · ONE FRONT DOOR AT EVERY LAYER mertek.io, the platform tenant a person granted the developer bundle self-registers a root app the root app, a platform on a platform its owner is app.owner in the new app; its creators are its users the child app, parentAppUid = the root the parent mints its grant; the child talks only to the parent Each layer re-offers the same mechanism to the layer below it.
Plate 03

Signup to a live Application, and the one crossing to MerTekStak

the sequence · the derived boot · the one typed crossing

DEVELOPER MERTEK.IO · THE ONLY SURFACE THE DEVELOPER SEES ACROSS THE PRODUCT BOUNDARY 1 · sign up an email and a password mertekioConsoleSignUp mints mer_identity, identity_alias, credential (hash only) 2 · server side, on the first sign-up mertekioGrantDeveloper grants the developer bundle in the control app 3 · sign in the same credential mertekioIssueDeveloperToken no developer scope, no token: deny_not_developer 4 · name a root app a name, nothing else mertekioRegisterRootApp the developer TOKEN authorizes it, never the admin secret 5 · name a child app a name, nothing else mertekioMintProvisionGrant scope mertek.provision:childAppUid, bound to the identity 6 · derived, never asked the developer sets no path mertekIoScaffoldBoot moduleCommit then moduleActivate on the derived key boot_<slug> 7 · the one crossing the developer never sees it mertekioInfraProvisionChild one typed request on contract.mertekstak.application-infra WHAT DOES NOT CROSS MerTek.io names no mertek* handler verb of MerTekStak. It reads no MerTekStak entity. It knows no row identifier, no column, and no relation. It names the Application by its declared NAME only. The transport handle is a PARAMETER, so one code path serves the remote adapter and the co-located adapter. An absent handle refuses. MerTekStak re-validates the grant locally writes application.parentAppUid meters the child usage resolves its own row identity TWO AUTHORITIES, NEVER ONE THE DEVELOPER TOKEN validated locally against the app keyset authorizes registerRootApp and the grant mint the developer holds it THE SERVICE CREDENTIAL sealed under the binding furth.platform.node-kek resolved server-side, never sent to a client authorizes the lineage parent and the domain bind
Plate 04

Live edit: the Application source is a store row, with generations and rollback

the write capability · the delivery capability · the generation compare-and-set

THE AUTHORING SIDE THE DELIVERY SIDE CAP_MODULE_WRITE · SEVEN VERBS moduleCommitappend one commit, serve nothing yet moduleActivateset the commit id that is served moduleSourcethe publisher reads back what it wrote moduleSetAudience0 server, 1 client, 2 both moduleSetPackagepackage, generation, visibility, role moduleRetirea durable tombstone; the id stops resolving moduleRestoreclear it; the exact prior pointers return A rollback is an activate of an earlier commit id. A retire keeps the history, so an audit still reads it. CAP_APP_DELIVERY · THREE VERBS, FOUR REFUSALS moduleActive · moduleEntry · modulesShip This is the client door. A publisher cannot confirm its own write through it, and a delivery runtime never holds the write capability. The two edges never merge. no_generation · no admitted generation is installed not_in_closure · the module belongs to another app visibility_private · product-private never crosses server_private · a server module ships no source THE GENERATION IS A COMPARE-AND-SET · mertek.dev.liveEdit CARRIES THE INTENT validate resolve the whole generation verify it, publish nothing activate claim = the expected base plus one a rival on the same base is superseded rollback replay the previous generation the same base must still be active THE STALE BASE REFUSES The console sends the generation it read as active. A rollback off a base no longer active denies deny_stale_base. An undeclared intent denies before any transport call. NO REDEPLOY, NO NODE REPLACEMENT This is the daily path for every Application, including MerTek.io itself. Only compiled-core C needs a new image, and MerTekStak rolls that out without downtime.
Plate 05

The fail-closed cascade: every refusal has a name

ten token checks · four policy vocabularies · seven guard refusals · the scoped grant

mertekioValidateToken · TEN ORDERED CHECKS, TEN NAMED REFUSALS the presented bearer claimHex.mac over a MerBuf claim two dot-separated parts? malformed the kid resolves to a key? unknown_kid the HMAC-SHA256 matches? bad_mac the claim app is the expected app? wrong_app the expiry is still ahead? expired the token family exists? no_family the family is still active? revoked_family within one keyset rotation? stale_keyset the required scope is held? wrong_scope a binding is present? missing_binding valid = 1 sub, app, scopes, prov, fam, obo DECLARED POLICY, NO DEFAULT mertekioRegisterRootApp reads four closed vocabularies: authModerequired | optional | anon anonPolicynone | ephemeral | device profilePolicyeager | lazy | none refreshPolicyrotate | fixed | none tokenLifetime must be greater than zero. ANY OTHER VALUE DENIES deny_bad_policy, written to the denial_event stream mertekioAdminGuardAt · SEVEN REFUSALS deny_no_configno platform_admin row exists deny_bad_argsan empty principal or secret deny_no_principalthe principal is not registered deny_revokedthe row carries a revokedAt deny_expiredthe request clock passed expiresAt deny_bad_secretthe hash compare fails, in constant time deny_no_scopethe row does not carry that scope THE SCOPED GRANT, AND WHO CHECKS IT MerTek.io mints one grant per child, scoped to that child. MerTekStak re-validates the same token locally, against the key material it already synced. It trusts no assertion.
Plate 06

The naming ledger, drawn as the refusal it is

the tracked-tree scan · the one allow-source · the planted proof

LEG 1 · EVERY SURVIVING SPELLING IS A LEDGERED TERM one git grep, one case-folded regex the whole tracked tree in one process, on the retired code-name stem the ledger lookup an exact path, or a dir prefix recorded, admitted unrecorded, REFUSED WHAT THE 21 LEDGER ROWS RECORD, IN SIX KINDS, AND WHY EACH ONE STAYS unrelated homonym · a model-ingestion showcase reel, and a payload workshop in an atlas detector, not an identifier · the pattern a gate or a package audit must hold to refuse refusal vocabulary · the retired roots a shape gate names so a resurrected root refuses rule statement · AGENTS.md and the product-doc home name the spelling nothing may carry directory prefix · the one plan-tree row, where the migration's own record quotes it the subject itself · the migration and its proof must spell what they rewrite FROM LEG 2 · THE RETIRED PRODUCT DOMAIN No active doc and no product source names it. The plan tree may record it as history, through the same ledger. LEG 3 · THE REFUSAL IS PROVEN, NOT ASSUMED The gate plants a known-bad file AND a known-good file in a scratch tree, and drives the leg 1 scan on a file it must report. WHY A SCAN NEEDS A PLANTED HIT A scan that matches nothing looks exactly like a clean tree, so leg 1 silence on its own proves nothing. Leg 3 also proves the ledger admits its own recorded exact path and its own recorded directory prefix, and that a path the ledger does not record is still refused. No inline suppression, and no default pass.

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.

One user identity

A person can enter the platform once and receive the approved view for each application. The front door does not take ownership of application data.

Specific example

An operator can move from readiness to planning tools without creating a separate identity in each system.

Scoped capabilities

Access describes the action, organization, service level, and policy together. A broad role name alone is not enough.

Specific example

A contractor can review training records for one unit without receiving access to live operational records.

Named refusal

When access is denied, the system records where and why the decision occurred. This helps support teams and auditors understand the result.

Specific example

A user can learn that an application policy blocked an action rather than receiving a vague sign-in error.

Uses

Example uses

Pilot questions

What the team must decide

Which identity providers must connect

How application owners retain permission authority

What denial information may be shown to each audience

Request a technical briefing