Skip to content

This is an internal working record, not an everyday instruction. It was written while the system was being rebuilt, for whoever maintains it. If you are here to do today's work, use the everyday documents instead: Procedures · Processes · Runbooks · The working day, step by step

Platform Tenant, Operating Profile, Capability And Configuration — Sequence And State Diagrams

  • Status: SOURCE-RECONCILED DIAGRAM CATALOG / NO RUNTIME CHANGE
  • Source baseline: qa@4f6165bc4c53a7d98b0c246392dd9ed5bd75c21c
  • Source authority: PLATFORM_TENANT_PROFILE_CAPABILITY_CONFIGURATION_SOURCE_AUTHORITY.md
  • Rebuild packet: PLATFORM_TENANT_PROFILE_CAPABILITY_CONFIGURATION_REBUILD_PACKET.md
  • Diagram rule: diagrams explain current and target boundaries; they do not authorize P4-003, module/config writes or Wiki publication.

1. Concern Separation

flowchart LR
    T[Tenant Identity]
    P[Operating Profile]
    M[Module]
    C[Named Capability]
    V[Typed Config]
    S[Credential]
    R[Route Access]
    A[Action / Record Access]

    T --> P
    P --> M
    M --> C
    C --> V
    C --> S
    C --> R
    R --> A

    T -. does not imply .-> M
    P -. does not imply .-> C
    M -. does not imply .-> R
    V -. does not imply .-> A
    S -. does not imply .-> A

Plain-text rule:

Every node is an independent result.
A later node may require an earlier positive result but never rewrites it.

2. Current Legacy WEB Page Context

sequenceDiagram
    actor User
    participant Page as PHP Page Bootstrap
    participant Session
    participant Config
    participant Menu as Menu/Role Helper
    participant Module as Module Guard
    participant Handler as Page Helper
    participant DB as MySQL

    User->>Page: Open page
    Page->>Session: Start/read session
    alt impersonation target exists
        Session-->>Page: TARGET_CLIENT_ID / target user
    else session CLIENT_ID exists
        Session-->>Page: CLIENT_ID / current user
    else legacy fallback
        Page->>Config: Config::CLIENT_ID
        Config-->>Page: deployment tenant
    end
    opt page calls role/menu guard
        Page->>Menu: requirePageRoleAccess / menu decision
        Menu-->>Page: allow or deny
    end
    opt page calls module guard
        Page->>Module: page/module decision
        Module-->>Page: enabled / disabled / unknown-compatible
    end
    Page->>Handler: query/write using scalar context
    Handler->>DB: tenant-scoped SQL when correctly implemented
    DB-->>Handler: rows/result
    Handler-->>Page: result
    Page-->>User: render

Risk:

A page that omits one guard or uses deployment fallback can behave differently from its API.

3. Current API Route With Optional Strict Principal

sequenceDiagram
    actor Client
    participant Router as API v2 Router
    participant Auth
    participant Context as Tenant Context Adapter
    participant Module as Module Guard
    participant Menu as Menu Route Guard
    participant Role as Numeric Role Guard
    participant Handler
    participant DB

    Client->>Router: Request
    Router->>Auth: Assert authenticated
    alt strictTenantPrincipal = true
        Router->>Context: Build strict typed context
        Context-->>Router: typed safe context + scalar bridge
    else legacy route
        Router->>Router: Build scalar apiContext()
    end
    Router->>Module: module decision
    Module-->>Router: allow/deny
    Router->>Menu: requiredMenuRoutes
    Menu-->>Router: allow/deny
    Router->>Role: requiredRoleIds
    Role-->>Router: allow/deny
    Router->>Handler: request context
    Handler->>DB: record/state predicate
    DB-->>Handler: result
    Handler-->>Client: response

Non-implication:

module/menu/role allow does not prove the record belongs to the tenant or the command is state-eligible.

4. Strict Tenant Context Construction

