Repository Structure and Workspace Layout
This page maps every top-level directory and configuration file in the Portal OS repository so you can navigate confidently from day one. Portal OS is a large, multi-language monorepo: the bulk of the code is Rust organized as a Cargo workspace, with C/C++ for Wayfire plugins and streaming, Python/shell for deployment automation, and a Unity project for the AR glasses receiver. Understanding the layout before touching code prevents the most common beginner mistakes, building the wrong crate, editing a generated file, or looking for Rust where there is only C.
Root-Level Project Metadata
Section titled “Root-Level Project Metadata”The repository root holds the workspace manifest, toolchain pins, and the legal/governance files that apply to the entire project. Every crate and subsystem inherits from these settings.
[workspace]resolver = "2"members = [ "portal/spatial", "portal/spatial-plugin", ... ]The root Cargo.toml defines 30 workspace members grouped into six subsystems: core compositor, shared utilities, input/streaming, the PCP (Portal Capability Protocol) subsystem, the context/LLM layer, and the NPU runtime. It also declares a shared dependency pool under [workspace.dependencies] so that every crate uses identical versions of tokio, serde, tracing, and dozens of other crates, this prevents version drift and keeps the lockfile clean.
The [workspace.package] block sets project-wide metadata: the Demain Source License V2.2, edition = "2021", rust-version = "1.97.0", and publish = false (no crates are published to crates.io). The [workspace.lints.clippy] section is unusually thorough, it promotes correctness, suspicious, style, complexity, perf, and pedantic all to deny, and additionally denies unwrap_used, expect_used, and panic_in_result_fn in production code. Each crate opts in by adding lints.workspace = true in its [package] section.
Toolchain and Cross-Compilation Pins
Section titled “Toolchain and Cross-Compilation Pins”| File | Purpose |
|---|---|
rust-toolchain.toml |
Pins Rust 1.97.0 with rustfmt, clippy, and rust-src components |
.cargo/config.toml |
Sets the aarch64-linux-gnu-gcc linker for ARM64 cross-compilation |
Cross.toml |
Configures cross-rs Docker images for aarch64 and armv7 targets |
clippy.toml |
MSRV = 1.97.0, excessive-nesting threshold = 250, too-many-lines threshold = 250 |
deny.toml |
cargo-deny configuration: license allowlist, advisory ignores, supply-chain rules |
The primary target is aarch64-unknown-linux-gnu because the Portal OS hardware runs a X Elite (ARM64). The .cargo/config.toml wires the GNU cross-linker, while Cross.toml provides Docker-based cross-compilation images for CI environments that lack the native toolchain.
Workspace Crate Map
Section titled “Workspace Crate Map”The following Mermaid diagram shows how the 30 workspace crates relate to each other, organized by functional subsystem. Arrows point from a crate toward the crates it depends on (import direction). Read the diagram top-to-bottom: the top row is the compositor surface, the middle row is application services, and the bottom row is shared infrastructure.
flowchart TD
subgraph Compositor
SPATIAL[portal-spatial]
PLUGIN[portal-spatial-plugin]
WARP[portal-warp]
WM[portal-wm]
end
subgraph Input & Streaming
INPUT[portal-input]
STREAM[portal-stream]
end
subgraph Application Framework
SHELL[portal-shell]
STYLE[portal-style]
LAUNCHER[portal-launcher]
LAUNCHERD[portal-launcherd]
CONTEXT[portal-context]
end
subgraph PCP Subsystem
PCP_CORE[pcp-core]
PCP_REG[pcp-registry]
PCP_DAEMON[pcp-daemon]
PCP_IPC[pcp-ipc]
PCP_CLI[pcp-cli]
end
subgraph Voice & AI
VOICE[portal-voice]
LLM[portal-llm]
NPU[portal-npu-runtime]
end
subgraph Shared
COMMON[portal-common]
end
PLUGIN --> SPATIAL
SPATIAL --> COMMON
WARP --> SPATIAL
WM --> COMMON
INPUT --> COMMON
STREAM --> COMMON
PCP_DAEMON --> PCP_CORE
PCP_DAEMON --> PCP_REG
PCP_DAEMON --> PCP_IPC
PCP_CLI --> PCP_IPC
PCP_REG --> PCP_CORE
VOICE --> NPU
CONTEXT --> LLM
SHELL --> STYLE
LAUNCHER --> COMMON
The crate catalog below lists every workspace member by name, path, crate type, and role:
| Crate Name | Path | Type | Role |
|---|---|---|---|
portal-spatial |
portal/spatial |
rlib + cdylib |
Spatial domain model: zones, dimensions, homography math |
portal-spatial-plugin |
portal/spatial-plugin |
cdylib |
Wayfire plugin entry point (loads into compositor process) |
portal-warp |
portal/warp |
cdylib |
Homography-based head-tracking warp renderer |
portal-wm |
portal/wm |
bin |
Window manager daemon, tracks Wayland toplevels via IPC |
portal-common |
portal/common |
rlib |
Shared error types, utilities, test infrastructure |
portal-input |
portal/input |
rlib |
Fusion engine: touch tracking, intent classification, virtual input |
portal-stream |
portal/stream |
rlib |
RTP packetization and HMAC-SHA256 stream authentication |
portal-launcher |
portal/launcher |
rlib |
Universal launcher: action registry, fuzzy search, desktop entry parsing |
portal-launcherd |
portal/launcherd |
bin |
Launcher daemon process |
portal-shell |
portal/shell |
rlib |
Shell interface for spatial application management |
portal-style |
portal/style |
rlib |
Design token system and theming (highest minor version at 0.4.0) |
portal-voice |
portal/voice |
rlib |
Voice pipeline: VAD, STT, NLU, TTS (highest minor version at 0.5.0) |
rnnoise-sys |
portal/voice/rnnoise-sys |
rlib |
FFI bindings to RNNoise denoiser C library |
qnn-sys |
portal/voice/qnn-sys |
rlib |
FFI bindings to Qualcomm Neural Network (QNN) SDK |
pcp-core |
portal/pcp/core |
rlib |
Core types, traits, error definitions for Portal Capability Protocol |
pcp-registry |
portal/pcp/registry |
rlib |
Capability registration and discovery |
pcp-ipc |
portal/pcp/ipc |
rlib |
IPC framing protocol for PCP daemon communication |
pcp-daemon |
portal/pcp/daemon |
bin |
PCP daemon process |
pcp-cli |
portal/pcp/cli |
bin |
Command-line interface to the PCP daemon |
portal-context |
portal/context |
rlib |
Context engine: event ingestion, decision making, template synthesis |
portal-llm |
portal/llm |
rlib |
On-device LLM integration layer |
portal-npu-runtime |
portal/npu-runtime |
rlib |
Safe Rust wrappers for Qualcomm Hexagon FastRPC |
portal-benches |
benches |
bench |
Criterion benchmarks for hot paths (IPC, RTP, TTS) |
The PCP subsystem alone contains 16 crates spanning core types, registry, AT-SPI2 integration, native bindings, push notifications, stream relay, platform abstraction, Wine interop, a simulator, CLI, IPC, daemon, learning, recovery, coordination, and inspection, each in its own subdirectory under portal/pcp/.
The portal/ Directory, Runtime Code
Section titled “The portal/ Directory, Runtime Code”The portal/ directory is the heart of the repository. It contains all Rust workspace crates alongside the C/C++ streaming pipeline, Wayfire plugins, deployment artifacts, and operational configuration. The following diagram shows the top-level organization:
portal/├── spatial/ # Spatial domain model (Rust cdylib + rlib)├── spatial-plugin/ # Wayfire spatial plugin (Rust cdylib)├── warp/ # Spatial warp rendering (Rust cdylib)├── wm/ # Window manager daemon (Rust binary)├── common/ # Shared utilities (Rust rlib)├── input/ # Input handling, fusion engine (Rust rlib)├── stream/ # RTP/streaming pipeline (Rust rlib)├── launcher/ # App launcher library (Rust rlib)├── launcherd/ # Launcher daemon (Rust binary)├── shell/ # Shell interface (Rust rlib)├── style/ # Design token system (Rust rlib)├── voice/ # Voice pipeline: VAD/STT/NLU/TTS (Rust rlib)├── pcp/ # Portal Capability Protocol (16 Rust crates)│ ├── core/ registry/ ipc/ daemon/ cli/│ ├── atspi2/ native/ push/ stream/│ ├── platform/ wine/ simulator/│ ├── learning/ recovery/ coordination/ inspection/├── context/ # Context engine (Rust rlib)├── llm/ # On-device LLM integration (Rust rlib)├── npu-runtime/ # Hexagon FastRPC wrappers (Rust rlib)├── streaming/ # Main streaming pipeline (C / GStreamer)├── wayfire-plugins/ # C++ shims for Wayfire compositor (CMake)├── compositor/ # Compositor configuration files├── protocols/ # Wayland protocol XML definitions├── network/ # the wireless AP / the DHCP server / NetworkManager configs├── systemd/ # Systemd service unit files (.service)├── apparmor/ # AppArmor security profiles├── scripts/ # Build and deployment shell scripts├── bin/ # Executable helper scripts├── config/ # Example configuration files├── android/ # Android receiver application source└── docs/ # Architecture and operations documentationEach Rust crate directory follows the standard Cargo layout: src/ for source code, tests/ for integration tests, benches/ for Criterion benchmarks, fuzz/ for cargo-fuzz targets (in select crates), and a Cargo.toml manifest. Every manifest inherits workspace settings via .workspace = true for license, edition, Rust version, authors, and lints.
Non-Rust Code Inside portal/
Section titled “Non-Rust Code Inside portal/”Three directories contain compiled code that is not part of the Cargo workspace:
The portal/streaming/ directory holds the primary streaming pipeline written in C, portal_stream.c is the entry point, with HMAC utilities in hmac_util.c/h, protocol headers generated from Wayland XML (wlr-export-dmabuf-protocol.c, xdg-shell-protocol.c), and a Makefile + build.sh for compilation. This C pipeline runs separately from the Rust streaming crate and handles DMA-BUF capture through GStreamer to hardware-encoded H.265 over RTP/UDP.
The portal/wayfire-plugins/ directory contains C++ CMake projects, thin shim plugins (portal-spatial, portal-spatial-warp, portal-virtual-output) that load into the Wayfire compositor process and call into the Rust cdylib crates via FFI. The CMakeLists.txt orchestrates the build, and portal-spatial-config.h defines compile-time configuration constants.
Deployment and Operations Artifacts
Section titled “Deployment and Operations Artifacts”Portal OS ships as a systemd service tree on the Portal OS hardware. The deployment artifacts live in three directories under portal/:
The portal/systemd/ directory contains 23 unit files and configuration templates. Key services include portal.service (the umbrella unit), portal-wm.service (window manager daemon), portal-input.service (input handler), portal-stream.service (streaming pipeline), portal-voice.service (voice pipeline), portal-llm.service (on-device LLM), portal-launcher.service (app launcher), and portal-pcp.service (capability protocol daemon). Environment variable templates are provided as .env.example files.
The portal/network/ directory contains the Wi-Fi access point configuration, the wireless AP-portal.conf (5 GHz AP for AR glasses connectivity), the DHCP server-portal.conf.tmpl (DHCP/DNS), NetworkManager.conf, and a udev rule for the the wireless interface interface. These create the dedicated network between the Portal OS hardware and the AR glasses.
The portal/compositor/ directory holds Wayfire configuration, wayfire.ini (production), wayfire-portal.ini, and spatial-warp.toml (warp renderer parameters). The portal/protocols/ directory contains portal-spatial-v1.xml, the custom Wayland protocol extension that defines the spatial compositor’s IPC interface.
Supporting Infrastructure
Section titled “Supporting Infrastructure”Fuzz Workspace
Section titled “Fuzz Workspace”The fuzz/ directory is a separate, standalone Cargo workspace (note its own [workspace] declaration in fuzz/Cargo.toml) that provides five libFuzzer targets targeting security-critical parsing code:
| Fuzz Target | Input Domain | Protects Against |
|---|---|---|
ipc_framing |
PCP IPC wire frames | Malformed protocol messages |
desktop_parser |
.desktop file entries |
Launcher injection via desktop entries |
rtp_depacketizer |
RTP packet sequences | Streaming pipeline crashes |
toml_config |
TOML configuration files | Config parsing panics |
gstreamer_argv |
Shell argument strings | GStreamer pipeline injection |
Each target has a corresponding corpus directory under fuzz/corpus/ for seed inputs.
Benchmarks
Section titled “Benchmarks”The benches/ directory is a workspace member (portal-benches) containing three Criterion benchmarks: spatial_ipc (IPC throughput), rtp_encode (RTP packetization performance), and voice_tts (TTS latency). These measure the hot paths identified in the latency budget and are run via cargo bench -p portal-benches.
Supply Chain Security
Section titled “Supply Chain Security”The supply-chain/ directory implements cargo-vet integration: audits.toml records per-crate security audits, imports.lock tracks audits imported from trusted third parties, config.toml configures the vet policy, and audit-priorities.md documents the triage order. Combined with deny.toml (cargo-deny), this provides a two-layer dependency governance framework, cargo-deny blocks vulnerable/unlicensed crates at build time, while cargo-vet records the human review that approved each dependency.
Specification-Driven Development
Section titled “Specification-Driven Development”The openspec/ directory implements a spec-driven change management workflow. The specs/ subtree holds architecture specifications organized by subsystem (elara, input, launcher, pcp, style, terminal), while changes/ tracks proposed modifications as self-contained proposals (e.g., add-pcp-app-launch, add-pcp-cli-daemon-ipc). The config.yaml file configures the openspec tooling. Companion .claude/ and .opencode/ directories provide AI-assisted commands and skills for exploring, proposing, applying, and archiving these specifications.
Build Scripts and Deployment Tooling
Section titled “Build Scripts and Deployment Tooling”The top-level scripts/ directory contains Python and shell automation for cross-cutting concerns that do not belong to a single crate:
| Script | Language | Purpose |
|---|---|---|
deploy/deploy.sh |
Shell | End-to-end deployment to the Portal OS hardware |
generate_sbom.sh |
Shell | Software Bill of Materials generation |
generate-manifest.py |
Python | Build manifest generation |
sign_release.sh |
Shell | Release artifact signing (cosign/minisign) |
verify_release.sh |
Shell | Release signature verification |
install-voice-models.sh |
Shell | Download and install STT/TTS/NLU model files |
hp_smoke_test.sh |
Shell | Smoke test suite for the Portal OS hardware |
scan_async_mutex.py |
Python | Static analysis for async mutex deadlocks |
The scripts/deploy/ subdirectory additionally contains aarch64-toolchain.cmake (CMake toolchain file for ARM64 cross-compilation) and ensure-hdmi-a2-resolution.sh (display configuration fixup).
Cross-Language Components
Section titled “Cross-Language Components”Two directories live outside portal/ for components that are fundamentally separate from the Rust workspace:
The unity/ directory contains the Unity project for the AR glasses receiver, SpatialPortal_3DoF/ is the main project with 3DoF head tracking, and builds/ holds pre-built technical documentation. The .gitignore carefully excludes Unity build artifacts (Library/, Temp/, obj/) while tracking source assets.
The inmo_app_analysis/ directory contains reverse-engineering artifacts from the AR glasses Android application, AndroidManifest.xml, decompiled Java sources, and resource files. This is a reference-only directory, not built code.
CI/CD and Quality Enforcement
Section titled “CI/CD and Quality Enforcement”The .github/workflows/ directory contains 14 GitHub Actions workflows that enforce quality gates on every push and pull request:
flowchart LR
PUSH[Push / PR] --> CHECK[check.yml<br/>fmt + clippy + docs + coverage]
PUSH --> TEST[test.yml<br/>unit + integration tests]
PUSH --> CROSS[cross-compile.yml<br/>aarch64 ARM64 build]
PUSH --> MIRI[miri.yml<br/>unsafe memory validation]
PUSH --> GUARD[guard-main.yml<br/>main branch protection]
PUSH --> SEMVER[semver.yml<br/>version compatibility]
PUSH --> GITLEAKS[gitleaks-scan.yml<br/>secret detection]
PUSH --> TRUFFLE[trufflehog-scan.yml<br/>verified secret scan]
RELEASE[Release Tag] --> REL[release.yml<br/>build + sign + publish]
RELEASE --> NOTIFY[notify-release.yml<br/>release notifications]
REL --> SBOM[SBOM generation]
REL --> SIGN[cosign signing]
SCHEDULED[Daily / Weekly] --> TR_DAILY[trufflehog-daily-subsystem.yml]
SCHEDULED --> TR_WEEKLY[trufflehog-weekly-repo.yml]
SCHEDULED --> SECURITY[security.yml]
The check.yml workflow runs four parallel jobs: fmt (formatting), clippy (two-tier linting, strict for --lib --bins, permissive for --tests), docs (cargo doc with -D warnings), and coverage (cargo-llvm-cov with an 85% line coverage floor). The test workflow (test.yml) runs cargo test in three phases: library tests, integration tests, and doc tests.
Locally, the justfile provides shorthand commands: just build-rust (full workspace build for ARM64), just build-cpp (Wayfire plugins), just test (workspace tests), and just clean (all artifacts). The .pre-commit-config.yaml adds two-layer secret scanning, Gitleaks (fast pattern-matching on staged changes) and TruffleHog (deep verification against live services), both running before any commit enters history.
File and Directory Quick Reference
Section titled “File and Directory Quick Reference”| Directory | What Lives Here | Build System |
|---|---|---|
portal/*/ |
Rust workspace crates (30 members) | Cargo (workspace) |
portal/streaming/ |
C streaming pipeline (GStreamer, H.265) | Makefile + shell |
portal/wayfire-plugins/ |
C++ Wayfire plugin shims | CMake |
portal/systemd/ |
Systemd service units | N/A (deployed as-is) |
portal/network/ |
Network configuration (the wireless AP, the DHCP server) | N/A (deployed as-is) |
portal/compositor/ |
Wayfire config files | N/A (deployed as-is) |
portal/protocols/ |
Wayland protocol XML | wayland-scanner |
portal/apparmor/ |
AppArmor profiles | N/A (deployed as-is) |
portal/scripts/ |
Build/deploy shell scripts | N/A |
portal/android/ |
Android receiver app | Gradle |
fuzz/ |
libFuzzer targets (5) | Cargo (standalone workspace) |
benches/ |
Criterion benchmarks (3) | Cargo (workspace member) |
supply-chain/ |
cargo-vet audits + config | N/A |
scripts/ |
Python/shell deployment automation | N/A |
unity/ |
Unity 3DoF receiver project | Unity Editor |
openspec/ |
Spec-driven change proposals | openspec tooling |
.github/workflows/ |
CI/CD pipeline definitions (14) | GitHub Actions |
Where to Go Next
Section titled “Where to Go Next”Now that you understand the layout, these pages will help you take the next steps:
- CI/CD Pipeline: Lint Enforcement, Cross-Compilation, and Release Signing, deep dive into the 14 GitHub Actions workflows
- Testing Strategy: Unit Tests, Property Tests, Fuzzing, and Benchmarks, how tests, fuzz targets, and benchmarks are organized