diff --git a/docs/knowledge-base/_category_.json b/docs/knowledge-base/_category_.json index 0fcf2aa..18c0f7d 100644 --- a/docs/knowledge-base/_category_.json +++ b/docs/knowledge-base/_category_.json @@ -1,5 +1,5 @@ { "label": "Knowledge Base", "position": 7, - "collapsed": true + "collapsed": false } diff --git a/docs/knowledge-base/system-architecture.md b/docs/knowledge-base/system-architecture.md new file mode 100644 index 0000000..95c315b --- /dev/null +++ b/docs/knowledge-base/system-architecture.md @@ -0,0 +1,171 @@ +--- +title: Fluent System Architecture +sidebar_position: 3 +--- + +Fluent is built as a **blended execution** system: different execution environments can coexist behind one shared state machine and one proving-oriented runtime model. + +This page is a practical architecture map based on: + +- the `fluentlabs-xyz/tech-book` architecture chapters, and +- current Fluentbase runtime docs (`fluentbase/docs/*`). + +When older tech-book wording and current runtime behavior diverge, this page follows current Fluentbase behavior. + +--- + +## 1) Big picture + +At a high level, Fluent has three layers: + +1. **Node/consensus shell** (modified Reth stack): transaction/block pipeline, networking, RPC, and chain integration. +2. **Execution coordination layer** (REVM integration + host): frame lifecycle, journal/state commit rules, privileged host operations. +3. **Runtime execution layer** (rWasm-based runtime model): contract logic execution, runtime dispatch, and resumable interruption flow. + +The key design choice is that **execution** and **state commitment** are deliberately separated: + +- runtimes execute logic and can yield, +- host/REVM performs authoritative stateful operations, +- final effects are committed deterministically. + +--- + +## 2) Blended execution model + +Traditional multi-VM designs often keep separate VM engines with explicit cross-VM bridges. +Fluent’s architecture instead centers on one execution substrate and shared state semantics. + +In practice: + +- applications from different VM ecosystems are represented through Fluent runtime routing, +- they share one address/state space, +- composability is native and synchronous at execution time. + +This is the architectural reason Fluent emphasizes **blended execution** rather than “many isolated VMs in one node.” + +--- + +## 3) Runtime routing via ownable accounts + +Fluentbase uses an ownable-account model to decide **which runtime executes an account**. + +Conceptually: + +- account identity and account state remain local to that account, +- execution engine is selected by owner/runtime routing, +- many accounts can share the same runtime implementation safely. + +Create-time routing determines runtime class (for example EVM/default path, and other runtime-specific paths via constructor format/prefix rules). + +Execution-time behavior then loads delegated runtime logic while preserving account-specific state isolation. + +This is the core mechanism that enables one state machine to host multiple EE styles without per-account VM duplication. + +--- + +## 4) Interruption protocol (`exec` / `resume`) + +Fluent runtimes are not treated as all-powerful engines. +When runtime code needs host-authoritative work (stateful/privileged operations), execution uses interruption: + +1. runtime executes, +2. runtime yields with interruption metadata, +3. host processes the requested action, +4. runtime resumes from saved context, +5. flow continues until final exit. + +Important properties: + +- resumable contexts are transaction-scoped, +- call IDs are protocol-significant, +- host remains final authority for sensitive transitions, +- deterministic resume behavior is required for consensus safety. + +This protocol is one of the most important architecture differences from simpler “single engine call” models. + +--- + +## 5) Syscall architecture (two layers) + +Fluentbase separates syscall concerns into two related surfaces: + +- **Runtime import layer**: what contracts/runtimes can call through the import namespace. +- **Host interruption syscall IDs**: host-side operation handlers used during interruption processing. + +Why this matters: + +- API shape and fuel rules at the import layer affect runtime compatibility, +- handler semantics at host layer affect consensus behavior, +- both must evolve in lockstep. + +--- + +## 6) Dual metering: gas and fuel + +Fluent keeps both: + +- **gas** (EVM-visible economics), and +- **fuel** (runtime execution accounting). + +These are linked by deterministic conversion (currently documented as `FUEL_DENOM_RATE = 20`). + +Operationally: + +- runtime runs under fuel limits derived from remaining gas, +- consumed/refunded fuel is translated back into gas settlement, +- conversion behavior is part of protocol consistency. + +So metering is not cosmetic; it is a core architecture contract between runtime and host. + +--- + +## 7) System runtimes and structured envelopes + +Fluent distinguishes regular contract execution from selected system/runtime paths. +For system runtime flows, output is carried in structured envelopes so host can deterministically apply: + +- return payload, +- storage/log effects, +- metadata transitions, +- frame/continuation outcomes. + +This envelope discipline is essential for correctness when execution is resumable and host-mediated. + +--- + +## 8) Upgrade architecture + +Fluent supports privileged runtime upgrades through a constrained control plane. + +Design intent: + +- allow runtime evolution without repeated hard-fork style node rewrites, +- keep authority and execution-path checks explicit, +- enforce host-side validation and routing restrictions for upgrade calls. + +In other words, runtime extensibility is intentional, but bounded by strict governance and host enforcement. + +--- + +## 9) Security and consensus boundaries + +From an architecture perspective, the highest-risk boundaries are: + +- runtime routing integrity, +- interruption/resume integrity, +- static-context immutability enforcement, +- bounds-before-allocation in host paths, +- syscall semantic determinism, +- upgrade authority boundaries. + +Most critical bugs in this type of system come from violating one of those boundaries, not from ordinary application logic. + +--- + +## 10) Practical mental model + +If you need one sentence: + +**Fluent is a host-governed, interruption-driven, rWasm-centered blended execution architecture where multiple EE styles share one state machine under deterministic routing, metering, and commit rules.** + +That model matches the tech-book architecture goals while aligning with current Fluentbase runtime docs and implementation direction. diff --git a/docs/system-architecture/01-overview.md b/docs/system-architecture/01-overview.md new file mode 100644 index 0000000..2bf9e32 --- /dev/null +++ b/docs/system-architecture/01-overview.md @@ -0,0 +1,82 @@ +--- +title: Architecture Overview +sidebar_position: 1 +--- + +Fluent is designed as a **blended execution** system: contracts from different execution environments can coexist behind one shared state machine. + +This section explains architecture at a systems level (not line-by-line code internals), using: + +- `fluentlabs-xyz/tech-book` as the conceptual baseline, +- current `fluentbase/docs` as implementation-aligned behavior. + +## The core architectural idea + +Most systems either: + +- run one VM everywhere, or +- run many VMs side-by-side and bridge between them. + +Fluent’s model is different: + +- one shared execution/state surface, +- runtime routing to decide how account logic is executed, +- host-governed interruption protocol for privileged/stateful operations, +- deterministic commit via REVM integration. + +This is why Fluent uses the term **blended execution** instead of just “multi-VM.” + +## Three layers to keep in mind + +### 1) Node and consensus shell + +A modified Reth-based node stack handles standard blockchain concerns: + +- networking, +- tx/block processing, +- mempool, +- RPC and external interfaces. + +### 2) Execution coordination layer + +This layer (REVM integration + host handlers) is responsible for: + +- frame lifecycle, +- state journal/commit rules, +- privileged host actions, +- syscall interruption handling. + +### 3) Runtime execution layer + +This layer runs contract/runtime logic using Fluent’s rWasm-centered runtime model. +It includes runtime dispatch, resumable contexts, and SDK/system binding boundaries. + +## Why this split matters + +Execution and commitment are not the same thing: + +- runtime executes logic and can yield, +- host validates and performs privileged state actions, +- final effects are committed deterministically. + +That separation is central to both security and proving ergonomics. + +## What this architecture is trying to optimize + +Fluent’s architecture balances: + +- **compatibility** (especially Ethereum-facing behavior), +- **composability** (cross-EE calls over shared state), +- **determinism** (consensus safety), +- **proving friendliness** (single blended execution model rather than many isolated proof domains). + +## Reading order + +1. [Execution model](./02-execution-model.md) +2. [Runtime routing and ownership](./03-runtime-routing-and-ownership.md) +3. [Interruption and syscall model](./04-interruption-and-syscalls.md) +4. [Runtime families and blended VM mapping](./05-runtime-families-and-blended-vm.md) +5. [State and storage model](./06-state-and-storage-model.md) +6. [Gas/fuel metering model](./07-gas-and-fuel-model.md) +7. [Upgrade and security boundaries](./08-upgrades-and-security-boundaries.md) +8. [L2/rollup context](./09-l2-rollup-context.md) diff --git a/docs/system-architecture/02-execution-model.md b/docs/system-architecture/02-execution-model.md new file mode 100644 index 0000000..7128a74 --- /dev/null +++ b/docs/system-architecture/02-execution-model.md @@ -0,0 +1,61 @@ +--- +title: Execution Model +sidebar_position: 2 +--- + +Fluent executes applications under a **shared execution model** rather than isolated per-VM silos. + +## Blended execution in practice + +At runtime, the system treats different EE styles (EVM-oriented, Wasm-oriented, and other routed runtimes) as parts of one coherent execution domain. + +The practical outcome: + +- contracts share one state space, +- cross-runtime interactions are direct and synchronous, +- composability does not require external asynchronous bridges for in-transaction calls. + +## Why not classic multi-VM + +Classic multi-VM systems frequently pay extra complexity for: + +- state synchronization between VM domains, +- consistency guarantees across VM boundaries, +- duplicated invariants in multiple runtimes. + +Fluent’s architecture instead centralizes execution coordination and state commitment, and uses runtime routing + interruption to keep policy enforcement unified. + +## Integration challenges Fluent must solve + +The tech-book highlights several architectural pain points when blending EEs. These remain useful design constraints: + +1. **Cryptography mismatch** between ecosystems. +2. **Address format mismatch** (20-byte vs other formats). +3. **Different metering models** and gas accounting assumptions. +4. **Different bytecode/account metadata requirements**. +5. **Variable storage patterns and data sizes**. + +Fluent addresses these by combining: + +- runtime-specific execution paths, +- compatibility-oriented interfaces, +- raw/storage-oriented interfaces where needed, +- host-governed syscall/interruption boundaries. + +## Deterministic host authority + +A key architectural rule: even when runtime code executes most of the business logic, sensitive operations still pass through host authority paths. + +This is enforced through interruption protocol and syscall handlers, so consensus-critical behavior is concentrated in one deterministic control plane. + +## Conceptual flow + +At high level, one transaction follows this shape: + +1. tx enters node pipeline, +2. REVM/frame setup resolves target execution path, +3. runtime executes until finalization or interruption, +4. host resolves interruptions and resumes execution as needed, +5. final result + state effects are committed. + +The rest of this section explains each of those moving parts in detail. diff --git a/docs/system-architecture/03-runtime-routing-and-ownership.md b/docs/system-architecture/03-runtime-routing-and-ownership.md new file mode 100644 index 0000000..31cc28e --- /dev/null +++ b/docs/system-architecture/03-runtime-routing-and-ownership.md @@ -0,0 +1,62 @@ +--- +title: Runtime Routing and Ownership +sidebar_position: 3 +--- + +Fluentbase separates two concerns that are often conflated: + +- **account identity/state**, and +- **execution engine selection**. + +## Ownable-account routing model + +In Fluent’s architecture, account execution can be delegated through ownership/runtime metadata. +That lets many accounts share runtime logic while preserving per-account state isolation. + +Why this matters: + +- avoids per-account runtime duplication, +- makes runtime families explicit, +- gives deterministic dispatch behavior. + +## Create-time runtime selection + +At deployment time, constructor payload format/prefix and routing rules determine the runtime class. + +Examples from current Fluentbase architecture include routed paths such as: + +- EVM/default delegated runtime, +- runtime-specific routed deploy paths (for supported formats), +- specialized runtime paths (for example universal token runtime pattern). + +Once created, account execution follows that routing model consistently. + +## Execution-time behavior + +When a routed account is called: + +- delegated runtime logic is used for execution, +- account-local state remains attached to the called account, +- host/REVM maintains authoritative commit semantics. + +This is how Fluent gets “shared runtime logic + isolated account state” simultaneously. + +## Direct-runtime call policy + +Runtime-owner addresses are not intended to be regular user-facing contracts. +By design, user execution should go through routed account semantics, not bypass routing invariants via direct runtime-owner invocation. + +## Metadata and ownership boundaries + +Metadata-changing operations are ownership-scoped. +A runtime family must not freely mutate metadata for accounts owned by another runtime family. + +This boundary is part of consensus safety: incorrect ownership checks can become cross-runtime privilege bugs. + +## Architectural connection to composability + +Routing and ownership are what make cross-EE composability feasible without losing determinism: + +- calls remain in one shared state space, +- each account still has clear execution semantics, +- host maintains invariant checks at interruption/syscall boundaries. diff --git a/docs/system-architecture/04-interruption-and-syscalls.md b/docs/system-architecture/04-interruption-and-syscalls.md new file mode 100644 index 0000000..8595e54 --- /dev/null +++ b/docs/system-architecture/04-interruption-and-syscalls.md @@ -0,0 +1,85 @@ +--- +title: Interruption and Syscall Architecture +sidebar_position: 4 +--- + +Interruption is one of Fluent’s defining mechanisms. + +It exists because runtime code should not directly perform every privileged or shared-state operation. + +## The `exec` / `resume` handshake + +At a high level: + +1. runtime executes, +2. runtime requests host intervention (interruption), +3. host handles requested operation, +4. runtime resumes with result, +5. repeat until final exit. + +This creates a deterministic boundary between: + +- execution logic in runtime, +- authority logic in host/REVM layer. + +## Why interruption exists + +Some operations need centralized host control, such as: + +- frame orchestration, +- privileged account/state access, +- validated state mutations, +- protocol-enforced checks. + +Interruption avoids embedding all of those directly into application runtime execution paths. + +## Two syscall layers + +Fluentbase docs describe two related syscall surfaces: + +### A) Runtime import layer + +The runtime imports a defined namespace of system bindings (I/O, context, hashing/crypto, control, nested execution, fuel helpers, etc.). + +This is what contracts/runtimes call. + +### B) Host interruption syscall-ID layer + +Host handlers process interruption payloads with protocol-level semantics (storage access, call/create flows, metadata operations, runtime-governed actions, etc.). + +This is where consensus-critical validation and charging behavior lives. + +## Determinism requirements + +Interruption handlers must stay deterministic across nodes: + +- input validation, +- static-context handling, +- charging order, +- output encoding, +- error mapping, +- ownership checks. + +Changing these casually is not a “refactor”; it is a protocol change. + +## Call IDs and resumable contexts + +Resumable context IDs are transaction-scoped protocol objects, not convenience IDs. + +Safety expectations include: + +- correct association of resume data with call ID, +- proper lifecycle reset per transaction, +- no state leakage across independent execution flows. + +## System-runtime structured envelopes + +For system runtime paths, output is transported in structured envelopes so host can safely and deterministically apply: + +- return values, +- logs, +- storage effects, +- metadata updates, +- frame outcomes. + +This envelope contract is a critical part of host/runtime interoperability. diff --git a/docs/system-architecture/05-runtime-families-and-blended-vm.md b/docs/system-architecture/05-runtime-families-and-blended-vm.md new file mode 100644 index 0000000..ff1cc55 --- /dev/null +++ b/docs/system-architecture/05-runtime-families-and-blended-vm.md @@ -0,0 +1,64 @@ +--- +title: Runtime Families and Blended VM +sidebar_position: 5 +--- + +Fluent’s architecture supports multiple runtime families while keeping one shared execution/state model. + +## rWasm as the execution substrate + +The tech-book frames rWasm as Fluent’s proving-friendly execution substrate: + +- derived from Wasm concepts, +- adapted for ZK/proving constraints, +- used as the core execution representation in the blended model. + +In architecture terms, rWasm is not “just another VM plugin”; it is the substrate around which runtime routing and host coordination are built. + +## Two integration styles + +The architecture commonly uses two patterns: + +1. **Translation-style path** + - source format is translated into rWasm-compatible execution representation. + +2. **Runtime-proxy path** + - account execution is delegated to specialized runtime logic under ownership/routing rules. + +These patterns allow incremental support for different EE families without abandoning one-state-machine design. + +## EVM-oriented path + +Fluent’s EVM integration keeps Ethereum-facing developer ergonomics while fitting Fluent runtime boundaries. + +Conceptually: + +- deployment and execution are routed through Fluent runtime mechanisms, +- EVM compatibility surface is preserved where expected, +- host/runtime boundaries still apply for privileged operations. + +## Wasm-oriented path + +Wasm-oriented flows are close to native Fluent execution because rWasm is Wasm-derived. + +The architecture still applies additional constraints/checking relevant to proving and runtime policy. + +## Solana/SVM-oriented path + +The tech-book describes Solana-oriented integration through projection/routing ideas and runtime execution support. + +As with any evolving architecture documentation, specific maturity and network-level availability can differ by release. The stable architectural takeaway is: + +- non-EVM formats are integrated via explicit routing/runtime boundaries, +- address and data-model differences are handled by compatibility/projection mechanisms, +- shared-state composability remains the design target. + +## Why families are still one architecture + +Even with multiple runtime families, Fluent avoids fragmented execution domains by keeping: + +- one state machine, +- one host-authoritative commit model, +- one interruption/syscall control plane. + +That is the core “blended VM” architecture claim. diff --git a/docs/system-architecture/06-state-and-storage-model.md b/docs/system-architecture/06-state-and-storage-model.md new file mode 100644 index 0000000..6720d1e --- /dev/null +++ b/docs/system-architecture/06-state-and-storage-model.md @@ -0,0 +1,51 @@ +--- +title: State and Storage Model +sidebar_position: 6 +--- + +Fluent architecture keeps one shared state model while supporting heterogeneous execution styles. + +## Shared trie/state principle + +A major architectural objective is that applications from different runtime families compose over one state surface, not isolated per-VM stores. + +This is what enables synchronous composability without external state bridges. + +## Account model compatibility + +The tech-book presents a simplified account structure aligned with Ethereum-style fields (address, balance, nonce, code hash, code size). + +Current Fluent architecture extends account behavior with ownership/routing metadata concepts to support runtime delegation and compatibility mapping where required. + +## Metadata and projected representations + +To bridge execution-environment differences, Fluent architecture includes metadata-oriented patterns such as: + +- projected/compatibility address handling for non-native formats, +- metadata storage for runtime-specific context, +- ownership-linked metadata policies. + +This is an architectural response to format mismatches (address widths, bytecode containers, storage conventions). + +## Raw vs compatibility views + +A recurring design pattern is dual data exposure: + +- **compatibility-oriented view** for mainstream EVM-facing tooling, +- **raw/storage-oriented view** for infra, proving, indexing, and forensic correctness. + +This split appears in RPC and runtime design because storage-level truth and compatibility-level expectations are not always identical for wrapped/runtime-managed accounts. + +## Why the storage model is host-sensitive + +Even though runtime executes business logic, storage correctness is constrained by host/governed commit rules and interruption handling. + +So storage architecture is not just “a trie schema”; it is an execution + policy + commit contract. + +## Practical consequence for builders + +Application developers get familiar account interfaces, but protocol/infrastructure developers should remember: + +- there are intentional compatibility mappings, +- raw representations can differ, +- proof/indexing systems should choose interfaces based on whether they need compatibility semantics or canonical storage semantics. diff --git a/docs/system-architecture/07-gas-and-fuel-model.md b/docs/system-architecture/07-gas-and-fuel-model.md new file mode 100644 index 0000000..0e84968 --- /dev/null +++ b/docs/system-architecture/07-gas-and-fuel-model.md @@ -0,0 +1,57 @@ +--- +title: Gas and Fuel Model +sidebar_position: 7 +--- + +Fluent architecture uses two accounting units: + +- **Gas** for Ethereum-visible economics, +- **Fuel** for runtime execution accounting. + +## Why two units + +Different runtime paths and host operations need a uniform internal accounting model, while external users still expect gas semantics. + +Fuel is the internal execution meter; gas remains the external economic meter. + +## Deterministic conversion contract + +Fluentbase currently documents a fixed conversion linkage (`FUEL_DENOM_RATE = 20`). + +Architecture-level implication: + +- conversion rules are protocol-sensitive, +- rounding/settlement behavior must stay deterministic, +- changing conversion semantics is effectively fork-level behavior change. + +## Settlement flow + +During execution/resume cycles: + +1. host derives runtime fuel budget from remaining gas, +2. runtime executes and reports consumed/refunded fuel, +3. host maps fuel deltas back into gas settlement, +4. final interpreter/journal accounting is committed. + +This is where runtime work and EVM-visible economics are reconciled. + +## Import-level fuel schedules + +System imports are associated with explicit charging procedures (constant/linear/quadratic style depending on operation type). + +This prevents undercharging expensive paths and keeps runtime cost model transparent and deterministic. + +## Runtime-family metering differences + +Some runtime paths are self-metered while others are engine-metered by policy. + +Architecturally, this means metering policy is part of runtime classification and not a single universal behavior for all paths. + +## Why this matters for architecture + +Metering is not a minor implementation detail: + +- it constrains runtime API design, +- it affects DoS resistance, +- it impacts proving and execution economics, +- it is part of consensus correctness. diff --git a/docs/system-architecture/08-upgrades-and-security-boundaries.md b/docs/system-architecture/08-upgrades-and-security-boundaries.md new file mode 100644 index 0000000..6925c49 --- /dev/null +++ b/docs/system-architecture/08-upgrades-and-security-boundaries.md @@ -0,0 +1,62 @@ +--- +title: Upgrades and Security Boundaries +sidebar_position: 8 +--- + +Fluent’s architecture is designed to evolve runtime behavior without treating every runtime change as a full protocol rewrite. + +That flexibility exists, but only within strict authority boundaries. + +## Runtime upgrade control plane + +At architecture level, upgrades follow a privileged path: + +1. governance-authorized caller triggers upgrade flow, +2. runtime artifact validation/translation checks are applied, +3. host-enforced upgrade path updates target runtime code, +4. change is visible as consensus-relevant runtime behavior. + +Both contract-level permissions and host-level path restrictions are required. + +## Why host enforcement is mandatory + +Contract checks alone are insufficient for protocol safety. + +Host-side enforcement prevents: + +- unauthorized runtime replacement, +- invalid upgrade payload application, +- static-context bypasses, +- upgrade path misuse by ordinary execution calls. + +## Core security boundaries to preserve + +From current Fluentbase security docs, these boundaries are the most architecture-critical: + +- routing integrity (runtime resolution cannot drift), +- interruption integrity (call ID / resume correctness), +- static-context immutability for mutating operations, +- bounds-before-allocation for untrusted lengths, +- deterministic syscall semantics, +- strict upgrade authority boundaries. + +## Typical failure classes + +Most critical failures in this architecture are not ordinary business-logic bugs; they are boundary violations, for example: + +- cross-runtime metadata mutation bypass, +- interruption context confusion, +- inconsistent gas/fuel settlement, +- malformed envelope decode leading to wrong side-effect commits, +- weakly constrained upgrade entry points. + +## Operational posture + +Because runtime updates are consensus-sensitive: + +- release process must be deterministic, +- upgrade artifacts and hashes must be auditable, +- network rollout must be coordinated, +- post-upgrade checks must validate expected routing and execution behavior. + +In short: Fluent supports runtime evolution, but treats upgrade machinery as high-trust critical infrastructure. diff --git a/docs/system-architecture/09-l2-rollup-context.md b/docs/system-architecture/09-l2-rollup-context.md new file mode 100644 index 0000000..ffa392d --- /dev/null +++ b/docs/system-architecture/09-l2-rollup-context.md @@ -0,0 +1,40 @@ +--- +title: L2 Rollup Context +sidebar_position: 9 +--- + +Fluent architecture should be read in L2-rollup context, not as an isolated VM experiment. + +## Rollup framing + +At system level, Fluent is positioned as an Ethereum-aligned rollup architecture where: + +- execution happens in Fluent’s blended model, +- resulting state transitions are committed in rollup form, +- proving/verification pipeline is a first-class design concern. + +## Why blended execution and proving are linked + +A key motivation from the tech-book is reducing complexity from proving many isolated nested VM models. + +Fluent’s architecture seeks to represent execution under a unified substrate/control model so proving surfaces stay coherent. + +In practical terms, this means architecture decisions in runtime routing, interruption, syscall design, and metering are all made with proving constraints in mind. + +## Data and proof topics + +The tech-book includes dedicated placeholders/chapters for ZK proof system and data availability context. + +At this docs level, the safe takeaway is: + +- proof/DA strategy is part of architecture constraints, +- execution model is intentionally shaped to be proof-friendly, +- application/runtime interfaces are designed to preserve deterministic replay and verifiable transitions. + +## Keep architecture and runtime docs aligned + +Because this stack evolves, the most reliable mental model is: + +- use tech-book for system intent, +- use current Fluentbase runtime docs for present behavior, +- treat mismatches as versioning drift and resolve in favor of current runtime semantics for implementation-sensitive decisions. diff --git a/docs/system-architecture/_category_.json b/docs/system-architecture/_category_.json new file mode 100644 index 0000000..b1bf017 --- /dev/null +++ b/docs/system-architecture/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "System Architecture", + "position": 3, + "collapsed": false +}