flowchart TD
    IN[Request / Job / Integration Input]
    WEB{WEB/API?}
    IMP{Impersonation?}
    ADM{Super-admin override?}
    JOB{Explicit CLI/Integration binding?}
    MAP{Trusted published mapping?}
    CTX[Strict TenantExecutionContext]
    LEG[Compatibility-only Legacy Context]
    ERR[Reject]

    IN --> WEB
    WEB -->|yes| IMP
    IMP -->|valid| MAP
    IMP -->|no| ADM
    ADM -->|allowlisted + explicit target + auth ref| MAP
    ADM -->|normal user session| MAP
    ADM -->|invalid/ambiguous| ERR
    WEB -->|no| JOB
    JOB -->|explicit single tenant| MAP
    JOB -->|legacy default| LEG
    MAP -->|matching| CTX
    MAP -->|missing| CTX
    MAP -->|mismatch| ERR

A missing mapping yields LEGACY_LOCAL_ONLY; a mismatched mapping rejects.


5. Current Module Decision

flowchart TD
    K[Module Key]
    SA{Unimpersonated Super Admin client 0?}
    ROW{Tenant Module Row}
    ERR{DB/source error?}
    ON[ALLOW: explicit enabled]
    OFF[DENY: explicit disabled]
    MISS[ALLOW: unconfigured compatibility]
    FAILOPEN[ALLOW: source-error compatibility]

    K --> SA
    SA -->|yes| ON
    SA -->|no| ROW
    ROW -->|enabled| ON
    ROW -->|disabled| OFF
    ROW -->|missing| MISS
    ROW -->|read error| ERR
    ERR -->|current compatibility| FAILOPEN

Target strict callers must not inherit MISS or FAILOPEN unless their definition explicitly permits compatibility.


6. Current Page Module And Config Decision

sequenceDiagram
    participant Page
    participant Map as config/modules.php
    participant Registry as T_MODULE_PAGE
    participant Module as T_TENANT_MODULE
    participant Config as T_TENANT_CONFIG

    Page->>Map: Lookup page slug
    Page->>Registry: Lookup page registry
    alt registry error
        Registry-->>Page: deny page_registry_error
    else inactive row
        Registry-->>Page: deny
    else mapped
        Map-->>Page: one / any / all module spec
        Page->>Module: Resolve module(s)
        Module-->>Page: current compatibility result
        opt config prerequisite
            Page->>Config: get bool default false
            Config-->>Page: enabled / disabled / fallback
        end
    else unmapped page
        Map-->>Page: allow / unknown compatibility
    end

7. Numeric MK Document Compatibility

flowchart LR
    REQ[MK Document Request]
    KEY{MK_DOCUMENT_WORKFLOW_ENABLED row?}
    VAL[Use stored bool]
    CID{clientId = 2?}
    YES[Enabled compatibility]
    NO[Disabled compatibility]

    REQ --> KEY
    KEY -->|present| VAL
    KEY -->|missing| CID
    CID -->|yes| YES
    CID -->|no| NO

Target:

flowchart LR
    REQ[Document Request]
    CTX[Strict Tenant Context]
    PROF[Operating Profile]
    CAP[mk.documents.render Capability]
    CFG[Typed Document Config]
    ACCESS[Action/Record Access]
    RESULT[Allow / Deny / Unavailable]

    REQ --> CTX --> PROF --> CAP --> CFG --> ACCESS --> RESULT

8. Target Full Resolution Sequence

sequenceDiagram
    actor Caller
    participant Context as Tenant Context App
    participant Profile as Profile App
    participant Module as Module Resolver
    participant Capability as Capability Resolver
    participant Config as Config Resolver
    participant Credential as Credential Resolver
    participant Access as Access App
    participant Command as Business Query/Command

    Caller->>Context: Resolve strict tenant/actor/request
    Context-->>Caller: TenantExecutionContext
    Caller->>Profile: Resolve profile assignment/version
    Profile-->>Caller: assigned/unavailable + provenance
    Caller->>Module: Resolve owner modules
    Module-->>Caller: enabled/disabled/unavailable
    Caller->>Capability: Resolve named capability
    Capability-->>Caller: enabled/disabled/unavailable
    Caller->>Config: Resolve required typed configs
    Config-->>Caller: value/validity/source
    opt provider effect
        Caller->>Credential: Resolve safe availability/ownership
        Credential-->>Caller: available/unavailable
    end
    Caller->>Access: Evaluate route/action/record
    Access-->>Caller: allow/deny/unknown
    alt all required results permit
        Caller->>Command: Execute
        Command-->>Caller: exact result/readback
    else denied/unavailable
        Caller-->>Caller: Stable safe error
    end

9. Operating Profile Relationship

