Development Workflow: Local Coding to Remote Deployment
The Portal project spans two hardware architectures — your x86_64 development machine and the ARM64 Spaceboard (Snapdragon X Elite) or Orange Pi 5 Max target — connected by a multi-stage pipeline that moves code from your editor through automated quality gates, cross-compilation, remote smoke testing, cryptographic signing, and finally systemd-based deployment on the target device. This page walks you through every stage of that journey, showing you exactly which commands to run, what each script does, and where the automated guardrails protect you from mistakes.
Sources: justfile#L1-L67, Cargo.toml#L1-L272, rust-toolchain.toml#L1-L4
Workflow at a Glance
Section titled “Workflow at a Glance”Before diving into individual steps, here is the complete pipeline from the moment you write code to the moment it runs on the Spaceboard:
flowchart TD
A["Write Code<br/>(macOS / Linux x86_64)"] --> B["Pre-commit Hooks<br/>Gitleaks + TruffleHog"]
B --> C["Local Checks<br/>cargo fmt, clippy, test"]
C --> D["Push Feature Branch"]
D --> E["CI Quality Gates<br/>fmt · clippy · docs · coverage<br/>test · miri · semver · security"]
E --> F{"All Checks Pass?"}
F -->|No| A
F -->|Yes| G["Pull Request to<br/>x-elite-spaceboard"]
G --> H{"Guard Main:<br/>Approved + CI Green?"}
H -->|No| A
H -->|Yes| I["Merge to x-elite-spaceboard"]
I --> J["Sync to Spaceboard<br/>sync-to-hp.sh"]
J --> K["Native Build + Smoke Test<br/>hp_smoke_test.sh"]
K --> L{"Smoke Pass?"}
L -->|No| A
L -->|Yes| M["Tag Release v*.*.*"]
M --> N["Release CI:<br/>Cross-compile + Sign + SBOM"]
N --> O["GitHub Release<br/>with Signed Artifacts"]
O --> P["Deploy to Spaceboard<br/>deploy-spaceboard.sh"]
P --> Q["Systemd Services<br/>Live on Hardware"]
Each box in this diagram corresponds to a concrete file, script, or workflow in the repository. The sections below walk through them in order.
Sources: .github/workflows/check.yml#L1-L87, scripts/sync-to-hp.sh#L1-L22, scripts/hp_smoke_test.sh#L1-L126
Stage 1: Setting Up Your Local Environment
Section titled “Stage 1: Setting Up Your Local Environment”Rust Toolchain
Section titled “Rust Toolchain”The project pins Rust 1.97.0 with rustfmt, clippy, and rust-src as mandatory components. This version is declared in a rust-toolchain.toml file, which rustup reads automatically — you do not need to manually run rustup install.
Sources: rust-toolchain.toml#L1-L4
Workspace Structure
Section titled “Workspace Structure”Portal uses a single Cargo workspace containing over 40 crates organized by subsystem. The root Cargo.toml defines all member crates and shared dependencies. The key architectural groups are:
| Group | Representative Crates | Purpose |
|---|---|---|
| Compositor & Spatial | portal-spatial, portal-spatial-plugin, portal-warp, portal-wm |
Wayland compositor integration and spatial rendering |
| Input | portal-input |
Touch fusion, keyboard daemon, virtual input devices |
| Voice & AI | portal-voice, portal-llm, portal-npu-runtime |
VAD, STT, TTS, on-device LLM, NPU wrappers |
| Streaming | portal-stream |
H.265 hardware encode → RTP/UDP pipeline |
| Application Framework | portal-context, portal-launcher, portal-shell, portal-style |
Context engine, universal launcher, design tokens |
| PCP | portal/pcp/* (18 crates) |
Portal Capability Protocol — IPC, registry, daemon |
| Shared | portal-common |
Common types, utilities |
Sources: Cargo.toml#L3-L45
Lint Enforcement
Section titled “Lint Enforcement”The workspace enforces a strict clippy policy at the workspace level. Production code (libraries and binaries) is held to the highest bar: correctness, suspicious, style, complexity, perf, and pedantic categories are all set to deny. Additionally, unwrap_used, expect_used, and panic_in_result_fn are denied to force proper error handling via Result. Test code receives a deliberately permissive policy because tests should panic on setup failure as the test signal.
Sources: Cargo.toml#L166-L214, .github/workflows/check.yml#L18-L46
Pre-commit Hooks: Secret Scanning Defense
Section titled “Pre-commit Hooks: Secret Scanning Defense”Before any change enters git history, two independent secret-scanning tools run in parallel:
| Layer | Tool | Mode | Speed | Strategy |
|---|---|---|---|---|
| Layer 1 | Gitleaks v8.30.1 | Pattern + entropy | Milliseconds | Scans only staged changes |
| Layer 2 | TruffleHog v3.95.3 | Deep verification | Slower | Scans diff from HEAD, verifies secrets against live APIs |
If either layer detects a secret, the commit is blocked. This dual-layer approach catches both fast false-positive-prone patterns (Layer 1) and slow but near-zero-false-positive verified secrets (Layer 2).
Sources: .pre-commit-config.yaml#L1-L35
Stage 2: Local Quality Checks
Section titled “Stage 2: Local Quality Checks”The justfile provides shorthand commands for the most common development tasks. Install just with cargo install just, then run just (with no arguments) to see all available recipes.
| Command | What It Does |
|---|---|
just build-rust |
Cross-compile all Rust crates for ARM64 (aarch64-unknown-linux-gnu) in release mode |
just build-crate <name> |
Build a specific crate for ARM64 |
just build-cpp |
Build Wayfire C++ plugins via CMake |
just build-voiced |
Build the voice daemon with ALSA fallback features |
just build-all |
Run all build targets in sequence |
just test |
Run cargo test --workspace --all-features |
just clean |
Remove all build artifacts |
For day-to-day development, you will typically run these commands natively on your x86_64 machine before pushing:
# Format checkcargo fmt --all -- --check
# Lint (production-grade strict)cargo clippy --lib --bins --workspace --all-features -- -D warnings
# Testscargo test --lib --workspace --all-featuresSources: justfile#L1-L67, .github/workflows/check.yml#L8-L16
ARM64 Sandbox for Local Binary Testing
Section titled “ARM64 Sandbox for Local Binary Testing”Since the target hardware is ARM64, you can test cross-compiled binaries locally using a Docker-based QEMU emulation sandbox. The run_sandbox.sh script spins up an arm64v8/debian:bookworm container that matches the Spaceboard’s OS environment exactly:
# Test a cross-compiled binary locally before deploying./run_sandbox.sh ./target/aarch64-unknown-linux-gnu/release/portal-wm --helpThe sandbox sets IS_SANDBOX=1 and TARGET_ARCH=arm64 environment variables so your code can detect it is running under emulation.
Sources: run_sandbox.sh#L1-L29, docs/ARM64_Sandbox_Environment_Setup.md#L5-L11
Stage 3: CI Quality Gates
Section titled “Stage 3: CI Quality Gates”When you push a branch or open a pull request, nine automated workflows run in parallel. Every workflow must pass before code reaches the main branch.
flowchart LR
PR["Push / Pull Request"] --> W1["Check<br/>fmt + clippy + docs<br/>+ coverage + clippy-arm64"]
PR --> W2["Test<br/>lib + integration tests"]
PR --> W3["Cross-Compile<br/>ARM64 release build"]
PR --> W4["Security<br/>cargo-audit + cargo-deny"]
PR --> W5["Semver<br/>API compatibility"]
PR --> W6["Miri<br/>UB scan on FFI crates"]
PR --> W7["Gitleaks<br/>Secret scan"]
PR --> W8["Guard Main<br/>Branch protection"]
Check Workflow Details
Section titled “Check Workflow Details”| CI Job | Gate | Failure Condition | Notes |
|---|---|---|---|
| fmt | cargo fmt --all -- --check |
Any unformatted code | Pinned to stable toolchain |
| clippy (production) | cargo clippy --lib --bins -- -D warnings |
Any clippy warning in production code | Strict: zero tolerance for unwrap/expect/panic |
| clippy (tests) | cargo clippy --tests -- -D warnings -A ... |
Any clippy warning in tests (except allowed) | Permissive on test-specific patterns |
| docs | cargo doc --no-deps --all-features with RUSTDOCFLAGS: -D warnings |
Any rustdoc warning | All features enabled |
| coverage | cargo llvm-cov --fail-under-lines 85 |
Line coverage below 85% | Floor accounts for FFI boundary gaps |
| clippy-arm64 | cross clippy --target aarch64-unknown-linux-gnu |
Any clippy warning on ARM64 | Currently continue-on-error: true (advisory) |
Sources: .github/workflows/check.yml#L1-L87
Test Workflow
Section titled “Test Workflow”The test pipeline runs in three stages: library unit tests (--lib), integration tests (--test '*'), and documentation tests (--doc). Doc tests currently run with continue-on-error: true while intra-doc links are being stabilized.
Sources: .github/workflows/test.yml#L1-L26
Security and Safety Scans
Section titled “Security and Safety Scans”| Workflow | Tool | Frequency | Purpose |
|---|---|---|---|
| Security | cargo-audit |
Push + PR + Daily cron | RustSec advisory database scan |
| Security | cargo-deny |
Push + PR + Daily cron | Advisories + licenses + bans + sources |
| Miri | cargo +nightly miri test |
Push + PR | Undefined Behavior scan on FFI-heavy crates (npu-runtime, spatial, input, voice) |
| Gitleaks | Gitleaks Action | Push + PR | Full-history secret scan with fetch-depth: 0 |
| Semver | cargo-semver-checks |
Push + PR | API compatibility regression detection (advisory, non-blocking) |
Sources: .github/workflows/security.yml#L1-L45, .github/workflows/miri.yml#L1-L51, .github/workflows/gitleaks-scan.yml#L1-L26, .github/workflows/semver.yml#L1-L24
Supply Chain Configuration
Section titled “Supply Chain Configuration”The deny.toml file controls cargo-deny’s behavior. It denies all advisory classes (vulnerabilities, unmaintained, unsound, yanked) by default. Each ignored advisory carries a documented reason and a re-verification timestamp. License compliance is enforced with a confidence threshold of 0.93 and an explicit allow-list of 14 approved license types.
Sources: deny.toml#L1-L21, deny.toml#L23-L41
Stage 4: Branch Protection and Pull Request Flow
Section titled “Stage 4: Branch Protection and Pull Request Flow”Since the repository runs on GitHub Free (which does not support native branch protection for private repos), a software-enforced Guard Main workflow provides equivalent protection.
flowchart TD
PUSH["Push to x-elite-spaceboard"] --> IS_BOT{"Is bot push?"}
IS_BOT -->|Yes| SKIP["Skip (prevent loops)"]
IS_BOT -->|No| IS_MERGE{"Is PR merge?"}
IS_MERGE -->|No, direct push| REVERT["Auto-revert commit<br/>Create security issue"]
IS_MERGE -->|Yes| APPROVED{"Was PR approved?<br/>(repo owner exempt)"}
APPROVED -->|No| ISSUE["Create violation issue"]
APPROVED -->|Yes| CI_PASSED{"Did CI checks pass?"}
CI_PASSED -->|No| ISSUE
CI_PASSED -->|Yes| ALLOW["Allow commit"]
CI_PASSED -->|Unknown| ALLOW
The rules enforced are:
- Direct pushes to
x-elite-spaceboardare automatically reverted and a security issue is filed with thesecurity-violationlabel. - PR merges require at least one approval — except PRs authored by the repo owner (single-developer allowance).
- CI checks must pass — any GitHub Actions check suite with
conclusion: failureblocks the merge. - Bot pushes and revert commits are skipped to prevent infinite guard-revert loops.
Sources: .github/workflows/guard-main.yml#L1-L227
Stage 5: Cross-Compilation for ARM64
Section titled “Stage 5: Cross-Compilation for ARM64”The project targets aarch64-unknown-linux-gnu (ARM64 Linux). Cross-compilation uses the cross tool (v0.2.5) with Docker-based toolchain images.
Configuration
Section titled “Configuration”The cross-compilation setup spans three files:
| File | Role |
|---|---|
Cross.toml#L1-L13 |
Defines Docker images for ARM64 and ARMv7 targets, passes through RUSTFLAGS and PKG_CONFIG variables |
.cargo/config.toml#L1-L3 |
Sets aarch64-linux-gnu-gcc as the linker for the aarch64-unknown-linux-gnu target |
scripts/deploy/aarch64-toolchain.cmake#L1-L14 |
CMake cross-compilation toolchain for C++ Wayfire plugins |
CI Cross-Compilation
Section titled “CI Cross-Compilation”The Cross-Compile workflow builds the entire workspace in release mode for ARM64 and uploads the resulting binaries as GitHub Actions artifacts:
| Artifact | Source Crate | Type |
|---|---|---|
libportal_spatial.so |
portal-spatial | Shared library (cdylib) |
portal-wm |
portal-wm | Binary |
portal-voiced |
portal-voice | Binary |
portal-llmd |
portal-llm | Binary |
portal-keyboardd |
portal-input | Binary |
Sources: .github/workflows/cross-compile.yml#L1-L28, Cross.toml#L1-L13, .cargo/config.toml#L1-L3
Stage 6: Remote Sync and Native Build
Section titled “Stage 6: Remote Sync and Native Build”Syncing Source to the Spaceboard
Section titled “Syncing Source to the Spaceboard”After merging to x-elite-spaceboard, the sync-to-hp.sh script uses rsync to push the source tree from your Mac worktree to the HP Spaceboard. It excludes build artifacts, git metadata, and editor-specific directories:
# From your Mac worktree:./scripts/sync-to-hp.shThe script syncs two things: the portal/ directory (all Rust source) and the workspace root files (Cargo.toml, Cargo.lock, deny.toml, rust-toolchain.toml).
Sources: scripts/sync-to-hp.sh#L1-L22
Native Build on the Spaceboard
Section titled “Native Build on the Spaceboard”The Spaceboard (HP EliteBook Ultra G1q with Snapdragon X Elite) builds the project natively — no cross-compilation needed. This is critical because the Hexagon DSP, Qualcomm IRIS encoder, and Adreno GPU libraries are only available on the target device. The hp_smoke_test.sh script orchestrates this:
# Full build + smoke test (run from Mac, SSHs into Spaceboard):./scripts/hp_smoke_test.sh
# Smoke test only (assumes already built):./scripts/hp_smoke_test.sh --skip-buildThe smoke test verifies each binary in sequence:
| Check | Binary | Verification Method |
|---|---|---|
| Workspace build | All crates | cargo build --workspace --release |
| Voice daemon build | portal-voiced | Build with 5 QNN features enabled |
| LLM daemon build | portal-llmd | Build with hexagon feature |
| Keyboard daemon build | portal-keyboardd | Build with keyboardd feature |
| Binary existence | All 5 binaries | test -x on each |
| Startup probe | portal-wm, portal-voiced, portal-llmd | timeout 5 <bin> --help (clap exits 0) |
| Unit tests | npu-runtime, spatial, input, voice | cargo test -p <crate> --lib |
| C tests | portal-stream (C) | make test in portal/streaming |
| Systemd probe | portal-llm | systemctl is-active or is-activating |
Sources: scripts/hp_smoke_test.sh#L1-L126, docs/x-elite-deployment-state.md#L1-L23
Deeper Integration Smoke Suite
Section titled “Deeper Integration Smoke Suite”For production verification, the hp-smoke-suite.sh script performs live hardware checks that go beyond binary buildability:
- Six services active — verifies
portal,portal-input,portal-stream,portal-voice,portal-llm,portal-pcpare allactive (running) - Voice UDP probe — sends a 4-byte probe to
127.0.0.1:5601to confirm the voice daemon’s audio socket is bound - Keyboard DRM scanout — checks
/sys/class/drm/card0-eDP-1/modesis non-empty (panel initialized) - Spatial IPC handshake — connects to
/run/portal/spatial.sockand sends aQueryStatusmessage - Service restart resilience — cycles
portal-inputthree times; each must return toactivewithin 10 seconds (catches DSP/DRM fd leaks)
Sources: scripts/hp-smoke-suite.sh#L1-L200
Stage 7: Release and Signing
Section titled “Stage 7: Release and Signing”When you are ready to publish a release, the workflow follows a strict cryptographic chain.
Release Trigger
Section titled “Release Trigger”Releases are triggered by pushing a git tag matching v* (e.g., git tag v0.2.1 && git push origin v0.2.1). This activates the Release workflow.
Sources: .github/workflows/release.yml#L1-L5
The Release Pipeline
Section titled “The Release Pipeline”flowchart TD
TAG["Tag Push: v*.*.*"] --> BUILD["Cross-compile<br/>ARM64 release build"]
BUILD --> SBOM["Generate SBOM<br/>CycloneDX JSON + XML<br/>(cargo-cyclonedx 0.5.9)"]
SBOM --> COSIGN["Cosign Signing<br/>Keyless Ed25519 via GitHub OIDC<br/>.sig + .pem + .bundle"]
COSIGN --> STAGE["Stage Artifacts<br/>binaries + SBOMs + signatures"]
STAGE --> MINISIGN{"MINISIGN_SECRET_KEY<br/>set in CI?"}
MINISIGN -->|Yes| SIGN_MIN["Minisign Signing<br/>Ed25519 signatures<br/>on all artifacts"]
SIGN_MIN --> VERIFY["Round-trip verify<br/>verify_release.sh"]
MINISIGN -->|No| SKIP_MIN["Skip minisign<br/>(cosign signatures sufficient)"]
VERIFY --> GH_REL["Publish GitHub Release<br/>with all assets"]
SKIP_MIN --> GH_REL
Dual Signing Strategy
Section titled “Dual Signing Strategy”Every release binary receives two independent signature types:
| Signature System | Algorithm | Identity | Transparency | Artifacts Produced |
|---|---|---|---|---|
| Cosign (Sigstore) | Ed25519 | GitHub OIDC (keyless) | Rekor transparency log | .sig, .pem, .bundle |
| Minisign | Ed25519 | Offline secret key | None (trust-on-first-use) | .minisig |
The dual-signing approach provides defense in depth: cosign provides automated, auditable keyless signing in CI, while minisign provides offline signing with a key generated on an air-gapped machine. The minisign step is optional in CI — if the MINISIGN_SECRET_KEY secret is not configured, cosign signatures alone are produced.
Sources: .github/workflows/release.yml#L52-L107, scripts/sign_release.sh#L1-L168, scripts/verify_release.sh#L1-L143
SBOM Generation
Section titled “SBOM Generation”Software Bills of Materials are generated using cargo-cyclonedx 0.5.9 in both CycloneDX JSON and XML formats (spec version 1.5). One SBOM file is produced per crate. The scripts/generate_sbom.sh script collects them into target/sbom/ for clean release uploads.
Sources: .github/workflows/release.yml#L34-L39, scripts/generate_sbom.sh#L1-L127
Release Artifacts
Section titled “Release Artifacts”Each GitHub Release includes five production binaries, each with up to five sidecar files:
| Binary | Purpose | Cosign Files | Minisign File |
|---|---|---|---|
portal-voiced |
Voice pipeline daemon (VAD + STT + TTS + NLU) | .sig, .pem, .bundle |
.minisig |
portal-llmd |
On-device LLM daemon (GenieX llama.cpp on Hexagon) | .sig, .pem, .bundle |
.minisig |
portal-keyboardd |
DRM/KMS keyboard daemon with Cairo rendering | .sig, .pem, .bundle |
.minisig |
portal-wm |
Window manager daemon (Wayland toplevel tracking) | .sig, .pem, .bundle |
.minisig |
portal-stream |
H.265 streaming C binary | .sig, .pem, .bundle |
.minisig |
Sources: .github/workflows/release.yml#L109-L136, scripts/sign_release.sh#L109-L115
Key Policy
Section titled “Key Policy”The release signing keypair follows a strict offline policy:
| Item | Rule |
|---|---|
Public keys (*.pub) |
Safe to commit — tracked in git at keys/portal-release.pub |
Secret keys (*.sec) |
Must never be committed — stored offline (1Password, hardware token, air-gapped media) |
| Key password | Entered interactively when signing — never piped via stdin, env var, or CLI flag |
| Key algorithm | minisign Ed25519 |
| Key rotation | On compromise or annual cadence, whichever is sooner |
Sources: keys/README.md#L1-L60
Stage 8: Deployment to Target Hardware
Section titled “Stage 8: Deployment to Target Hardware”Spaceboard Deployment (One-Shot)
Section titled “Spaceboard Deployment (One-Shot)”The deploy-spaceboard.sh script is a 12-step idempotent installer that sets up a fresh Spaceboard from scratch. Run it as root on the target device:
sudo ./portal/scripts/deploy-spaceboard.sh| Step | Action | Details |
|---|---|---|
| 1 | Create directories | /run/portal, /var/lib/portal, user data dirs |
| 2 | NetworkManager config | dns=none, uap0 interface |
| 3 | Mask conflicting services | dnsmasq, getty@tty1 |
| 4 | Set default target | multi-user.target (no display manager) |
| 5 | Portal config | Wayfire init at /etc/portal/wayfire.ini |
| 6 | Network configs | hostapd (5GHz AP) + dnsmasq DHCP |
| 7 | Systemd services | 13 Portal services + 2 watchdogs |
| 8 | Utility scripts | File watcher, Wine monitor, health monitor |
| 9 | Patched hostapd | ath11k EALREADY/EBUSY fix |
| 10 | System software | box64, LibreOffice, inotify-tools, Wine |
| 11 | Log files | /var/log/portal-*.log |
| 12 | Enable services | systemctl daemon-reload + enable all |
Sources: portal/scripts/deploy-spaceboard.sh#L1-L100
Orange Pi Deployment (Manual)
Section titled “Orange Pi Deployment (Manual)”For the legacy Orange Pi 5 Max target, the deployment process is more manual and documented in scripts/deploy/README.md. The key difference is that Rust libraries are cross-compiled on the build machine, while C++ shims must be built on the Orange Pi itself:
# 1. Transfer filesrsync -avz scripts/deploy/ orangepi@<ip>:/tmp/portal-deploy/
# 2. Install libraries on Orange Pissh orangepi@<ip>sudo cp /tmp/portal-deploy/libportal_spatial.so /usr/local/lib/sudo ldconfig
# 3. Build C++ shims on the Orange Picd /tmp/portal-deploy/../wayfire-pluginscmake -B build .cmake --build build
# 4. Install pluginssudo cp build/portal-spatial.so /usr/lib/wayfire/sudo cp build/portal-spatial-warp.so /usr/lib/wayfire/Sources: scripts/deploy/README.md#L72-L116, scripts/deploy/deploy.sh#L1-L39
Post-Deployment: HDMI Resolution Fix
Section titled “Post-Deployment: HDMI Resolution Fix”The Portal compositor requires a non-standard 2560×1080 resolution on HDMI-A-2 for the glasses output. The ensure-hdmi-a2-resolution.sh script idempotently patches /boot/orangepiEnv.txt with the kernel cmdline parameter video=HDMI-A-2:2560x1080@60e (the e suffix forces the mode even when EDID does not advertise it). A reboot is required after applying.
Sources: scripts/deploy/ensure-hdmi-a2-resolution.sh#L1-L82, scripts/deploy/README.md#L165-L187
Stage 9: Cross-Repository Synchronization
Section titled “Stage 9: Cross-Repository Synchronization”Once a release is published, two synchronization pipelines keep downstream repositories updated:
Public Repo Sync
Section titled “Public Repo Sync”The sync-to-public.sh script creates a squashed single-commit tree of the current release and force-pushes it to Demain-Technology/Portal-OS. The public repo gets exactly one commit per release — clean history with no intermediate work visible.
Sources: scripts/sync-to-public.sh#L1-L79
Board Issue Mirroring
Section titled “Board Issue Mirroring”Two GitHub Actions workflows provide event-driven synchronization:
- Sync to demain-deenson (
sync-to-demain.yml): When a PR is opened or merged, the workflow extracts mirror issue references from the PR body (e.g.,closes #123) and dispatches events to thedemain-deenson/portalrepository. - Notify Release (
notify-release.yml): When a GitHub Release is published, the workflow dispatches arelease-publishedevent to the board repository with the tag name, body, and URL.
Sources: .github/workflows/sync-to-demain.yml#L1-L90, .github/workflows/notify-release.yml#L1-L34
Quick Reference: Complete Command Sequence
Section titled “Quick Reference: Complete Command Sequence”For a developer making a change end-to-end, here is the full sequence of commands:
# 1. Create feature branchgit checkout -b feat/my-change
# 2. Write code, then run local checkscargo fmt --allcargo clippy --lib --bins --workspace --all-features -- -D warningscargo test --lib --workspace --all-features
# 3. Commit (pre-commit hooks run automatically)git add -A && git commit -m "feat: my change"
# 4. Push and open PRgit push origin feat/my-change# CI workflows run: check, test, cross-compile, security, miri, semver, gitleaks
# 5. After CI passes and PR is approved, merge to x-elite-spaceboard# Guard Main verifies approval + CI green
# 6. Sync to Spaceboard and smoke test./scripts/sync-to-hp.sh./scripts/hp_smoke_test.sh
# 7. Tag releasegit tag v0.2.X && git push origin v0.2.X# Release CI builds, signs (cosign + minisign), generates SBOM, publishes
# 8. Sync to public repo./scripts/sync-to-public.sh v0.2.X
# 9. Deploy to Spaceboard (on the device)sudo ./portal/scripts/deploy-spaceboard.shSources: justfile#L1-L67, scripts/sync-to-hp.sh#L1-L22, .github/workflows/release.yml#L1-L5, portal/scripts/deploy-spaceboard.sh#L1-L100
Where to Go Next
Section titled “Where to Go Next”Now that you understand the complete development pipeline, these pages dive deeper into specific stages:
- ARM64 Sandbox Environment Setup — Full QEMU/Docker sandbox configuration for testing ARM64 binaries on x86_64 hosts
- Repository Structure and Workspace Layout — Detailed map of the 40+ workspace crates and their dependencies
- Testing Strategy: Unit Tests, Property Tests, Fuzzing, and Benchmarks — How the test suite is organized across unit, property, fuzz, and benchmark targets
- CI/CD Pipeline: Lint Enforcement, Cross-Compilation, and Release Signing — In-depth analysis of all nine CI workflows
- Security Hardening: AppArmor, Stream Authentication, and Supply Chain Audits — The security posture enforced at each pipeline stage
- Systemd Service Management and Network Topology — How the 15+ systemd services are orchestrated on the target hardware