Skip to content

Latest commit

 

History

History
427 lines (311 loc) · 16 KB

File metadata and controls

427 lines (311 loc) · 16 KB

Contributing to Spanda

Thank you for your interest in contributing to Spanda — an Autonomous Systems Platform with a safety-first programming language at its core.


Ways to contribute


Development setup

Prerequisites

  • Node.js 18+
  • Rust stable
  • npm

Clone and build

git clone https://github.com/Davalgi/Spanda.git
cd Spanda
npm install
npm run build:rust

Run tests

# TypeScript / Vitest
npm test

# Rust
cargo test --workspace

# Full PR gate (matches CI Fast workflow)
./scripts/ci-fast.sh

Optional pre-push hook (fmt + cross-surface check):

./scripts/setup-githooks.sh

See docs/ci-architecture.md for tiered CI (Fast / Integration / Nightly).

Format and lint

cargo fmt --all
cargo clippy --workspace -- -D warnings
npm run lint

After bulk inline documentation edits, run:

python3 scripts/normalize_inline_docs.py

Inline documentation

Every module and function in Rust (crates/), TypeScript (src/, packages/), Python (scripts/), and Spanda (.sd) must follow the structured docstring standard in docs/coding-standards.md.

Module headers

  • Rust: //! block at the top of the file describing module purpose.
  • TypeScript: /** ... @module */ block at the top of the file.

Function API docs