flowchart TD
    TENANT[Tenant Assignment]
    PROFILE[Operating Profile Definition]
    STREAMS[Value Streams / Process Families]
    TERMS[Terminology / Templates]
    MODS[Required / Optional Modules]
    CAPS[Default Capability Definitions]
    CFGS[Config Definition Set]

    TENANT --> PROFILE
    PROFILE --> STREAMS
    PROFILE --> TERMS
    PROFILE --> MODS
    PROFILE --> CAPS
    PROFILE --> CFGS

    MODS -. explicit tenant module result required .-> TENANT
    CAPS -. explicit capability result required .-> TENANT
    CFGS -. typed value resolution required .-> TENANT

Profile is applicability/default metadata, not a direct grant.


10. Target Config Resolution

flowchart TD
    DEF[Registered Config Definition]
    OBS[Tenant/Published Observation]
    TYPE{Type/shape/range valid?}
    PRESENT[VALUE / VALID / source]
    FALL{Explicit fallback allowed?}
    DEFAULT[VALUE / MISSING|INVALID|ERROR / fallback]
    UNAV[UNAVAILABLE / reason]

    DEF --> OBS
    OBS --> TYPE
    TYPE -->|yes| PRESENT
    TYPE -->|missing/invalid/error| FALL
    FALL -->|yes| DEFAULT
    FALL -->|no| UNAV

The result retains validity and source even when a fallback value is used.


11. Credential Ownership Resolution

sequenceDiagram
    participant Caller
    participant Context as Strict Tenant Context
    participant Definition as Secret Definition
    participant Owner as Credential Owner Ref
    participant Source as Tenant Config / Env / Secret Ref
    participant Result as Safe Resolution

    Caller->>Context: tenant + actor + request
    Caller->>Definition: required secret key/module/sources
    Caller->>Owner: expected owner reference
    Owner->>Context: match local/global tenant?
    alt mismatch
        Context-->>Result: UNAVAILABLE / credential_owner_mismatch
    else match
        Caller->>Source: load secret in trusted server boundary
        alt present and valid
            Source-->>Result: AVAILABLE / source / hasValue=true
        else missing/error
            Source-->>Result: UNAVAILABLE / reason
        end
    end
    Result-->>Caller: safe metadata only

No secret value crosses the diagnostic/browser boundary.


12. Current Admin Direct Applied-State Update

sequenceDiagram
    actor Admin
    participant UI as Admin Console
    participant API as Platform Admin API
    participant DB as Runtime MySQL
    participant Cache as Request/Process Caches
    participant Caller as Runtime Consumer

    Admin->>UI: Toggle module / save config
    UI->>API: PATCH target tenant state
    API->>DB: Update applied row
    DB-->>API: commit
    API-->>UI: success
    UI->>API: GET rows
    API->>DB: reread
    DB-->>UI: applied row
    Note over Cache,Caller: Universal cache/effective-state reread is not guaranteed

13. Target Draft / Publish / Apply / Readback

sequenceDiagram
    actor Editor
    actor Reviewer
    participant CT as Control Tower
    participant Apply as Deployment Apply Agent
    participant DB as Runtime Applied State
    participant Resolver as Effective Resolver
    participant Audit

    Editor->>CT: Create/update draft
    CT-->>Editor: impact preview
    Reviewer->>CT: Approve release
    CT->>CT: Publish immutable release
    CT->>Apply: release + target + expected applied version
    Apply->>DB: validate and apply bounded rows
    DB-->>Apply: commit / per-child result
    Apply->>Resolver: invalidate/version and reread
    Resolver->>DB: read applied state
    DB-->>Resolver: rows/version
    Resolver-->>Apply: effective profile/module/capability/config results
    Apply->>Audit: persist release/apply/readback result
    Apply-->>CT: APPLIED / PARTIAL / DRIFTED / FAILED

Runtime requests continue to read local applied state, not Control Tower.


14. Partial Apply Recovery

flowchart TD
    START[Apply Release]
    ID[Identity/Profile]
    MOD[Modules]
    CAP[Capabilities]
    CFG[Configs]
    SEC[Credential References]
    READ[Applied Rows + Effective Reread]
    OK[APPLIED]
    PART[PARTIAL]
    ROLL[Rollback / Supersede]

    START --> ID --> MOD --> CAP --> CFG --> SEC --> READ
    READ -->|all expected| OK
    ID -->|failure after prior child| PART
    MOD -->|failure| PART
    CAP -->|failure| PART
    CFG -->|failure| PART
    SEC -->|failure| PART
    PART --> ROLL

