OpportunitiesEntities
Docs
    Ring Platform

    Decentralized Self-building Future

    Sign In
    Entities
    Opportunities
    Store
    Docs
    Platform Concepts
    RING EconomySonoratek LLCGlobal ImpactAI Meets Web3
    Get Started
    Quick StartCalculatorRoadmap
    Privacy|Contact
    v1.104.23|Sonoratek LLC

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    Inventory & Stock
    Vendor Management
    Commissions & Settlements
    SubscriptionConductor
    PaymentConductor
    Ring Oracle
    Payments Overview
    Public Pools & DAO Jars
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Credit Rewards
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    Peer Games
    News Module
    Member Blogs
    Public Profile Pages
    Profile Account Widgets
    Ring File Cabinet
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Vertical Presets (SSOT)
    Ringization playbook
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Project configuration
    Public environment variables
    Order Lab secrets
    WalletConnect Project ID (Reown Cloud)
    Supported services
    NODUS wiki (project knowledge)
    Configuration playbook
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel Deployment
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Backend Services
    Firebase Integration
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    Inventory & Stock
    Vendor Management
    Commissions & Settlements
    SubscriptionConductor
    PaymentConductor
    Ring Oracle
    Payments Overview
    Public Pools & DAO Jars
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Credit Rewards
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    Peer Games
    News Module
    Member Blogs
    Public Profile Pages
    Profile Account Widgets
    Ring File Cabinet
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Vertical Presets (SSOT)
    Ringization playbook
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Project configuration
    Public environment variables
    Order Lab secrets
    WalletConnect Project ID (Reown Cloud)
    Supported services
    NODUS wiki (project knowledge)
    Configuration playbook
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel Deployment
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Backend Services
    Firebase Integration
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    Inventory & Stock
    Vendor Management
    Commissions & Settlements
    SubscriptionConductor
    PaymentConductor
    Ring Oracle
    Payments Overview
    Public Pools & DAO Jars
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Credit Rewards
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    Peer Games
    News Module
    Member Blogs
    Public Profile Pages
    Profile Account Widgets
    Ring File Cabinet
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Vertical Presets (SSOT)
    Ringization playbook
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Project configuration
    Public environment variables
    Order Lab secrets
    WalletConnect Project ID (Reown Cloud)
    Supported services
    NODUS wiki (project knowledge)
    Configuration playbook
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel Deployment
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Backend Services
    Firebase Integration
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)
    Ring Logo

    Loading documentation...

    Preparing Ring content

    Ring Logo

    Loading documentation...

    Preparing Ring content

    Ring Logo

    Loading documentation...

    Preparing Ring content

    Vertical Presets (SSOT)

    Use Founder / Developer tabs in the docs sidebar to filter this page. Shared sections apply to both audiences.

    Ring white-labels share one Layer1 codebase: ring/web (hostname ring-platform.org is the docs portal, not a checkout directory). Verticals are selected by preset name in ring-config.json. Typed catalogs live under features/*/presets/<preset>.ts (and home under components/pages/home-presets/<preset>.tsx). Optional L2 packs sit at ring-presets/<pack>/ and compose between Layer1 and the clone overlay.

    Two sources of preset modules

    SourceWhat lives thereWhen it wins
    Platform (ring-platform.org)Shared niches (platform, agricultural, …)Base of every build
    Clone project dir (e.g. ring-greenfood-live)Branding, ring-config.json, custom <preset>.ts + registry overlaysOverwrite on collision after platform copy

    Build merge (clone truth prevails)

    Use ringdom-clone-build (ringdom-mcp):

    1. Copy latest ring-platform.org → build tmp (skips node_modules / .next / .git)
    2. Copy all files from the clone project dir onto that tmp — overwrite collisions
    3. Docker / CI build from the tmp dir

    Do not expect a thin overlay alone to be a runnable app — merge first.

    Two tiers of content

    TierWhatWhere
    1 — dataCategory lists, badge tokens, labelsring-config.json maps + locales/
    2 — typed logicEntity catalogs, zod/forms, niche field UIsfeatures/*/presets/<preset>.ts (platform and/or clone overlay)

    Config keys

    GreenFood sets entities / productFields / productBadges to "agricultural" and home.preset to "mvm-landing".

    Accessors (named preset SSOT)

    All use the configured *.preset string. If a singular key is unset, entities and productBadges fall back to productFields.preset, then "platform" — no hard-coded niche if/else.

    • getEntitiesPreset() → features/entities/presets registry
    • getHomePreset() → components/pages/home-presets registry
    • getPresetPack() → presets.pack folder name under ring-presets/<pack>/ (null when unset)
    • getOverlayFeature() → overlay.featureId (null on bare Layer1)
    • getProductFieldsPreset() / getProductFieldsPresets()
    • getProductBadgesPreset() / getProductBadgesPresets()

    Entities registry

    Rule: preset names appear in ring-config + the registry map. Consumers call getEntityTypes() / getEntityTypeList() — never import agricultural.ts directly.

    Custom niche on a clone: add features/entities/presets/<name>.ts in the clone project, overlay index.ts to register it, set entities.preset to that name, then ringdom-clone-build.

    Bundle discipline: sync catalogs are lightweight UI lists. Heavy ERP field catalogs live in *-erp.ts modules loaded only via async loadErpEntityTypes().

    Copy / icons layering (no hardcoded UI strings)

    • Catalog (presets/<name>.ts): ids, emoji, English fallback names/descriptions
    • Copy: locales/*/modules/entities.json → types.<id> + types.<id>Desc
    • Visual skin: components/entities/entity-type-icons.tsx TYPE_VISUALS map
    • Render: useEntityTypeLabel() / useEntityTypeDescription() — i18n first, catalog fallback

    Home landing registry

    Add a shared vertical (platform)

    1. Add features/entities/presets/<name>.ts (+ optional <name>-erp.ts)
    2. One line in ENTITIES_PRESET_REGISTRY (+ ERP_CATALOG_REGISTRY if needed)
    3. Optional landing → components/pages/home-presets/<name>.tsx
    4. Optional Tier-1 maps under productFieldsPresets / productBadgesPresets
    5. i18n keys in locales/*/modules/entities.json
    6. Document the preset id in ring-config.template.json

    Target roster: platform, agricultural, then tourism, sport, business, pet, auto, connect, technopark, manufacturing.

    Thin exclude (propagation)

    .reggie-propagate-exclude.json protects overlay-only paths from being overwritten by Reggie:

    • ring-config.json
    • public/logo*.svg, favicon.ico, public/branding/
    • locales/{en,uk,ru}/config.json, vendor.json
    • Custom features/*/presets/<clone-only>.ts (+ registry overlay) when not upstreamed yet
    • Tier-3 plug: lib/overlay/registry.ts only (maps). Do not exclude lib/overlay/types.ts or lib/overlay/runtime.ts — those are platform SSOT.

    Tier-3 overlay socket (platform) + plug (clone)

    PathOwnerRole
    lib/overlay/types.tsLayer1Contracts (OverlayMessages, registries)
    lib/overlay/runtime.tsLayer1loadPackMessages / loadOverlayMessages / resolveOverlayHomeRail
    lib/overlay/registry.tsLayer1 empty maps; clone overlays mapsDomain feature loaders
    locales/{locale}/pack.jsonLayer1 ships {}; pack overwrites at composePack i18n namespaces

    Consumers import from @/lib/overlay/runtime. Clones never duplicate loaders in registry.ts. Do not add pack to LocaleFileId / assembleMessages — pack merge happens in buildMessages outside 'use cache', same as the overlay.

    Pack locale socket (Layer1)

    StageLoaderCached?
    Layer1 locales/{locale}/**/*.jsonassembleMessagesYes
    Pack locales/{locale}/pack.jsonloadPackMessagesNo — skipped when getPresetPack() is null
    Clone appendOverlayMessagesloadOverlayMessagesNo — skipped when getOverlayFeature() is null

    Later leaf keys win (mergeJsonRecords in lib/i18n.ts). Nested objects merge, so a clone overlay can override one string without replacing the pack namespace.

    Layer1 keeps an empty pack.json for every fallback locale (en, uk, ru, es, de) so webpack always resolves @/locales/${loc}/pack.json on bare Layer1 and on the empire overlay.

    In block comments, write locales/{locale}/pack.json. A glob locales/*/pack.json inside /* … */ terminates the comment at */.

    Pack copy is how a vertical (news, marketplace, …) ships extra labels without editing Layer1 lib/i18n.ts. Your clone still wins brand leaves through the overlay plug. Icon ids for pack nav slots are a separate Layer1 map — see Whitelabel navigation.

    loadPackMessages (in lib/overlay/runtime.ts) returns {} when presets.pack is unset. Otherwise it dynamic-imports @/locales/${loc}/pack.json (loc is uk, ru, es, or de when the request locale matches those; any other code uses en) and accepts a JSON object only (arrays are rejected).

    Nav chrome: packs may overwrite lib/navigation/primary-nav.ts. They must not overwrite lib/navigation/platform-menu.ts or lib/navigation/primary-nav-icons.ts. New Lucide ids land on Layer1 first.

    Operator checklist (calculator / Order Lab): Ringization playbook. Shared code ships from Layer1 ring/web. Clone-local custom presets stay in the clone dir and win at compose (ringdom-clone-build / merge-dev).

    GreenFood cutover

    Deprecated

    • Hard-coded if (productPreset === 'agricultural') in accessors
    • Per-clone custom-types.ts / overrides.ts without a named preset module
    • switch (vertical) in feature code — use the registry
    • Building Docker images from a thin overlay without platform merge
    • Adding pack to LocaleFileId / putting pack.json inside 'use cache'
    • Overlaying lib/navigation/primary-nav-icons.ts with clone-named Lucide imports

    Related documentation

    Related documentation

    Localization

    Deep-dive: message merge order, pack.json shape, and locale env.

    Whitelabel Navigation

    Next-step: closed icon map and overlay remap-only nav socket.

    Ringization playbook

    Same-workflow: Tier-1/2/3 ringize and overlay registry plug.

    Customization Guide

    Prerequisite: config-first branding before named presets.

    1. Docs
    2. /Customization
    3. /Vertical Presets (SSOT)

    Updated Sep 9, 20265 min listen

    Vertical Presets (SSOT)

    Use Founder / Developer tabs in the docs sidebar to filter this page. Shared sections apply to both audiences.

    Ring white-labels share one Layer1 codebase: ring/web (hostname ring-platform.org is the docs portal, not a checkout directory). Verticals are selected by preset name in ring-config.json. Typed catalogs live under features/*/presets/<preset>.ts (and home under components/pages/home-presets/<preset>.tsx). Optional L2 packs sit at ring-presets/<pack>/ and compose between Layer1 and the clone overlay.

    Two sources of preset modules

    SourceWhat lives thereWhen it wins
    Platform (ring-platform.org)Shared niches (platform, agricultural, …)Base of every build
    Clone project dir (e.g. ring-greenfood-live)Branding, ring-config.json, custom <preset>.ts + registry overlaysOverwrite on collision after platform copy

    Build merge (clone truth prevails)

    Use ringdom-clone-build (ringdom-mcp):

    1. Copy latest ring-platform.org → build tmp (skips node_modules / .next / .git)
    2. Copy all files from the clone project dir onto that tmp — overwrite collisions
    3. Docker / CI build from the tmp dir

    Do not expect a thin overlay alone to be a runnable app — merge first.

    Two tiers of content

    TierWhatWhere
    1 — dataCategory lists, badge tokens, labelsring-config.json maps + locales/
    2 — typed logicEntity catalogs, zod/forms, niche field UIsfeatures/*/presets/<preset>.ts (platform and/or clone overlay)

    Config keys

    GreenFood sets entities / productFields / productBadges to "agricultural" and home.preset to "mvm-landing".

    Accessors (named preset SSOT)

    All use the configured *.preset string. If a singular key is unset, entities and productBadges fall back to productFields.preset, then "platform" — no hard-coded niche if/else.

    • getEntitiesPreset() → features/entities/presets registry
    • getHomePreset() → components/pages/home-presets registry
    • getPresetPack() → presets.pack folder name under ring-presets/<pack>/ (null when unset)
    • getOverlayFeature() → overlay.featureId (null on bare Layer1)
    • getProductFieldsPreset() / getProductFieldsPresets()
    • getProductBadgesPreset() / getProductBadgesPresets()

    Entities registry

    Rule: preset names appear in ring-config + the registry map. Consumers call getEntityTypes() / getEntityTypeList() — never import agricultural.ts directly.

    Custom niche on a clone: add features/entities/presets/<name>.ts in the clone project, overlay index.ts to register it, set entities.preset to that name, then ringdom-clone-build.

    Bundle discipline: sync catalogs are lightweight UI lists. Heavy ERP field catalogs live in *-erp.ts modules loaded only via async loadErpEntityTypes().

    Copy / icons layering (no hardcoded UI strings)

    • Catalog (presets/<name>.ts): ids, emoji, English fallback names/descriptions
    • Copy: locales/*/modules/entities.json → types.<id> + types.<id>Desc
    • Visual skin: components/entities/entity-type-icons.tsx TYPE_VISUALS map
    • Render: useEntityTypeLabel() / useEntityTypeDescription() — i18n first, catalog fallback

    Home landing registry

    Add a shared vertical (platform)

    1. Add features/entities/presets/<name>.ts (+ optional <name>-erp.ts)
    2. One line in ENTITIES_PRESET_REGISTRY (+ ERP_CATALOG_REGISTRY if needed)
    3. Optional landing → components/pages/home-presets/<name>.tsx
    4. Optional Tier-1 maps under productFieldsPresets / productBadgesPresets
    5. i18n keys in locales/*/modules/entities.json
    6. Document the preset id in ring-config.template.json

    Target roster: platform, agricultural, then tourism, sport, business, pet, auto, connect, technopark, manufacturing.

    Thin exclude (propagation)

    .reggie-propagate-exclude.json protects overlay-only paths from being overwritten by Reggie:

    • ring-config.json
    • public/logo*.svg, favicon.ico, public/branding/
    • locales/{en,uk,ru}/config.json, vendor.json
    • Custom features/*/presets/<clone-only>.ts (+ registry overlay) when not upstreamed yet
    • Tier-3 plug: lib/overlay/registry.ts only (maps). Do not exclude lib/overlay/types.ts or lib/overlay/runtime.ts — those are platform SSOT.

    Tier-3 overlay socket (platform) + plug (clone)

    PathOwnerRole
    lib/overlay/types.tsLayer1Contracts (OverlayMessages, registries)
    lib/overlay/runtime.tsLayer1loadPackMessages / loadOverlayMessages / resolveOverlayHomeRail
    lib/overlay/registry.tsLayer1 empty maps; clone overlays mapsDomain feature loaders
    locales/{locale}/pack.jsonLayer1 ships {}; pack overwrites at composePack i18n namespaces

    Consumers import from @/lib/overlay/runtime. Clones never duplicate loaders in registry.ts. Do not add pack to LocaleFileId / assembleMessages — pack merge happens in buildMessages outside 'use cache', same as the overlay.

    Pack locale socket (Layer1)

    StageLoaderCached?
    Layer1 locales/{locale}/**/*.jsonassembleMessagesYes
    Pack locales/{locale}/pack.jsonloadPackMessagesNo — skipped when getPresetPack() is null
    Clone appendOverlayMessagesloadOverlayMessagesNo — skipped when getOverlayFeature() is null

    Later leaf keys win (mergeJsonRecords in lib/i18n.ts). Nested objects merge, so a clone overlay can override one string without replacing the pack namespace.

    Layer1 keeps an empty pack.json for every fallback locale (en, uk, ru, es, de) so webpack always resolves @/locales/${loc}/pack.json on bare Layer1 and on the empire overlay.

    In block comments, write locales/{locale}/pack.json. A glob locales/*/pack.json inside /* … */ terminates the comment at */.

    Pack copy is how a vertical (news, marketplace, …) ships extra labels without editing Layer1 lib/i18n.ts. Your clone still wins brand leaves through the overlay plug. Icon ids for pack nav slots are a separate Layer1 map — see Whitelabel navigation.

    loadPackMessages (in lib/overlay/runtime.ts) returns {} when presets.pack is unset. Otherwise it dynamic-imports @/locales/${loc}/pack.json (loc is uk, ru, es, or de when the request locale matches those; any other code uses en) and accepts a JSON object only (arrays are rejected).

    Nav chrome: packs may overwrite lib/navigation/primary-nav.ts. They must not overwrite lib/navigation/platform-menu.ts or lib/navigation/primary-nav-icons.ts. New Lucide ids land on Layer1 first.

    Operator checklist (calculator / Order Lab): Ringization playbook. Shared code ships from Layer1 ring/web. Clone-local custom presets stay in the clone dir and win at compose (ringdom-clone-build / merge-dev).

    GreenFood cutover

    Deprecated

    • Hard-coded if (productPreset === 'agricultural') in accessors
    • Per-clone custom-types.ts / overrides.ts without a named preset module
    • switch (vertical) in feature code — use the registry
    • Building Docker images from a thin overlay without platform merge
    • Adding pack to LocaleFileId / putting pack.json inside 'use cache'
    • Overlaying lib/navigation/primary-nav-icons.ts with clone-named Lucide imports

    Related documentation

    Related documentation

    Localization

    Deep-dive: message merge order, pack.json shape, and locale env.

    Whitelabel Navigation

    Next-step: closed icon map and overlay remap-only nav socket.

    Ringization playbook

    Same-workflow: Tier-1/2/3 ringize and overlay registry plug.

    Customization Guide

    Prerequisite: config-first branding before named presets.

    1. Docs
    2. /Customization
    3. /Vertical Presets (SSOT)

    Updated Sep 9, 20265 min listen

    Vertical Presets (SSOT)

    Use Founder / Developer tabs in the docs sidebar to filter this page. Shared sections apply to both audiences.

    Ring white-labels share one Layer1 codebase: ring/web (hostname ring-platform.org is the docs portal, not a checkout directory). Verticals are selected by preset name in ring-config.json. Typed catalogs live under features/*/presets/<preset>.ts (and home under components/pages/home-presets/<preset>.tsx). Optional L2 packs sit at ring-presets/<pack>/ and compose between Layer1 and the clone overlay.

    Two sources of preset modules

    SourceWhat lives thereWhen it wins
    Platform (ring-platform.org)Shared niches (platform, agricultural, …)Base of every build
    Clone project dir (e.g. ring-greenfood-live)Branding, ring-config.json, custom <preset>.ts + registry overlaysOverwrite on collision after platform copy

    Build merge (clone truth prevails)

    Use ringdom-clone-build (ringdom-mcp):

    1. Copy latest ring-platform.org → build tmp (skips node_modules / .next / .git)
    2. Copy all files from the clone project dir onto that tmp — overwrite collisions
    3. Docker / CI build from the tmp dir

    Do not expect a thin overlay alone to be a runnable app — merge first.

    Two tiers of content

    TierWhatWhere
    1 — dataCategory lists, badge tokens, labelsring-config.json maps + locales/
    2 — typed logicEntity catalogs, zod/forms, niche field UIsfeatures/*/presets/<preset>.ts (platform and/or clone overlay)

    Config keys

    GreenFood sets entities / productFields / productBadges to "agricultural" and home.preset to "mvm-landing".

    Accessors (named preset SSOT)

    All use the configured *.preset string. If a singular key is unset, entities and productBadges fall back to productFields.preset, then "platform" — no hard-coded niche if/else.

    • getEntitiesPreset() → features/entities/presets registry
    • getHomePreset() → components/pages/home-presets registry
    • getPresetPack() → presets.pack folder name under ring-presets/<pack>/ (null when unset)
    • getOverlayFeature() → overlay.featureId (null on bare Layer1)
    • getProductFieldsPreset() / getProductFieldsPresets()
    • getProductBadgesPreset() / getProductBadgesPresets()

    Entities registry

    Rule: preset names appear in ring-config + the registry map. Consumers call getEntityTypes() / getEntityTypeList() — never import agricultural.ts directly.

    Custom niche on a clone: add features/entities/presets/<name>.ts in the clone project, overlay index.ts to register it, set entities.preset to that name, then ringdom-clone-build.

    Bundle discipline: sync catalogs are lightweight UI lists. Heavy ERP field catalogs live in *-erp.ts modules loaded only via async loadErpEntityTypes().

    Copy / icons layering (no hardcoded UI strings)

    • Catalog (presets/<name>.ts): ids, emoji, English fallback names/descriptions
    • Copy: locales/*/modules/entities.json → types.<id> + types.<id>Desc
    • Visual skin: components/entities/entity-type-icons.tsx TYPE_VISUALS map
    • Render: useEntityTypeLabel() / useEntityTypeDescription() — i18n first, catalog fallback

    Home landing registry

    Add a shared vertical (platform)

    1. Add features/entities/presets/<name>.ts (+ optional <name>-erp.ts)
    2. One line in ENTITIES_PRESET_REGISTRY (+ ERP_CATALOG_REGISTRY if needed)
    3. Optional landing → components/pages/home-presets/<name>.tsx
    4. Optional Tier-1 maps under productFieldsPresets / productBadgesPresets
    5. i18n keys in locales/*/modules/entities.json
    6. Document the preset id in ring-config.template.json

    Target roster: platform, agricultural, then tourism, sport, business, pet, auto, connect, technopark, manufacturing.

    Thin exclude (propagation)

    .reggie-propagate-exclude.json protects overlay-only paths from being overwritten by Reggie:

    • ring-config.json
    • public/logo*.svg, favicon.ico, public/branding/
    • locales/{en,uk,ru}/config.json, vendor.json
    • Custom features/*/presets/<clone-only>.ts (+ registry overlay) when not upstreamed yet
    • Tier-3 plug: lib/overlay/registry.ts only (maps). Do not exclude lib/overlay/types.ts or lib/overlay/runtime.ts — those are platform SSOT.

    Tier-3 overlay socket (platform) + plug (clone)

    PathOwnerRole
    lib/overlay/types.tsLayer1Contracts (OverlayMessages, registries)
    lib/overlay/runtime.tsLayer1loadPackMessages / loadOverlayMessages / resolveOverlayHomeRail
    lib/overlay/registry.tsLayer1 empty maps; clone overlays mapsDomain feature loaders
    locales/{locale}/pack.jsonLayer1 ships {}; pack overwrites at composePack i18n namespaces

    Consumers import from @/lib/overlay/runtime. Clones never duplicate loaders in registry.ts. Do not add pack to LocaleFileId / assembleMessages — pack merge happens in buildMessages outside 'use cache', same as the overlay.

    Pack locale socket (Layer1)

    StageLoaderCached?
    Layer1 locales/{locale}/**/*.jsonassembleMessagesYes
    Pack locales/{locale}/pack.jsonloadPackMessagesNo — skipped when getPresetPack() is null
    Clone appendOverlayMessagesloadOverlayMessagesNo — skipped when getOverlayFeature() is null

    Later leaf keys win (mergeJsonRecords in lib/i18n.ts). Nested objects merge, so a clone overlay can override one string without replacing the pack namespace.

    Layer1 keeps an empty pack.json for every fallback locale (en, uk, ru, es, de) so webpack always resolves @/locales/${loc}/pack.json on bare Layer1 and on the empire overlay.

    In block comments, write locales/{locale}/pack.json. A glob locales/*/pack.json inside /* … */ terminates the comment at */.

    Pack copy is how a vertical (news, marketplace, …) ships extra labels without editing Layer1 lib/i18n.ts. Your clone still wins brand leaves through the overlay plug. Icon ids for pack nav slots are a separate Layer1 map — see Whitelabel navigation.

    loadPackMessages (in lib/overlay/runtime.ts) returns {} when presets.pack is unset. Otherwise it dynamic-imports @/locales/${loc}/pack.json (loc is uk, ru, es, or de when the request locale matches those; any other code uses en) and accepts a JSON object only (arrays are rejected).

    Nav chrome: packs may overwrite lib/navigation/primary-nav.ts. They must not overwrite lib/navigation/platform-menu.ts or lib/navigation/primary-nav-icons.ts. New Lucide ids land on Layer1 first.

    Operator checklist (calculator / Order Lab): Ringization playbook. Shared code ships from Layer1 ring/web. Clone-local custom presets stay in the clone dir and win at compose (ringdom-clone-build / merge-dev).

    GreenFood cutover

    Deprecated

    • Hard-coded if (productPreset === 'agricultural') in accessors
    • Per-clone custom-types.ts / overrides.ts without a named preset module
    • switch (vertical) in feature code — use the registry
    • Building Docker images from a thin overlay without platform merge
    • Adding pack to LocaleFileId / putting pack.json inside 'use cache'
    • Overlaying lib/navigation/primary-nav-icons.ts with clone-named Lucide imports

    Related documentation

    Related documentation

    Localization

    Deep-dive: message merge order, pack.json shape, and locale env.

    Whitelabel Navigation

    Next-step: closed icon map and overlay remap-only nav socket.

    Ringization playbook

    Same-workflow: Tier-1/2/3 ringize and overlay registry plug.

    Customization Guide

    Prerequisite: config-first branding before named presets.

    1. Docs
    2. /Customization
    3. /Vertical Presets (SSOT)

    Updated Sep 9, 20265 min listen

    Locale System

    See-also: locale-config SSOT used by pack locale fallback.

    json
    
    {
      "presets": { "pack": "news-station" },
      "entities": { "preset": "platform" },
      "home": { "preset": "platform" },
      "productFields": { "preset": "platform" },
      "productBadges": { "preset": "platform" },
      "productFieldsPresets": {
        "platform": { "storeCategories": ["commerce", "education", "…"] },
        "agricultural": { "storeCategories": ["organic-produce", "honey-sweets", "…"] }
      },
      "productBadgesPresets": {
        "platform": { "productBadges": ["new", "featured", "popular"] },
        "agricultural": { "productBadges": ["organic", "local", "regenerative"] }
      }
    }
    text
    
    ringdom-clone-build({ project_name: "ring-greenfood-live", dry_run?: true })
    → .ringdom-build/<project>/<timestamp>
    text
    
    features/entities/presets/
      types.ts             # EntityTypeCatalog contract
      platform.ts          # export const entityTypes (26 industries)
      agricultural.ts      # healthy-living UI catalog (lightweight)
      agricultural-erp.ts  # heavy ERP field catalogs — async-only via loadErpEntityTypes()
      index.ts             # ENTITIES_PRESET_REGISTRY + getEntityTypes()
    text
    
    components/pages/
      home.tsx                       # platform default landing
      home-presets/mvm-landing.tsx   # multi-vendor-marketplace e-commerce landing
      home-content-resolver.tsx      # HOME_PRESET_REGISTRY + getHomePreset()
    text
    
    ensure ring-config: entities/productFields/productBadges = agricultural, home = mvm-landing
    keep branding + locale deltas in ring-greenfood-live
    ringdom-clone-build({ project_name: "ring-greenfood-live" })
    build/deploy from .ringdom-build/ring-greenfood-live/<stamp>

    Locale System

    See-also: locale-config SSOT used by pack locale fallback.

    json
    
    {
      "presets": { "pack": "news-station" },
      "entities": { "preset": "platform" },
      "home": { "preset": "platform" },
      "productFields": { "preset": "platform" },
      "productBadges": { "preset": "platform" },
      "productFieldsPresets": {
        "platform": { "storeCategories": ["commerce", "education", "…"] },
        "agricultural": { "storeCategories": ["organic-produce", "honey-sweets", "…"] }
      },
      "productBadgesPresets": {
        "platform": { "productBadges": ["new", "featured", "popular"] },
        "agricultural": { "productBadges": ["organic", "local", "regenerative"] }
      }
    }
    text
    
    ringdom-clone-build({ project_name: "ring-greenfood-live", dry_run?: true })
    → .ringdom-build/<project>/<timestamp>
    text
    
    features/entities/presets/
      types.ts             # EntityTypeCatalog contract
      platform.ts          # export const entityTypes (26 industries)
      agricultural.ts      # healthy-living UI catalog (lightweight)
      agricultural-erp.ts  # heavy ERP field catalogs — async-only via loadErpEntityTypes()
      index.ts             # ENTITIES_PRESET_REGISTRY + getEntityTypes()
    text
    
    components/pages/
      home.tsx                       # platform default landing
      home-presets/mvm-landing.tsx   # multi-vendor-marketplace e-commerce landing
      home-content-resolver.tsx      # HOME_PRESET_REGISTRY + getHomePreset()
    text
    
    ensure ring-config: entities/productFields/productBadges = agricultural, home = mvm-landing
    keep branding + locale deltas in ring-greenfood-live
    ringdom-clone-build({ project_name: "ring-greenfood-live" })
    build/deploy from .ringdom-build/ring-greenfood-live/<stamp>

    Locale System

    See-also: locale-config SSOT used by pack locale fallback.

    json
    
    {
      "presets": { "pack": "news-station" },
      "entities": { "preset": "platform" },
      "home": { "preset": "platform" },
      "productFields": { "preset": "platform" },
      "productBadges": { "preset": "platform" },
      "productFieldsPresets": {
        "platform": { "storeCategories": ["commerce", "education", "…"] },
        "agricultural": { "storeCategories": ["organic-produce", "honey-sweets", "…"] }
      },
      "productBadgesPresets": {
        "platform": { "productBadges": ["new", "featured", "popular"] },
        "agricultural": { "productBadges": ["organic", "local", "regenerative"] }
      }
    }
    text
    
    ringdom-clone-build({ project_name: "ring-greenfood-live", dry_run?: true })
    → .ringdom-build/<project>/<timestamp>
    text
    
    features/entities/presets/
      types.ts             # EntityTypeCatalog contract
      platform.ts          # export const entityTypes (26 industries)
      agricultural.ts      # healthy-living UI catalog (lightweight)
      agricultural-erp.ts  # heavy ERP field catalogs — async-only via loadErpEntityTypes()
      index.ts             # ENTITIES_PRESET_REGISTRY + getEntityTypes()
    text
    
    components/pages/
      home.tsx                       # platform default landing
      home-presets/mvm-landing.tsx   # multi-vendor-marketplace e-commerce landing
      home-content-resolver.tsx      # HOME_PRESET_REGISTRY + getHomePreset()
    text
    
    ensure ring-config: entities/productFields/productBadges = agricultural, home = mvm-landing
    keep branding + locale deltas in ring-greenfood-live
    ringdom-clone-build({ project_name: "ring-greenfood-live" })
    build/deploy from .ringdom-build/ring-greenfood-live/<stamp>