Place API documentation inside the function body (or /// / JSDoc above the signature when required for rustdoc). Required sections: Description, Inputs, Outputs, Example.

Block comments

Before each meaningful logic block (if, match, loops, error paths), add a plain-English // comment explaining what that block does. Do not use generic placeholders like "Process each item" or prefix with Logic:.

Tooling

Script Purpose
scripts/validate_documentation.py Audit coverage; CI warnings
scripts/validate_architecture.py Layer classification, zero-waiver baseline, manifest sync (CI Fast lint-rust)
scripts/sync_architecture_manifest.sh Regenerate architecture-manifest.json after YAML edits
scripts/add_structured_api_docs.py Generate structured API doc blocks
scripts/fix_structured_doc_gaps.py Fix empty Inputs and legacy single-line comments
scripts/repair_doc_param_typos.py Repair truncated parameter names in generated docs
scripts/add_inline_docs.py Legacy API doc generator
scripts/add_logic_block_docs.py Generate contextual block comments
scripts/normalize_inline_docs.py Fix spacing and indentation after bulk edits

After bulk documentation edits, run:

python3 scripts/normalize_inline_docs.py
python3 scripts/validate_documentation.py --report

Always run cargo fmt --all before committing — inline doc insertion can affect brace indentation.


Project structure

crates/                 Rust workspace — see crates/README.md
  spanda-core/          Public facade (re-exports, hardware_verify, shims)
  spanda-driver/        compile, check, run pipeline
  spanda-cli/           Native spanda binary
  spanda-interpreter/   Tree-walking runtime
  spanda-parser/        Parser
  spanda-package/       Package manager (no spanda-core dep)
  …                     See crates/README.md for full list

src/                    TypeScript mirror (tests, CLI wrapper, LSP helpers)
packages/lsp/           Language Server
packages/web/           Web playground
examples/               Sample .sd programs
tests/                  Vitest test suite
docs/                   Documentation

Rule of thumb: Language semantics changes land in the owning workspace crate (spanda-parser, spanda-typecheck, spanda-interpreter, …). Update spanda-core shims/re-exports when the public spanda_core:: API changes. TypeScript mirror (src/) should stay in parity for parsing, types, and runtime behavior used in tests.

Crate dependency rule: first-party apps (spanda-cli, spanda-node, spanda-wasm, spanda-dap, spanda-llvm) import workspace crates directly; only external embedders need spanda-core.


Coding standards

Rust

  • Run cargo fmt --all before committing
  • Fix all cargo clippy --workspace -- -D warnings warnings
  • Add tests in the owning crate (crates/spanda-*/tests/, crates/spanda-core/tests/) or inline #[test] for new behavior
  • Keep changes focused — one logical change per commit
  • Match existing module organization and naming

TypeScript

  • Run npm run lint (TypeScript --noEmit)
  • Add Vitest tests in tests/ for mirror changes
  • Follow existing patterns in src/parser/, src/runtime/, etc.

Spanda examples (.sd)

  • Use physical units (m/s, rad, ms)
  • Include safety blocks for motion examples
  • AI examples must use safety.validate() before actuator.execute()
  • Add showcase examples to examples/showcase/ for high-visibility demos
  • Ensure examples pass spanda check (and spanda run where applicable)

Architecture review

Permanent governance for platform coherence and non-duplication. Every architectural change must pass Architecture Review before merge.

Start here: docs/architecture-governance.md

When review is required

Architecture Review is mandatory before implementing or merging:

  • New platform services or runtime components
  • New communication layers or transport abstractions
  • New or breaking APIs (REST, gRPC, CLI JSON)
  • New SDK surfaces (Rust, Python, TypeScript together)
  • New workspace crates under crates/
  • New architecture diagrams or layer changes
  • New roadmap items with platform scope
  • New Control Center features with platform impact
  • Provider, plugin, or official package changes that expand platform contracts

Bug fixes, typos, and internal refactors with no contract change do not require a formal proposal — but the PR template still applies when in doubt.

How to propose

  1. Open an architecture proposal before large implementation work.
  2. Complete the twelve gates in docs/architecture-review-checklist.md.
  3. Perform duplication search per docs/non-duplication-policy.md.
  4. Wait for Architecture Review outcome (Recommend or better) before large builds.
  5. For significant decisions, add an ADR under docs/adr/ using docs/adr/template.md.

Process details: docs/design-review-process.md.

Pull requests

All PRs use .github/PULL_REQUEST_TEMPLATE.md. Architecture-affecting PRs must link the approved issue or ADR and confirm the quality gate:

  • Architecture Review completed
  • Duplication Analysis completed
  • Security Review completed (when applicable)
  • Compatibility Review completed
  • Entity Integration documented
  • Tests planned or added
  • Documentation updated
  • ADR created (major changes)

Roadmap items

New items in ROADMAP.md must include: Problem, Architecture Fit, Entity Integration, Existing Capability Extended, Duplication Analysis, Security Review, Test Plan, Demo Plan, and Release Impact. See architecture-governance.md#roadmap-rule.

Principles (summary)

Extend before creating · Reuse before duplicating · Prefer providers and packages over core expansion · Prefer Entity integration · Prefer additive API changes · Every feature demonstrable · Every capability testable · Every significant decision documented in an ADR.

Full list: docs/architecture-governance.md#architecture-principles.


How to add a language feature

  1. Propose first — open a language proposal for non-trivial syntax or semantics changes
  2. Implement in Rust — lexer → parser → AST → type checker → runtime (in that order)
  3. Add tests — Rust integration tests + Vitest mirror tests
  4. Update docs — see Keeping documentation in sync below
  5. Add an example — demonstrate the feature in examples/

For v0.1.0-alpha, we are not adding large new language features. Focus on stability, tests, and documentation unless the proposal is critical.


Keeping documentation in sync

Rule: Any long, big, or major update must include documentation updates in the same change set. Do not merge feature work with stale README or docs.

What counts as major

  • New language syntax, runtime behavior, or CLI commands/flags
  • Architecture, crate layout, or CI workflow changes
  • New integrations (ROS2, FFI, fleet, triggers, concurrency, etc.)
  • Feature status or roadmap shifts
  • New showcase or reference examples

Typos, internal refactors with no user-visible effect, and test-only changes usually do not need doc updates.

Minimum checklist

After major work, review and update every file that applies:

File When
README.md Capabilities, CLI, examples, differentiators, roadmap
CHANGELOG.md User-visible additions, fixes, or breaking changes
docs/feature-status.md Stability or capability matrix changes
docs/getting-started.md New commands, workflows, or demo paths
docs/README.md New guides or doc index changes
docs/platform-architecture.md Layer rules, CI governance, dependency policy
docs/architecture-governance.md Architecture Review gate, principles, quality gate
docs/architecture-waiver-burn-down.md Waiver baseline changes (should remain at 0)

Topic-specific docs (update when the area changed):

  • Language: docs/spanda-language.md (+ dedicated guide if one exists, e.g. docs/triggers.md)
  • Runtime / compiler: docs/architecture.md, docs/lean-core.md
  • Platform layers / dependencies: docs/platform-architecture.md, docs/dependency-rules.md
  • Concurrency / fleet / triggers: docs/concurrency.md, docs/triggers.md
  • Hardware / verify: docs/hardware-compatibility.md
  • Packages: docs/packages.md, docs/spanda-toml.md
  • FFI / ROS2: docs/ffi-and-ecosystem.md
  • Roadmap / strategy: docs/roadmap.md, docs/product-strategy.md
  • Contributor workflow: this file (CONTRIBUTING.md)

Also add a runnable example and link it from README.md or docs/getting-started.md when it is a key demo.

The Cursor rule .cursor/rules/documentation-sync.mdc enforces this for agent-assisted sessions.


How to add an example

  1. Create examples/your_example.sd (or examples/showcase/ for curated demos)
  2. Verify locally:
spanda check examples/your_example.sd
spanda run examples/your_example.sd        # if it has runnable behavior
spanda verify examples/your_example.sd     # if it has deploy targets
  1. Add to golden fixtures if it should stay runnable in CI (tests/golden/manifest.json). Mission trace files (.trace) may live under examples/ or tests/golden/; other runtime traces stay gitignored.
  2. For tutorial-style programs, prefer numbered files under examples/basics/ or topic dirs (integration/, end_to_end/, features/); see examples/features/README.md and examples/basics/README.md.
  3. Reference it in README or docs/getting-started.md if it is a key demo

Releases

Spanda uses Semantic Versioning. User-facing changes belong in CHANGELOG.md under ## [Unreleased] in the same PR as the feature or fix.

When to bump: See docs/versioning.md — each stream (workspace, SDKs, desktop) has its own semver; bump only the stream whose area changed.

Automatic releases (preferred)

After CI Integration passes on main, the Auto release workflow bumps the workspace version and pushes a vX.Y.Z tag when the merged pull request has one of these labels:

Label When to use
release:major v1.0 positioning or breaking language/API/SDK changes
release:minor Roadmap release milestone complete (v0.5, …) or substantial additive platform release
release:patch Bug fixes, stable promotions, and small updates within the current release line

Create the labels in the GitHub repo if they do not exist yet (release:major, release:minor, release:patch). Apply one release label before merging. The workflow bumps the workspace stream and pushes a v* tag that triggers cargo-dist Release. When the merged PR also changed Control Center paths (packages/web, packages/control-center-desktop, Control Center API/CLI), Auto release bumps the desktop stream too and pushes desktop-v*, which triggers the Tauri GitHub Release workflow. SDK releases still use --stream sdk locally — see docs/versioning.md and docs/control-center-versioning.md.

| Control Center path check (local) | ./scripts/control_center_paths_changed.sh origin/main — exit 0 when the diff touches Control Center | | Version display | Sidebar vX.Y.Z; spanda control-center --version; GET /v1/versioncontrol_center_ui_version |

Manual release

Use Actions → Bump version when you need an ad-hoc semver bump without a labeled PR. Choose workspace or desktop stream; pick patch, minor, or major; leave Push release tag enabled to publish.

Local dry run

python3 scripts/bump_version.py minor --dry-run
python3 scripts/bump_version.py patch --stream desktop --dry-run

Pull request process

  1. Fork the repository and create a feature branch
  2. For platform or architectural changes, complete Architecture review first
  3. Make focused changes with tests
  4. Run ./scripts/ci-fast.sh locally (or the individual commands in docs/ci-architecture.md)
  5. Open a PR against main using the PR template
  6. CI Fast must pass (lint-rust, test-rust, test-typescript, test-python-sdk, test-ts-sdk, cross-surface-check, cross-interface)
  7. Architecture-affecting PRs must pass the quality gate
  8. After merge to main, CI Integration runs automatically — keep main green before stacking more work

Cross-surface API changes: follow the checklist in docs/ci-architecture.md#cross-surface-change-protocol.


Commit messages

  • Use clear, descriptive summaries
  • Explain why in the body when non-obvious
  • Split unrelated changes into separate commits
  • Do not include agent or tool attribution in commit messages

Code of conduct

This project follows the Contributor Covenant. Be respectful and constructive.


Questions

Open a GitHub Discussion or issue if you are unsure where to start. We are happy to help newcomers find a good first contribution.