Welcome to Cougr

Cougr is an on-chain game engine built for the Stellar network and Soroban smart contracts. It provides a full Entity-Component-System (ECS) runtime alongside account abstraction and zero-knowledge primitives in a single crate.

This documentation site is generated automatically from the salazarsebas/Cougr repository.

Start

Welcome to the Start section. If you're new to Cougr, this is the right place to begin.

  • Getting Started — install the toolchain and run your first test in under two minutes.
  • Build Your First Game — a step-by-step walkthrough from an empty directory to a deployed game on Stellar Testnet.

Getting Started

This page is synced from the main Cougr repository. To edit it, open a PR against salazarsebas/Cougr.


Prerequisites

Before you can build a Cougr game, you need the following tools installed:

ToolInstall command
Rust`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs
Stellar CLIcargo install stellar-cli --features opt
wasm32 targetrustup target add wasm32-unknown-unknown

Clone and run the starter example

git clone https://github.com/salazarsebas/Cougr
cd Cougr/examples/spawn_and_move
cargo test

All tests should pass within two minutes on a machine that has Rust installed.

Next step

Once the tests pass, head over to Build Your First Game for the full sequential tutorial.

Build Your First Game

This page is being written. It will be synced automatically from docs/start/build-your-first-game.md in the main Cougr repository once merged.

Tracked in: salazarsebas/Cougr — Stage 3 Tutorial issue


What you'll build

A fully working "Spawn and Move" game — players enter a shared world, get assigned an entity ID, and can walk in four directions. At the end you'll deploy it to Stellar Testnet.

Time to complete: ~30 minutes
Prerequisites: Getting Started steps complete.

Check back soon — or watch the repository to be notified when this page goes live.

Learn

The Learn section takes you from a working first game to understanding the design decisions that make Cougr work the way it does.

GuideStatus
Architecture✅ Available
Game Patterns✅ Available
On-Chain / Off-Chain Boundary Guide🔜 Coming soon
Smart Contract Patterns🔜 Coming soon
Testing Guide🔜 Coming soon
Deployment Guide🔜 Coming soon

Architecture

High-level overview of how Cougr is organized. For usage, see README.md.

Layers

┌──────────────────────────────────────────────────────────────┐
│           game::SorobanGame  (contract integration)          │  Contract layer
├──────────────────────────────────────────────────────────────┤
│               app::GameApp                                   │  Default runtime surface
├───────────┬───────────────┬──────────────────────────────────┤
│  ECS      │  Accounts     │  Standards      │  ZK Proofs     │
├───────────┴───────────────┴─────────────────┴────────────────┤
│  soroban-sdk 25.1.0  (no_std, WASM)                          │
└──────────────────────────────────────────────────────────────┘

game::SorobanGame (src/game.rs) bridges the ECS and Soroban contract models. The SorobanGame trait provides load_world and save_world as default methods, eliminating repetitive storage-key boilerplate from contract entrypoints. Wire up once with impl_soroban_game!(MyContract, "key").

The companion helpers SimpleWorld::load_from_instance and save_to_instance are the underlying primitives when you want finer control.

GameApp (src/plugin/mod.rs) is the default onboarding layer for complex games. It owns a SimpleWorld, the scheduler, plugin registration, and runtime resources in one place.

ECS

Two storage backends, same ComponentTrait interface:

BackendFileStrategyBest for
SimpleWorldsrc/simple_world/Map<(EntityId, Symbol), Bytes> with dual Table/Sparse indexesGeneral use, small entity counts
ArchetypeWorldsrc/archetype_world/Groups entities by component signatureLarge entity counts, batch queries

Both support typed access (get_typed<T>, set_typed<T>) and raw access (get_component, add_component).

Supporting systems:

  • Query cache (src/query/) — version-tagged, invalidates on world mutation
  • Hooks (src/hooks.rs) — callbacks on component add/remove
  • Observers (src/observers.rs) — event-driven reactions
  • Commands (src/commands.rs) — deferred mutations during system execution
  • Scheduler (src/scheduler/) — stage-based, dependency-aware system ordering
  • Change tracker (src/change_tracker.rs) — per-component dirty flags
  • Plugins (src/plugin/) — modular game logic bundles
  • Incremental storage (src/incremental/) — only persist dirty entities

Component definition

Three macros cover every component case:

MacroWhen to use
impl_component!Fixed-size primitives (i32, u32, u64, u128, u8, bool, bytes32)
impl_component_observed!Same as above, plus structured Soroban events on every set
impl_rich_component!Complex types via XDR codec: Address, Vec, String, Option, nested structs

impl_rich_component! requires #[contracttype] on the struct. The XDR serialisation is handled entirely by the Soroban SDK — no manual serialize/deserialize implementation is needed.

Rich components are stored in Soroban instance storage (not the ECS Map) but share the same entity ID space.

ZK Proofs (src/zk/)

All ZK operations use Stellar Protocol 25 (X-Ray) host functions — the heavy crypto runs on the host, not in WASM.

  • Groth16 (groth16.rs) — proof verification via BN254 pairing
  • BLS12-381 (bls12_381.rs) — G1 add/mul/MSM, pairing checks
  • Poseidon2 (crypto.rs) — ZK-friendly hashing, behind hazmat-crypto feature
  • Merkle trees (merkle/) — SHA256 and Poseidon variants, sparse trees, on-chain proofs
  • Pedersen (commitment.rs) — commitment scheme for hidden state
  • Game circuits (circuits.rs, traits.rs) — GameCircuit trait + pre-built circuits (Movement, Combat, Inventory, TurnSequence) + CustomCircuitBuilder
  • ECS integration (components.rs, systems.rs) — CommitReveal, HiddenState, ProofSubmission components with verification systems

Accounts (src/accounts/)

Account abstraction layer with pluggable implementations:

CougrAccount (trait)
├── ClassicAccount      — standard Stellar keypair
└── ContractAccount     — smart contract wallet
     ├── SessionStorage — persistent session keys
     ├── RecoveryStorage — guardian-based recovery
     ├── DeviceStorage  — multi-device key management
     └── Secp256r1Storage — WebAuthn/Passkey keys

Key traits: CougrAccount, SessionKeyProvider, RecoveryProvider, MultiDeviceProvider.

SessionBuilder provides a fluent API for constructing scoped session keys. authorize_with_fallback handles graceful degradation from session keys to direct authorization. See ADR 0005.

Standards (src/standards/)

Reusable contract standards for integrations that need explicit operational controls:

  • Ownable and Ownable2Step for owner-managed authority
  • AccessControl for role-based authorization with delegated admins
  • Pausable for emergency stops
  • ExecutionGuard for serialized critical sections
  • RecoveryGuard for blocking sensitive paths during recovery windows
  • BatchExecutor for bounded multi-operation flows
  • DelayedExecutionPolicy for time-delayed operation queues

Each standard instance is keyed by a caller-supplied Symbol, which keeps storage deterministic and avoids collisions when a contract composes multiple modules.

Competitive Layers (workspace subcrates)

Three layers ship inside the single cougr-core crate. Implementation lives in src/{circuits,session,test}/; internal/cougr-core-* workspace members use stubs for isolated cargo check -p runs.

Public moduleSourceMaturityFeature
cougr_core::circuitssrc/circuits/Experimentalalways
cougr_core::sessionsrc/session/Betaalways
cougr_core::testsrc/test/Betatestutils

Circuit builders: hidden_cards, fog_of_war, fair_dice, sealed_bidGameCircuitSpec. Examples: hidden_hand, fog_explorer, dice_duel, blind_auction. See ADR 0006.

The test sandbox uses no_std + alloc with Soroban testutils — not std. Enable with cougr-core feature testutils. Modules: GameHarness, Scenario, WorldFixture, ReplayLog, SnapshotAssert. See ADR 0004 and ADR 0007.

Feature Flags

FlagEnables
hazmat-cryptoPoseidon2 hash, BN254 curve ops (via soroban-sdk/hazmat-crypto)
testutilscougr_core::test sandbox, MockAccount, Soroban test helpers
debugRuntime introspection, metrics, state snapshots (src/debug/)

Build

Release builds are configured with LTO, opt-level = "z", and overflow-checks = true to keep artifacts optimized for constrained execution environments.

Primary target: wasm32v1-none.

Cougr Patterns

Purpose

This document captures the recommended architectural patterns for new Soroban game contracts built on Cougr.

The goal is to standardize how teams structure worlds, systems, stages, and storage choices instead of relying on ad-hoc example interpretation.

Find a pattern by problem

Start here if you know what you're trying to build but not which Cougr module answers it. Each row links to the module-level doc for full detail, and to a concrete, current example that demonstrates it.

I want...UseExampleRead more
Fairness (a roll, a draw, an outcome no one can predict or bias)circuits::FairDiceBuilder — on-chain Groth16-verified randomness (Experimental)dice_duelHidden Information Guidance below, PRIVACY_MODEL.md
Hidden information (cards, ship positions, sealed bids — state some players shouldn't see)privacy::stable commit-reveal + Merkle primitivesbattleship (canonical), rock_paper_scissors, hidden_hand, blind_auctionHidden Information Guidance below, PRIVACY_MODEL.md
To gate an action behind a role (admin-only, minter-only, etc.)AccessControl — role-based authorization with per-role admin delegationSTANDARDS_LAYER.md § AccessControl
Off-chain-friendly real-time movement (clients track state without polling)impl_component_observed! — emits a (COUGR, set, <component>) event on every changespawn_and_move (start here), snakeSystem Design and Query Guidance below, docs/ECS_CORE.md
A passwordless sign-in (Face ID / Touch ID instead of a seed phrase)secp256r1 passkey signer, composed through AccountKernelguild_arenaACCOUNT_KERNEL.md § Signers
A session players approve once, not per-transactionSession signer + SessionPolicy (scope, expiry, operation budget)session_arenaACCOUNT_KERNEL.md § Session Model
Account recovery if a device is lostGuardianPolicy + ActiveDevicePolicyguild_arenaACCOUNT_KERNEL.md § Policies
An emergency stop / pause switchPausableSTANDARDS_LAYER.md § Pausable
To serialize mutations / guard against reentrancy-like issuesExecutionGuardSTANDARDS_LAYER.md § ExecutionGuard
Delayed or timelocked executionDelayedExecutionPolicySTANDARDS_LAYER.md § DelayedExecutionPolicy
To batch several operations safelyBatchExecutorSTANDARDS_LAYER.md § BatchExecutor
To know whether I even need ECSDirect contract model for small/config-driven contractsWhen Not To Use ECS below
To pick table vs. sparse storageTable for hot-loop state, sparse for infrequent markersStorage Guidance below
A thin, explicit contract entrypoint / gameplay loopGameApp + explicit stage placementspawn_and_move, snakeDefault Entry Point and Stage Layout below

Everything below this point is the module-level architectural guidance the table above links into — organized by Cougr's internal structure rather than by problem, for readers who already know which area they're working in.

Default Entry Point

Use GameApp as the default runtime entrypoint.

Recommended shape:

  1. build the app
  2. register plugins and startup systems
  3. register tick systems into explicit stages, preferably with named_system(...) / named_context_system(...)
  4. run one schedule tick per contract invocation that advances gameplay

This keeps the "contract entrypoint" thin and the gameplay loop explicit.

Stage Layout

Cougr's recommended schedule is:

  • Startup: one-time entity/resource setup
  • PreUpdate: input decoding, action validation, turn preparation
  • Update: core gameplay state transitions
  • PostUpdate: scoring, derived-state maintenance, indexing side effects
  • Cleanup: despawns, expiry handling, transient marker removal

Do not use cross-stage before / after dependencies. Stage order is already the primary contract between phases.

System Design

Prefer small systems with one responsibility:

  • validation systems should reject or mark invalid intent
  • update systems should apply game-state transitions
  • cleanup systems should remove expired markers or entities

Use context-aware systems when you need deferred structural changes:

  • queue spawns during iteration
  • queue despawns after collision passes
  • queue marker additions that should apply after the current scan

Use plain world/env systems when the system only needs direct mutation and no command buffering.

Query Guidance

Prefer SimpleQueryBuilder for gameplay queries that need:

  • multiple required components
  • negative filters
  • sparse-component inclusion
  • "any-of" matching

Guidelines:

  • default to table-only queries for tight loops
  • opt into sparse inclusion only when marker/tag data must participate
  • choose required components carefully so the scheduler can use the narrowest candidate set

Hidden Information Guidance

For hidden-state or commit-reveal contracts:

  • keep the contract entrypoints thin and verification-oriented
  • use privacy::stable Merkle and commit-reveal primitives instead of example-local crypto formats
  • treat proof verification as a boundary concern, not as something every gameplay system needs to understand
  • keep public derived state separate from private commitments and Merkle roots

battleship is the canonical reference for this pattern.

Storage Guidance

Use table storage for:

  • frequently scanned gameplay state
  • canonical state that participates in core loops
  • components used by Update systems on most ticks

Use sparse storage for:

  • infrequent markers
  • administrative tags
  • components mostly accessed by targeted lookups instead of broad scans

If a component becomes part of the hot loop, move it to table storage instead of compensating with more complex query logic.

Keep modules separated by concern:

  • ECS/gameplay core
  • account/auth flows
  • privacy/ZK
  • standards/operational controls

Do not let auth or ZK concerns leak into every system by default. Compose them at the boundaries where they are needed.

When Not To Use ECS

Do not force ECS into contracts that are:

  • tiny and single-entity
  • mostly configuration/state-machine driven
  • dominated by one-off administrative flows

If the problem is closer to a fixed state machine than a world simulation, a direct contract model may be simpler and cheaper.

On-Chain / Off-Chain Boundary Guide

This page is being written.

Named as the second-highest-priority missing document in docs/strategy/08-ux-strategy.md and docs/strategy/12-documentation-architecture.md.

Tracked in: salazarsebas/Cougr issues


What this guide will cover

Developers coming from traditional game development or web backends often hit the same wall: what logic actually needs to be on-chain, and what doesn't? Getting this wrong is expensive — literally, in gas fees.

This guide will answer:

  • Which game state must live in Soroban contract storage vs. what can stay off-chain
  • How Cougr's observed components (impl_component_observed!) bridge the gap with real-time events
  • Patterns for off-chain movement with on-chain settlement
  • Resource cost intuition: what makes a transaction cheap vs. expensive

Check back soon — or watch the repository to be notified when this page goes live.

Smart Contract Patterns

This page is being written.

Will consolidate Soroban-specific patterns from PATTERNS.md and STANDARDS_LAYER.md into one place, distinguishing "Cougr patterns" from "general Soroban patterns."

Tracked in: salazarsebas/Cougr issues


What this guide will cover

  • Access control with AccessControl and Ownable
  • Emergency stop patterns with Pausable
  • Time-delayed operations with DelayedExecutionPolicy
  • Batch operations with BatchExecutor
  • How these standards compose with the ECS world

Check back soon — or watch the repository.

Testing Guide

This page is being written.

GameHarness, Scenario, and SnapshotAssert exist in the codebase and are used across thousands of lines of tests, but have no standalone guide yet. Named explicitly in docs/strategy/08-ux-strategy.md Stage 5.

Tracked in: salazarsebas/Cougr issues


What this guide will cover

  • Setting up GameHarness for unit tests
  • Writing Scenario-based integration tests
  • Using SnapshotAssert to lock in expected world state
  • How the Soroban test sandbox works (and how it differs from running cargo test for a normal library)
  • Estimating resource costs before you deploy

Check back soon — or watch the repository.

Deployment Guide

This page is being written.

The README has dev commands, but there's no standalone guide walking through production deployment to Stellar Testnet and Mainnet.

Tracked in: salazarsebas/Cougr issues


What this guide will cover

  • Configuring the Stellar CLI for Testnet and Mainnet
  • Building a release .wasm binary with the correct flags (LTO, opt-level = "z")
  • Deploying with stellar contract deploy
  • Understanding what a deployment costs (resource fees)
  • Upgrading a contract after deploy

Check back soon — or watch the repository.

Reference

The Reference section contains low-level documentation for Cougr's modules, the API surface, and architectural decision records.

DocumentDescription
ECS CoreThe core ECS primitives: Entity, Component, Query, System, Scheduler
Account KernelAccount abstraction layer — session keys, recovery, passkeys
Standards LayerReusable contract standards: AccessControl, Pausable, Ownable, etc.
Privacy ModelZK proofs, Pedersen commitments, hidden state
Feature Flagshazmat-crypto, testutils, debug — what each enables
Performance GuideResource cost intuition, benchmarks, optimization patterns
API ContractPublic API guarantees and stability promises
Compatibility PromisesWhat Cougr will and won't break between releases
Migration GuideHow to update your game for new cougr-core versions
CLI Reference🔜 Ships with the CLI
Client SDK Reference🔜 Ships with the TypeScript SDK
ADRsArchitecture Decision Records

Cougr ECS Core

Purpose

This document defines the defended conceptual model for Cougr's ECS runtime.

It is the answer to "what are the actual core primitives?" and "which path is the one new users should learn first?"

Core Model

The stable conceptual model is:

  • Entity: an opaque runtime identity
  • Component: typed or raw data attached to entities
  • Query: a declarative selection over entities by component presence
  • System: logic that reads or mutates the world
  • CommandQueue: deferred structural mutations
  • GameApp: app-level orchestration over world + scheduler + plugins
  • RuntimeWorld / RuntimeWorldMut: the shared backend contract for Soroban-first worlds

For Soroban gameplay contracts, the recommended path is:

  • app
  • SimpleWorld
  • SimpleQuery
  • SimpleScheduler
  • GameApp

ArchetypeWorld is the alternate backend for heavier query workloads.

The shared stable overlap between those backends lives in:

  • ecs::RuntimeWorld
  • ecs::RuntimeWorldMut

Backend Roles

SimpleWorld

Use when:

  • entity counts are modest
  • table-backed scans dominate
  • operational simplicity matters more than archetype migration costs

Cost profile:

  • cheap add/remove/update
  • indexed table and all-storage component lookups
  • predictable query path for common gameplay loops

ArchetypeWorld

Use when:

  • multi-component queries dominate
  • entity composition is relatively stable
  • migration cost is acceptable in exchange for tighter query scopes

Cost profile:

  • more expensive structural changes
  • more selective scans for multi-component queries

Learnability Rule

A new user should be able to learn the main Cougr runtime from:

  1. README.md
  2. GameApp
  3. SimpleWorld
  4. SimpleQueryBuilder
  5. one or two canonical examples

If a concept requires diving outside the Soroban-first runtime path to understand basic gameplay flow, that is a product bug.

Account Kernel

Purpose

The goal is to make authorization explicit, modular, and replay-safe while keeping the accounts namespace outside Cougr's frozen 1.0 stable contract.

Core Model

The account subsystem is now organized around:

  • AccountKernel
    • the orchestrator that runs signer verification, policy checks, and replay protection
  • signer interfaces
    • AccountSigner
    • base implementations: direct owner auth, session auth, secp256r1 passkey auth
  • policy interfaces
    • generic Policy<C>
    • base implementations for intent expiry, session enforcement, active device checks, and guardian checks
  • signed intent schema
    • SignedIntent, SignerRef, IntentProof
  • structured auth results
    • AuthResult, AuthMethod

Signed Intent Schema

SignedIntent binds:

  • target account
  • signer reference
  • action payload
  • nonce
  • expiry
  • deterministic action_hash
  • proof material

The deterministic hash is derived from:

  • nonce
  • expiry
  • signer identity fields
  • action system name
  • action bytes

Replay Protection

Cougr uses two replay domains:

  • per-account nonce tracking for direct owner auth and passkey auth
  • per-session nonce tracking for session intents

The replay implementation lives in:

Session Model

Session state now includes:

  • unique key_id
  • scoped allowed actions
  • operation budget
  • expiration timestamp
  • next_nonce

Session enforcement requires all of:

  • session exists
  • action is in scope
  • session is not expired
  • operation budget remains
  • intent nonce matches next_nonce

On success the session consumes one operation and advances next_nonce.

Signers

Current base signer implementations:

  • direct owner signer
    • uses require_auth
  • session signer
    • explicit non-fallback session path evaluated by the kernel
  • secp256r1 passkey signer
    • verifies signatures against registered passkeys

Policies

The policy layer is intentionally reusable across account features.

Current base policies:

  • IntentExpiryPolicy
  • SessionPolicy
  • ActiveDevicePolicy
  • GuardianPolicy

This is how device and recovery support now live under the same policy model instead of ad hoc checks.

Auth Results

AuthResult returns structured information instead of only Result<(), AccountError>.

Current fields:

  • method used
  • nonce consumed
  • session key id, when applicable
  • remaining operations, when applicable

Integration Note

The account kernel is now consumed through the curated accounts / auth surface directly.

The previous GameWorld wrapper was removed so 1.0.0 does not freeze an extra orchestration layer. Authorization should be composed explicitly at the application layer around GameApp, SimpleWorld, and the account primitives.

Standards Layer

Purpose

The standards layer introduces reusable, storage-aware contract primitives in the style of OpenZeppelin building blocks, but shaped for Cougr's Soroban-oriented single-crate model.

These modules are meant to be composed into application contracts and account flows without depending on any example project.

Included Standards

Ownable

  • single-owner access primitive
  • explicit initialization
  • direct transfer and renounce flows
  • typed ownership transition events

Ownable2Step

  • staged ownership handoff
  • pending-owner tracking in storage
  • explicit acceptance requirement before ownership changes
  • cancellation support for abandoned handoffs

AccessControl

  • role-based authorization keyed by Symbol
  • per-role admin delegation
  • explicit grant, revoke, and renounce semantics
  • default admin role for bootstrapping new modules

Pausable

  • storage-backed emergency stop flag
  • explicit paused and unpaused transitions
  • guard methods for mutating entrypoints

ExecutionGuard

  • storage-backed execution lock
  • suited for reentrancy-like protection and mutation serialization
  • can be used as explicit enter/exit calls or as a scoped closure wrapper

RecoveryGuard

  • blocks sensitive flows while a recovery window is active
  • generic enough to compose with account recovery or application-defined incident response

BatchExecutor

  • reusable batch length validation
  • single-path execution semantics for collections of operations
  • explicit empty and oversize rejection

DelayedExecutionPolicy

  • storage-backed delayed operation queue
  • deterministic operation IDs
  • readiness and expiry checks
  • cancellation and execution events

Storage and Namespacing

Each standards module is instantiated with a Symbol identifier.

That identifier becomes part of the storage key, which allows a single contract to host multiple independent instances of the same standard without collisions.

Authorization Model

These modules do not assume hidden caller semantics.

Where authorization matters:

  • Ownable and Ownable2Step require an explicit caller address
  • AccessControl checks the caller against the relevant admin role
  • Pausable, RecoveryGuard, and similar state machines leave the surrounding authorization decision to the integrating contract

This is intentional. Cougr keeps authorization visible at the integration boundary instead of burying it in generic helpers.

Error Semantics

The standards layer uses StandardsError for consistent negative-path behavior across integrations.

Important failure modes include:

  • unauthorized caller
  • duplicate initialization
  • missing or mismatched pending owner
  • duplicate role grant or missing role during revoke
  • paused versus not-paused guard failures
  • execution lock contention
  • recovery-active guard failure
  • empty or oversized batches
  • delayed operation not ready, expired, already executed, or missing

Maturity

Status: Stable

The standards layer is part of Cougr's frozen 1.0 stable contract. Integrators should still supply their own caller-auth composition where required, but the module interfaces and documented failure semantics are now part of the defended public surface.

Cougr Privacy Model

Purpose

This document defines Cougr's privacy and proof-verification contract after the 1.0 release gate.

Its job is to separate the stable privacy subset from experimental proof systems so that the repository can make a smaller, stronger claim about what is safe to depend on in the stable contract.

Stable Privacy Surface

The stable privacy subset in Cougr is:

  • commitments
  • commit-reveal flows
  • hidden-state encoding interfaces
  • Merkle inclusion verification
  • sparse Merkle utilities
  • privacy interfaces:
    • CommitmentScheme
    • MerkleProofVerifier
    • HiddenStateCodec
    • ProofVerifier as an interface contract only

These are exposed through:

  • cougr_core::privacy::stable
  • cougr_core::zk::stable as the compatibility alias

Experimental Privacy Surface

The following remain Experimental:

  • Groth16 proof verification flows
  • proof-submission execution helpers
  • prebuilt verification circuits
  • fog-of-war Merkle exploration orchestration
  • multiplayer ZK state-channel transition contracts
  • recursive proof-composition descriptors
  • advanced hidden-state automation
  • hazmat Poseidon-based privacy helpers
  • broader confidential-state abstractions

These are exposed through:

  • cougr_core::privacy::experimental
  • cougr_core::zk::experimental as the compatibility alias

Compatibility note:

Experimental modules may still be re-exported from cougr_core::zk for transition convenience, but they are not part of Cougr's stable privacy promise. New application code should prefer cougr_core::privacy::experimental so the product-level intent is obvious at the import site.

1.0 Privacy Freeze

The frozen 1.0 privacy contract is exactly:

  • commitments
  • commit-reveal flows
  • hidden-state codec interfaces
  • Merkle inclusion verification
  • sparse Merkle utilities
  • the interface contracts re-exported from cougr_core::privacy::stable

The following are explicitly excluded from the 1.0 stable privacy contract:

  • zk::experimental
  • proof-submission orchestration that depends on experimental verification
  • Groth16 verifier implementations
  • prebuilt advanced circuit helpers
  • state-channel, recursive, and fog-of-war orchestration helpers

Privacy Maturity Table

SurfaceStatusNotes
CommitmentsStableExplicit interface and verification contract
Commit-revealStableExplicit component semantics and deadline behavior
Hidden-state encodingStableStable codec interface; fixed-width codecs can be defended
Merkle inclusion and sparse Merkle utilitiesStableMalformed proof behavior and inclusion semantics are explicit
Proof submission systemsBetaUseful orchestration, but still coupled to experimental verification flows
Groth16 verification and prebuilt circuitsExperimentalAssumptions are explicit, but not yet strong enough for a stable promise

Proof Verification Contract

Cougr's experimental Groth16 verifier makes these explicit guarantees:

  • verification keys must satisfy vk.ic.len() == public_inputs.len() + 1
  • malformed verification-key shape returns ZKError::InvalidVerificationKey
  • malformed pairing inputs return ZKError::InvalidInput
  • a well-formed but invalid proof returns Ok(false) only when the pairing check fails

Cougr does not currently claim stronger guarantees for Groth16 around:

  • subgroup validation beyond Soroban host-type decoding
  • normalization guarantees beyond fixed-width typed wrappers
  • broader proof-system maturity for production confidentiality claims

That is why the implementation remains Experimental even though the verifier interface is explicit.

Merkle Verification Contract

Cougr's stable Merkle verification guarantees:

  • malformed proofs with siblings.len() != depth return ZKError::InvalidProofLength
  • well-formed but non-matching proofs return Ok(false)
  • sparse Merkle utilities produce the same on-chain proof representation used by the stable SHA256 verifier

Hidden-State Encoding Contract

Stable hidden-state codecs must:

  • define an exact byte-level representation
  • reject malformed encoded state with ZKError::InvalidInput
  • avoid silent truncation or padding

The built-in Bytes32HiddenStateCodec satisfies this by requiring an exact 32-byte payload in both directions.

Relationship to Public Surface

This model works with:

Any future claim that advanced proof verification is Stable should add stronger input-validation guarantees, clearer host-assumption boundaries, and tighter negative-path coverage than exists today.

Cougr Feature Flags

Purpose

This document groups Cougr feature flags by maturity and intended usage.

Current Flags

FlagMaturityIntended useNotes
debugSupport-onlyLocal diagnostics and introspectionExposes runtime snapshots and metrics that are not part of the stable product contract
hazmat-cryptoExperimentalAdvanced ZK and cryptographic integrationsEnables low-level host crypto helpers; do not treat as part of the stable privacy promise
testutilsNon-contract support surfaceTests and explicit test-utility consumersEnables testing helpers such as MockAccount

Policy

  • feature flags do not automatically promote a surface into the stable contract
  • test-only or support-only flags remain outside compatibility guarantees
  • new security-sensitive flags should default to Beta or Experimental until their contracts are written down

Relationship To Public Surface

The maturity of the feature flag should be interpreted together with:

In the product-level facade:

  • auth mirrors the Beta accounts surface
  • privacy::stable and privacy::experimental mirror the split inside zk
  • ops mirrors the stable standards surface

Cougr Performance Guide

Purpose

This document explains the current performance model for Cougr's Soroban-first ECS path.

It is not a promise of fixed gas costs. It is a guide to the data structures and tradeoffs that determine query and scheduling behavior.

The practical question it should answer is:

  • which backend should I use
  • where should a component live
  • what kinds of mutations are cheap versus expensive

SimpleWorld Query Model

SimpleWorld now maintains direct component indexes:

  • table_index for table-backed components
  • all_index for table + sparse lookups

That changes the expected behavior of the common query paths:

  • get_table_entities_with_component() uses the direct table index
  • get_all_entities_with_component() uses the all-storage index
  • SimpleQuery selects the narrowest available required component index before filtering

This is the default performance story for gameplay loops.

Use SimpleWorld by default when:

  • your hot loop is dominated by one- or two-component scans
  • you mutate entity composition often
  • you rely on table vs sparse placement to control scan scope

Use ArchetypeWorld when:

  • your hot loop is dominated by repeated multi-component queries
  • entity compositions are relatively stable after setup
  • you are willing to pay more for add/remove migrations to get tighter query scopes

Storage Tradeoffs

Table storage:

  • optimized for repeated scans
  • should back components that appear in hot gameplay loops

Sparse storage:

  • better for infrequent markers or tags
  • excluded from table-only scans by default

If a sparse component starts showing up in tick-critical queries, it is usually a signal that the component belongs in table storage.

Prescriptive rule:

  • if you scan it every tick, it probably belongs in table storage
  • if you mostly address it directly or use it as a sparse marker, keep it sparse

Scheduler Tradeoffs

SimpleScheduler now validates stage-local dependencies before execution.

Costs introduced by the stronger model:

  • dependency validation during run planning
  • topological ordering within each stage

Benefits:

  • explicit execution order
  • early detection of invalid schedules
  • safer composition as system counts grow

This is a good trade in Soroban-oriented contracts because schedule size is typically small relative to the cost of incorrect execution order.

Benchmark Focus Areas

Benchmarks should answer these practical questions:

  • how many entities can the indexed query path scan efficiently
  • when does ArchetypeWorld outperform SimpleWorld
  • what is the cost of adding/removing indexed components
  • what is the cost of stage validation and deferred command application

The current benchmark suite in benches/ecs_bench.rs covers these paths directly.

It now includes:

  • entity spawn cost
  • component insert / lookup cost
  • indexed query vs sparse-inclusive query cost
  • cache warm-read vs invalidated-read behavior
  • scheduler validation + execution cost
  • SimpleWorld vs ArchetypeWorld multi-component query comparison
  • SimpleWorld vs ArchetypeWorld structural mutation comparison

Reading The Current Benchmarks

Interpret the benchmark output in this order:

  1. Query Paths If plain indexed queries and cached queries are already cheap enough, stay on SimpleWorld.
  2. Backend Query Comparison If ArchetypeWorld is materially better on your real multi-component query shape, it may be worth adopting.
  3. Backend Structural Mutation Comparison If archetype migration is significantly more expensive for your workload, do not switch just because query numbers look better in isolation.
  4. Query Cache Invalidation If your world mutates every tick, cache benefits may collapse; optimize data shape first.

Decision Heuristics

Choose SimpleWorld when:

  • gameplay writes are frequent
  • entity compositions change often
  • table/sparse separation gives you enough control
  • your queries are broad but predictable

Choose ArchetypeWorld when:

  • the same multi-component query runs constantly
  • compositions are mostly fixed after startup
  • entity migration cost is amortized over many reads

Keep GameApp, SimpleWorld, and SimpleQuery as the default performance story for new Soroban gameplay code.

Interpretation Rules

Use benchmark output to compare patterns, not to claim universal throughput numbers.

For real contracts, evaluate:

  • data shape
  • component cardinality
  • table vs sparse placement
  • how often the world mutates between repeated queries

Performance guidance should always be tied back to those conditions.

If benchmark results and your data shape disagree, trust the data shape first.

Cougr Public API Contract

Purpose

This document defines how Cougr presents its public Rust API for 1.0.

It answers four practical questions:

  • which entrypoints are central to the product
  • which surfaces are usable but still evolving
  • which modules should not be interpreted as production commitments
  • which compatibility shims or testing helpers are intentionally outside the long-term contract

API Positioning

Cougr exposes a broad crate surface, but only a scoped subset is part of the defended 1.0 contract.

The current product story is:

  • cougr-core is primarily an ECS framework for Soroban-compatible applications
  • app is the default gameplay runtime surface for new projects
  • auth, privacy, and ops are the clearest product-level domain namespaces
  • accounts remain Beta, while privacy is split between a stable primitive subset and experimental proof systems
  • ECS onboarding/runtime surfaces and standards are part of the 1.0 stable contract
  • helper APIs that exist only for compatibility or transition should remain clearly demoted

This file now serves as the explicit 1.0 stable API list for cougr-core.

Core entrypoints

These are the frozen entrypoints for the 1.0 stable contract:

  • SimpleWorld
  • ArchetypeWorld
  • ecs::{RuntimeWorld, RuntimeWorldMut, WorldBackend}
  • typed and raw component operations
  • command queues
  • scheduling primitives
  • events, hooks, and observers
  • incremental persistence utilities

Concrete frozen root-level contract:

  • SimpleWorld
  • ArchetypeWorld
  • CommandQueue
  • Component, ComponentTrait, ComponentStorage, ComponentId
  • SimpleQuery, SimpleQueryBuilder
  • RuntimeWorld, RuntimeWorldMut, WorldBackend
  • Resource
  • runtime::ChangeTracker, runtime::TrackedWorld
  • Plugin, PluginGroup, GameApp
  • ScheduleStage, SystemConfig, SimpleScheduler, SystemGroup
  • prelude
  • runtime
  • app
  • ops as the clearest Stable standards namespace
  • standards as a Stable namespace
  • privacy::stable as the clearest stable privacy namespace
  • zk::stable as the stable privacy namespace
  • auth as the clearest Beta account namespace
  • accounts as a Beta namespace
  • privacy::experimental as an explicitly non-contract namespace
  • zk::experimental as an explicitly non-contract namespace

Supported but evolving surfaces

These surfaces are useful and implemented, but should continue to be presented as Beta:

  • accounts
  • higher-level query helpers
  • higher-level scheduler helpers
  • proof-submission helpers in zk

Stable privacy subset

These privacy surfaces are intentionally narrower and can be presented as Stable:

  • commitments
  • commit-reveal
  • hidden-state codec interfaces
  • Merkle inclusion and sparse Merkle utilities
  • zk::stable

Non-contract surfaces

These surfaces are public today, but they must not be interpreted as stable commitments:

  • testing-only helpers
  • advanced proof-verification APIs whose assumptions are still being hardened
  • zk::experimental
  • compatibility shims retained for transition
  • internals-heavy modules whose invariants are not yet documented as stable guarantees

Top-Level Surface in src/lib.rs

Public modules

Current top-level modules:

  • app
  • auth
  • accounts
  • archetype_world
  • commands
  • component
  • debug behind feature flag
  • error
  • event
  • ops
  • privacy
  • plugin
  • query
  • resource
  • scheduler
  • simple_world
  • zk

Internal implementation modules such as hidden scheduler helpers, storage internals, and entity internals are no longer part of the intended default public surface. They may still exist in the repository, but the root crate is not meant to advertise them as onboarding entrypoints. Advanced runtime support such as hooks, observers, change tracking, and incremental storage is exposed through curated re-exports and runtime instead of direct top-level module entrypoints.

Public re-exports

Current top-level re-exports emphasize:

  • worlds: SimpleWorld, ArchetypeWorld
  • backend contracts: RuntimeWorld, RuntimeWorldMut, WorldBackend
  • ECS data: Component, ComponentId, ComponentStorage, ComponentTrait, Position, Resource
  • orchestration: CommandQueue, GameApp, schedulers
  • queries: SimpleQuery, SimpleQueryBuilder
  • domain access through explicit namespaces: auth, privacy, ops, accounts, zk::stable, zk::experimental

Public top-level helper functions

There are no root-level placeholder helper functions in the supported contract.

The sanctioned onboarding path is the curated root surface itself:

  • app
  • auth
  • privacy
  • ops
  • SimpleWorld
  • ArchetypeWorld
  • CommandQueue
  • GameApp
  • app::{named_system, named_context_system} and add_systems

Compatibility Exceptions

Public API Risks

The main public API risks before this cleanup were:

  • the crate exports more surface area than it can reasonably defend as stable
  • some internals-heavy modules are public before their long-term contract is clearly documented
  • some privacy and verification surfaces are easy to overread as production guarantees
  • accounts and privacy modules still include beta-grade behavior that is intentionally documented outside the stable story

Freeze Direction

The 1.0 freeze is intentionally narrower than the full public module graph:

  • app is the clearest default runtime namespace for new gameplay code
  • auth is the clearest Beta auth namespace for application code
  • privacy is the clearest domain namespace for privacy adoption, with stability determined by submodule
  • ops is the clearest stable namespace for operational standards in application code
  • root re-exports and prelude are the default onboarding path
  • runtime is the supported namespace for advanced ECS integrations that are not part of the smallest onboarding contract
  • query and archetype_world retain their cache/state helpers outside the smallest root onboarding surface
  • standards is a supported stable namespace
  • accounts remains a public Beta namespace
  • zk::stable is the only privacy namespace treated as Stable
  • zk::experimental remains public for explicit opt-in use, but outside compatibility guarantees

Cougr Compatibility Promises

Purpose

This document defines the compatibility story Cougr is prepared to defend at 1.0.

It turns the maturity model into explicit expectations for adopters, contributors, and maintainers.

1.0 Baseline

Cougr 1.0.0 freezes a scoped stable surface inside a broader public crate.

That means:

  • compatibility promises are scoped by maturity, not by visibility alone
  • stable, beta, and experimental namespaces can coexist in the same crate
  • the stable guarantee is the documented contract, not every public symbol

Stable Surfaces

The following surfaces are treated as Cougr's strongest 1.0 compatibility commitments:

  • root ECS onboarding and runtime entrypoints documented in API_CONTRACT.md
  • prelude
  • runtime
  • ops
  • standards
  • privacy::stable
  • zk::stable
  • the contracts documented in PRIVACY_MODEL.md for commit-reveal, hidden-state codecs, and Merkle verification

For these surfaces, maintainers should preserve:

  • type and function intent unless there is a documented breaking reason
  • documented failure behavior
  • documented malformed-input behavior where applicable
  • byte-level or proof-shape contracts already written in the privacy model

Beta Surfaces

The following surfaces are supported but intentionally not frozen:

  • higher-level ECS helpers outside the frozen root/runtime contract
  • auth
  • accounts
  • proof-submission orchestration that depends on experimental verification flows

For Beta surfaces, maintainers commit to:

  • keep the product direction coherent
  • document meaningful semantic changes
  • avoid gratuitous churn
  • preserve the curated onboarding path where practical

For Beta surfaces, maintainers do not yet promise:

  • SemVer-stable signatures
  • unchanged storage layouts for every helper
  • unchanged auth or orchestration semantics across all releases

Experimental Surfaces

The following surfaces are explicitly outside compatibility guarantees:

  • privacy::experimental
  • zk::experimental
  • hazmat cryptographic helpers
  • advanced proof-verification helpers and descriptors
  • any public support surface documented as test-only or transition-only

These may:

  • change shape
  • move namespace
  • be removed
  • gain stronger validation that changes edge-case behavior

Non-Contract Support Surfaces

Support-only surfaces such as MockAccount are not part of the default product contract.

They exist for tests and explicit utility consumers, not as long-term framework guarantees.

Change Management Rules

When changing a Stable or Beta public surface, update at minimum:

1.0 Freeze Decisions

The 1.0 release gate decisions are:

  • ECS onboarding and runtime surfaces are in the stable contract
  • ops is the stable domain alias for standards
  • standards is in the stable contract
  • auth is a Beta domain alias and is not part of the stable guarantee
  • accounts remains Beta and is not part of the stable guarantee
  • privacy::stable maps to the frozen privacy contract
  • zk::stable is the frozen privacy contract
  • privacy::experimental remains outside compatibility guarantees
  • zk::experimental remains outside compatibility guarantees

Migration Guide

Purpose

This guide explains how to move existing Cougr integrations toward the curated 1.0 product surface.

It is not a promise that every older pattern disappears immediately. It is the recommended direction for users who want to converge on the defended path.

Core Direction

Prefer these namespaces in new or updated code:

  • app for gameplay runtime
  • auth for account and session flows
  • privacy::stable for stable privacy primitives
  • ops for operational standards

Runtime Migration

From direct world/scheduler wiring

If you currently do something like:

#![allow(unused)]
fn main() {
let mut world = SimpleWorld::new(&env);
let mut scheduler = SimpleScheduler::new();
}

prefer:

#![allow(unused)]
fn main() {
let mut app = cougr_core::app::GameApp::new(&env);
}

and register systems through GameApp.

When multiple systems belong to the same phase, prefer the declarative path:

#![allow(unused)]
fn main() {
use cougr_core::app::{named_context_system, named_system, GameApp, ScheduleStage};

let mut app = GameApp::new(&env);
app.add_systems((
    named_system("spawn", |world, env| {
        let entity = world.spawn_entity();
        world.set_typed(env, entity, &Position::new(0, 0));
    })
    .in_stage(ScheduleStage::Startup),
    named_context_system("cleanup_tags", |context| {
        let entities = context
            .world()
            .get_entities_with_component(&symbol_short!("expired"), context.env());
        for i in 0..entities.len() {
            let entity = entities.get(i).unwrap();
            context
                .commands()
                .remove_component(entity, symbol_short!("expired"));
        }
    })
    .in_stage(ScheduleStage::Cleanup),
));
}

Why:

  • clearer lifecycle
  • explicit stages
  • one onboarding surface instead of several loose primitives
  • a single system registration model for plain and context-aware systems

From the removed pre-1.0 ECS model

If you were previously on the removed pre-1.0 World / System path, port directly to GameApp, SimpleWorld, and SimpleQuery.

Query Migration

If you still do ad-hoc scans or manual component filtering, prefer:

  • SimpleQueryBuilder
  • SimpleQueryState
  • SimpleQueryCache

Both SimpleQueryBuilder and ArchetypeQueryBuilder now support:

  • with_components(...)
  • without_components(...)
  • with_any_components(...)

If you need backend-agnostic gameplay helpers across Soroban-first worlds, prefer:

  • RuntimeWorld
  • RuntimeWorldMut

These are the shared contracts between SimpleWorld and ArchetypeWorld.

Domain Migration

Accounts

If you currently import from accounts directly in application code:

#![allow(unused)]
fn main() {
use cougr_core::accounts::SessionBuilder;
}

prefer:

#![allow(unused)]
fn main() {
use cougr_core::auth::SessionBuilder;
}

The semantics are the same today. The change is about product clarity.

Privacy

If you rely on stable privacy primitives, prefer:

#![allow(unused)]
fn main() {
use cougr_core::privacy::stable::...
}

instead of:

#![allow(unused)]
fn main() {
use cougr_core::zk::stable::...
}

If you rely on advanced proof tooling, prefer:

#![allow(unused)]
fn main() {
use cougr_core::privacy::experimental::...
}

and treat it as an explicit opt-in to non-frozen APIs.

Standards

If you currently import standards directly:

#![allow(unused)]
fn main() {
use cougr_core::standards::Pausable;
}

prefer:

#![allow(unused)]
fn main() {
use cougr_core::ops::Pausable;
}

Again, this is a namespace migration for clarity, not a semantic rewrite.

Example-Level Migration

Use these examples as references:

  • snake for app::GameApp and stage-based gameplay loops
  • battleship for privacy::stable and hidden-information patterns
  • guild_arena for account/session/recovery patterns

What Does Not Need Immediate Migration

You do not need to rewrite everything at once if:

  • the contract still needs a focused port from the removed pre-1.0 runtime path
  • you are preserving an older example or integration
  • your current code already sits behind a stable local abstraction

The main goal is to stop growing new code on top of older default imports.

Migration Checklist

  • move runtime entrypoints to app where practical
  • move account imports to auth
  • move stable privacy imports to privacy::stable
  • move standards imports to ops
  • update local docs/examples to use the curated namespaces

CLI Reference

This page does not exist yet because the cougr-cli crate does not exist yet.

Per docs/strategy/12-documentation-architecture.md: "CLI reference — Does not exist because the CLI does not exist yet; ships alongside it."

When the CLI ships, this page will document all cougr new, cougr add, and cougr check subcommands.

Tracked in: salazarsebas/Cougr issues

Client SDK Reference

This page does not exist yet because the TypeScript client SDK does not exist yet.

Per docs/strategy/12-documentation-architecture.md: "Client SDK reference — Ships alongside the SDK described in 06-product-strategy.md."

When the SDK ships, this page will document the TypeScript API for connecting a frontend to a Cougr game contract, including wallet integration and session key management.

Tracked in: salazarsebas/Cougr issues

Architecture Decision Records

Architecture Decision Records (ADRs) document significant technical decisions made in Cougr's design. They are kept in the main salazarsebas/Cougr repository under docs/adr/ and synced here automatically.

Each ADR follows the format: context → decision → consequences.

ADRTitle
0001Public API Surface
0002Accounts Beta
0003Privacy Model Split
0004Standards Layer Stable
0006Game Circuit Suite
0007Workspace Subcrates

Showcase

The showcase gallery generator is a separate epic. This page reserves its place in the navigation.


The Showcase is a live directory of games and demos built with Cougr. It will be generated automatically from the examples/ directory in the main repository and from community submissions.

Examples in the core repository

ExampleDescriptionComplexity
spawn_and_moveCanonical hello-world: spawn a player, walk in four directionsStarter
tic_tac_toeTurn-based two-player game; rich component demonstrationIntermediate
murdokuFull game with a client frontendAdvanced

Submit your game

Once the showcase gallery is built, you'll be able to submit your Cougr game for a "Cougr Verified" badge by opening a PR to this repository.

Check back soon — or watch the repository.

Example Gallery

This page will be auto-generated. The gallery generator is tracked as a separate epic.

See the Showcase index for an overview of currently known examples.

Design

This section is being built. All design documents are gaps identified in docs/strategy/12-documentation-architecture.md and will be produced alongside the design system rollout.


The Design section contains guidelines for anyone building a client application against Cougr, contributing visual work, or working on the docs site itself.

GuideStatus
Branding Guide🔜 Coming soon
UI Guidelines🔜 Coming soon
UX Guidelines🔜 Coming soon
Accessibility🔜 Coming soon

Branding Guide

This page is being written.

Will cover: logo usage, color palette, typography, design tokens, and the "Cougr Verified" badge. Full specification in docs/strategy/09-design-strategy.md in the main repository.

UI Guidelines

This page is being written.

Will cover UI patterns for building a client application against a Cougr game contract. The murdoku frontend in the main repo is the first worked reference this guide will draw from.

UX Guidelines

This page is being written.

Will cover player-facing UX patterns — wallet connection, session key UX, and transaction feedback — distinct from the developer UX covered in the Learn section.

Accessibility

This page is being written.

Will cover accessibility requirements for both this documentation site and for client applications built on Cougr. Currently unaddressed anywhere in the project — flagged in docs/strategy/12-documentation-architecture.md.

Community

Welcome to the Community section. This is where you'll find everything about how to contribute, how decisions are made, and how to stay up to date.

DocumentDescription
ContributingHow to open issues, write code, and get PRs merged
Code of ConductExpected behaviour in all project spaces
GovernanceHow decisions are made, who can merge, how disputes are resolved
SecurityHow to report vulnerabilities
RoadmapWhere the project is headed
RFC ProcessHow to propose significant changes before implementing them
ChangelogWhat changed in each release

Contributing

Contributions should improve the framework, the example catalog, or the supporting documentation with a clear purpose. This repository is structured to be useful both as a reusable library and as a reference codebase, so changes should optimize for correctness, clarity, and maintainability.

Scope

Good contributions typically fall into one of these categories:

AreaExpected outcome
Core frameworkImproved ECS, scheduling, storage, authorization, or zero-knowledge capabilities
ExamplesNew game patterns, better reference implementations, or tighter example documentation
DocumentationClearer architecture, setup, or usage guidance aligned with the current codebase
QualityBetter tests, tooling, validation, or CI coverage

Development Standards

  • Keep changes focused. Avoid mixing unrelated refactors with feature work.
  • Update documentation when behavior, structure, or public APIs change.
  • Prefer clear names and straightforward control flow over clever abstractions.
  • Preserve repository consistency. New files should fit the existing layout and conventions.
  • Do not add generated reports, ad hoc summaries, or temporary planning documents to the repository root.

Local Validation

Run the relevant checks before opening a pull request:

cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test

If you modify an example project, also run that example's local checks from its own directory. If the example supports Soroban contract builds, validate that flow as well.

Documentation Expectations

Documentation should be professional, current, and proportionate:

  • avoid stale exact counts when the repository is expected to grow
  • explain decisions and usage patterns without turning every page into a long-form essay
  • use tables when they improve scanability, not as a default for all content
  • keep root-level documentation limited to material with clear long-term value
  • follow the terminology and voice rules in docs/VOICE_GUIDE.md for all doc, example, and marketing copy

Pull Requests

Pull requests should make it easy to review technical intent. A strong PR description usually covers:

  1. what changed
  2. why the change was needed
  3. how it was validated
  4. any follow-up work or constraints reviewers should know about

Adding Examples

When adding a new example:

  • make the example self-contained
  • include a local README.md
  • keep the example focused on one or two clear patterns
  • add CI coverage when the example is meant to remain a maintained reference

Review Criteria

Changes are more likely to be accepted when they:

  • solve a real problem in the framework or examples
  • keep the API and repository structure coherent
  • include appropriate validation
  • improve the repository without increasing maintenance noise

Public API Checklist

Changes that touch public Rust APIs should be reviewed against this checklist before merge:

  • the symbol belongs to the curated onboarding path or an intentional namespace such as accounts, zk::stable, or zk::experimental
  • stable, beta, experimental, and test-only surfaces are not mixed in the same default entrypoint
  • new public names do not duplicate an existing public concept
  • root-level re-exports are intentional and minimal
  • examples and integration tests use the sanctioned public path instead of deep internal module paths
  • documentation is updated to match the actual exported API

Code of Conduct

⚠️ This document is an urgent gap identified in docs/strategy/12-documentation-architecture.md: "Missing despite 25+ active external contributors. Should be added immediately, independent of any other work in this package — this is a near-zero-cost fix for a real, present governance gap."

Tracked in: salazarsebas/Cougr issues


A Code of Conduct will be added here imminently. It will be based on the Contributor Covenant and apply to all project spaces including GitHub Issues, Pull Requests, and any community channels.

Governance

This page is being written.

Identified as a gap in docs/strategy/12-documentation-architecture.md. No documented decision-making process exists yet.


Will cover:

  • Who can merge pull requests
  • How disputes over public API changes are resolved
  • How maintainer status is granted and revoked
  • The relationship between the existing CONTRIBUTING.md Public API Checklist and final authority on API decisions

Tracked in: salazarsebas/Cougr issues

Security Policy

Status

Cougr now defines a 1.0.0 stable contract for a scoped subset of the crate. Not every public subsystem is part of that stable guarantee.

Security-sensitive areas include:

  • account authorization
  • session lifecycle and replay protection
  • persistent storage integrity
  • proof verification and privacy primitives
  • ECS mutation ordering where authorization depends on state transitions

Maturity and Guarantees

Current guidance:

AreaStatusGuidance
ECS runtime and storageStablePart of the 1.0 contract when used through the documented onboarding and runtime surfaces
Accounts and smart-account flowsBetaDo not assume full production guarantees without project-specific review
Standards layer (standards)StableReusable contract primitives are part of the 1.0 stable contract
Privacy primitives (zk::stable)StableCommit-reveal, hidden-state codecs, and Merkle utilities are the stable privacy contract
Advanced ZK verificationExperimentalTreat as non-stable until verification contracts and assumptions are fully hardened

The latest maturity definitions live in docs/MATURITY_MODEL.md. The current threat-model baseline lives in docs/THREAT_MODEL.md. The explicit compatibility story lives in docs/COMPATIBILITY_PROMISES.md.

Threat Model Expectations

Cougr does not currently claim:

  • external audit coverage
  • formal verification
  • full production guarantees across all auth and privacy paths
  • stable compatibility guarantees for experimental modules

Before adopting Cougr in security-critical deployments, review at minimum:

  • auth and signer flows
  • replay handling
  • session scope and revocation rules
  • storage schema assumptions
  • proof verification assumptions

Reporting a Vulnerability

If you find a security issue:

  1. Do not open a public issue with exploit details.
  2. Report the issue privately to the project maintainers.
  3. Include:
    • affected module
    • reproduction steps
    • impact assessment
    • version or commit information
    • suggested mitigation if available

Until a dedicated security contact is published, use the maintainer channels associated with this repository and clearly label the report as a security disclosure.

Supported Versions

The latest stable release line and current mainline development state should be assumed relevant for fixes unless a maintenance policy says otherwise.

Secure Contribution Expectations

Changes affecting auth, privacy, storage, or unsafe internals should include:

  • updated invariants or trust assumptions
  • negative-path tests
  • compatibility notes when public behavior changes
  • documentation changes when guarantees or maturity shift

Roadmap

This page is being written.

No ROADMAP.md exists in the main repository yet. Per docs/strategy/12-documentation-architecture.md: "Should be a public, living version of 13-roadmap.md, updated quarterly, not a one-time publish."


The public roadmap will be maintained here once established. It will track:

  • Near-term: cougr-cli (cougr new, cougr add, cougr check)
  • Medium-term: TypeScript client SDK, resource-cost reporting in test harness
  • Long-term: Visual editor, showcase gallery, hosted-service option

Tracked in: salazarsebas/Cougr issues

RFC Process

This page is being written.

The ADR practice (docs/adr/) covers internal architecture decisions well. An RFC process is the public-facing counterpart for changes the community should weigh in on before they happen.

Per docs/strategy/12-documentation-architecture.md: "Recommend adopting a lightweight RFC template modeled directly on the existing ADR format, since the team already has the discipline to use it well."


When the RFC process is established it will cover:

  • What kinds of changes require an RFC (public API changes, new primitives, breaking changes)
  • The RFC template (based on the existing ADR format)
  • How to submit, how long the comment period is, and who has final say

Tracked in: salazarsebas/Cougr issues

Changelog

Unreleased

Added

  • cougr-cli — new workspace member publishing the cougr binary
  • cougr new <name> [--template <name>] — scaffolds a Soroban game contract crate following the canonical lib.rs / components.rs / systems.rs layout, with a passing test::GameHarness suite and a dependency on the published cougr-core release rather than a path dependency
  • Four embedded templates, each derived from a canonical example and compiled into the binary so cougr new works offline: starter (spawn_and_move), turn-based (tic_tac_toe), hidden-info (hidden_hand), session-auth (session_arena)
  • CLI CI workflow — lints and tests cougr-cli, then generates each template and runs cargo fmt, clippy, cargo test, and a wasm32v1-none release build against it

1.1.0

Added

  • game::SorobanGame trait — standard load_world / save_world contract pattern; implement once with impl_soroban_game!(Contract, "key"), use in every entrypoint
  • impl_soroban_game! macro — wires SorobanGame to any #[contract] struct
  • SimpleWorld::load_from_instance — load world from Soroban instance storage, returning a fresh empty world on first call
  • SimpleWorld::save_to_instance — persist world to Soroban instance storage
  • SimpleWorld::set_rich_observed — store a rich component and emit a RichComponentChangedEvent for off-chain indexers
  • SimpleWorld::remove_rich_observed — remove a rich component and emit a del event
  • RichComponentChangedEvent — new Soroban event type with topics ("COUGR", "rich", component_type) for rich component change notifications
  • spawn_and_move example — canonical Cougr starter game demonstrating the complete idiomatic pattern: impl_component_observed! + SorobanGame + typed ECS access
  • SorobanGame re-exported from prelude — import from cougr_core::prelude::*
  • cougr_core::circuits — four pre-built ZK game builders (hidden cards, fog of war, fair dice, sealed bid) with pipeline-embedded verification keys
  • cougr_core::sessionSessionManager, SessionStatus, and ActiveSession (Beta)
  • cougr_core::testGameHarness, Scenario, and ReplayLog sandbox behind the testutils feature
  • Circom pipelineinternal/cougr-core-circuits with CI workflow and on-chain Groth16 proof verification using real VKs
  • ZK exampleshidden_hand, fog_explorer, dice_duel, and blind_auction
  • Workspace subcratesinternal/cougr-core-{circuits,session,test} per ADR 0007

Changed

  • tic_tac_toe example modernised: replaced ~200 lines of manual serialization with impl_rich_component! for Board and Players, and impl_soroban_game! for load/save. Public API is unchanged; all existing tests pass
  • README rewritten with clean 30-line quick start and full feature documentation
  • canonical example set expanded from three (snake, battleship, guild_arena) to ten: spawn_and_move (Starter), tic_tac_toe (Rich components), session_arena (Session UX), hidden_hand, fog_explorer, dice_duel, blind_auction (ZK circuits), snake (Arcade/GameApp), battleship (Hidden information), guild_arena (Auth & recovery)
  • session_arena example added as canonical reference for session::SessionManager

Stability Notes

  • game::SorobanGame is Stable
  • SimpleWorld::load_from_instance / save_to_instance are Stable
  • set_rich_observed / remove_rich_observed are Stable
  • RichComponentChangedEvent is Stable
  • cougr_core::session is Beta
  • cougr_core::circuits and embedded test VKs are Experimental
  • cougr_core::test is Experimental (testutils only)

1.0.0

Added

  • app as the default gameplay runtime surface
  • auth, privacy, and ops as product-level domain namespaces
  • RuntimeWorld and RuntimeWorldMut as shared Soroban-first backend contracts
  • stronger stage scheduling with ordering, sets, and validation
  • SimpleQueryBuilder, query state/cache improvements, and richer ArchetypeWorld query helpers
  • expanded benchmark coverage for backend comparisons and cache invalidation behavior

Changed

  • the recommended onboarding path is now app::GameApp + SimpleWorld + SimpleQueryBuilder
  • canonical examples now emphasize the curated runtime story and explicit maturity boundaries
  • battleship now uses stable privacy primitives from zk::stable
  • documentation now treats SimpleWorld and ArchetypeWorld as the defended Soroban-first backends

Stability Notes

  • Stable: ECS onboarding/runtime contract, app, ops, standards, privacy::stable, zk::stable
  • Beta: auth, accounts, game_world
  • Experimental: privacy::experimental, zk::experimental, hazmat cryptographic helpers

Upgrade Notes

  • Prefer app over wiring scheduler/world primitives directly for new gameplay code
  • If you still have pre-1.0 code built around removed runtime abstractions, port directly to GameApp, SimpleWorld, and SimpleQuery
  • Prefer ops, privacy, and auth in application code when you want domain-oriented imports
  • Treat root-level advanced re-exports as compatibility/advanced surfaces rather than the default learning path
  • See docs/MIGRATION_GUIDE.md for concrete migration mappings