If the underlying storage cannot share one transaction, each child disposition remains explicit.


15. Page / API / Action / Record Gates

flowchart LR
    AUTH[Authenticated Actor]
    CTX[Strict Tenant]
    PAGE[Page/API Availability]
    MOD[Module]
    CAP[Named Capability]
    ROLE[Role/Action]
    RECORD[Record Tenant/State]
    CONFIG[Config/Credential]
    ALLOW[ALLOW]

    AUTH --> CTX --> PAGE --> MOD --> CAP --> ROLE --> RECORD --> CONFIG --> ALLOW

A failed or unknown gate returns its own reason. It must not be converted into a generic module failure.


16. CTC Versus MK Profile Resolution

flowchart TD
    T1[Tenant A]
    T2[Tenant B]
    P1[ctc-execution vN]
    P2[mk-order vN]
    COMMON[Shared Platform Modules]
    CTC[CTC Process Capabilities]
    MK[MK Process Capabilities]
    CFG1[CTC Typed Config]
    CFG2[MK Typed Config]

    T1 --> P1
    T2 --> P2
    P1 --> COMMON
    P2 --> COMMON
    P1 --> CTC
    P2 --> MK
    P1 --> CFG1
    P2 --> CFG2

The same codebase and modules may be shared while process applicability and configuration differ.


17. Shared Versus Dedicated Deployment

flowchart TD
    REL[Published Tenant Release]
    SAAS[Shared SaaS Deployment]
    DED[Dedicated Deployment]
    MAP1[Local Tenant Mapping]
    MAP2[Local Tenant Mapping]
    DB1[Shared Runtime MySQL]
    DB2[Dedicated Runtime MySQL]
    RES1[Effective Reread]
    RES2[Effective Reread]

    REL --> SAAS --> MAP1 --> DB1 --> RES1
    REL --> DED --> MAP2 --> DB2 --> RES2

Each target returns an independent apply/readback result. Dedicated does not imply request-time Control Tower access.


18. Current-To-Target Migration

sequenceDiagram
    participant Old as Current Scalar Helpers
    participant Shadow as Typed Read Shadow
    participant Target as Target Resolver
    participant Caller as Selected Caller
    participant DB as Current MySQL

    Old->>DB: current module/config read
    DB-->>Old: scalar result
    Shadow->>DB: observations + definitions
    DB-->>Shadow: rows/metadata
    Shadow->>Target: resolve typed result
    Target-->>Shadow: decision/source/validity/reason
    Shadow-->>Caller: parity diagnostic only
    Note over Old,Caller: Old remains authority during shadow
    Caller->>Target: cut over selected cohort after acceptance
    Target->>DB: typed read
    DB-->>Target: result
    Target-->>Caller: authoritative typed decision

Do not let old and target resolvers independently authorize the same write.


19. Rollback Sequence

sequenceDiagram
    actor Operator
    participant Control as Release Owner
    participant Apply
    participant DB
    participant Resolver
    participant Caller

    Operator->>Control: Select predecessor/superseding release
    Control->>Apply: Apply rollback package with expected version
    Apply->>DB: restore reviewed applied state
    DB-->>Apply: commit
    Apply->>Resolver: invalidate/version and reread
    Resolver-->>Apply: effective state
    Apply->>Caller: selected parity/health checks
    Caller-->>Apply: observed result
    Apply-->>Control: ROLLED_BACK / PARTIAL / DRIFTED

20. Diagram Maintenance Triggers

Update the applicable diagram when any of these change:

  • tenant context field/provenance/constructor;
  • impersonation/admin override behavior;
  • operating profile composition/assignment;
  • module missing/error policy;
  • page module/config mapping;
  • capability prerequisites/defaults;
  • config type/source/default/cache policy;
  • credential ownership/source;
  • Admin current write path;
  • Control Tower publish/apply contract;
  • Shared/Dedicated target behavior;
  • access composition;
  • migration authority or rollback.

---

Source: docs/processes/PLATFORM_TENANT_PROFILE_CAPABILITY_CONFIGURATION_SEQUENCE_DIAGRAMS.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.