Thank you for your interest in contributing to SpecSync! This guide will help you get started.
- Rust 1.89 or newer (the CI toolchain is pinned; see
rust-toolchain.toml) - Git
# Clone the repo
git clone https://github.com/CorvidLabs/spec-sync.git
cd spec-sync
# Build
cargo build
# Run tests
cargo test
# Run lints
cargo clippy -- -D warnings
# Format code
cargo fmtfledge lanes run pre-push
# or: ./scripts/pre-push-gate.shRuns fmt + cargo check + strict path/spec coverage only (target: ~seconds–2 min warm).
Does not run full cargo test or clippy — those are fledge lanes run verify / CI. Do not push red.
# Validate specs in the current directory
cargo run -- check
# Generate specs for uncovered modules
cargo run -- generate --uncovered
# Run strict validation and bypass the incremental cache
cargo run -- check --strict --forceUse the Bug Report issue template. Include:
- SpecSync version (
specsync --version) - OS and Rust version
- Minimal reproduction steps
- Expected vs actual behavior
Use the Feature Request issue template. Describe:
- The problem you're trying to solve
- Your proposed solution
- Alternatives you've considered
The documentation marketing site lives in site/ (Astro + MDX). To work on docs locally:
cd site
bun install
bun run dev # dev server at localhost:4321
bun run build # production build → site/dist/
bun test # run all site testsDocs content lives in site/src/content/docs/. The site is deployed automatically to GitHub Pages on every push to main via .github/workflows/pages.yml.
- Fork the repo and create a branch from
main - Make your changes
- Add or update tests as needed
- Run
cargo testandcargo clippy— everything must pass - Update documentation if you changed behavior (
site/src/content/docs/) - Open a PR using the PR template
SpecSync supports 33 languages via extractors in src/exports/. To add a new one:
- Create
src/exports/<language>.rsimplementing anextract_exports(content: &str) -> Vec<String>function - Register the extractor in
src/exports/mod.rsand update theLanguageenum insrc/types.rs - Add test fixtures in
tests/fixtures/<language>/ - Add tests covering:
- Export detection (functions, classes, types, constants)
- Visibility filtering (skip private/internal items)
- Test file exclusion patterns
- Update
README.mdwith the language in the supported languages table - Update
site/src/content/docs/spec-format.mdif the language has any special behaviors
Write clear, concise commit messages. Use the imperative mood:
fix: handle wildcard re-exports in TypeScript parserfeat: add Elixir language supportdocs: update CLI reference for new --format flagtest: add cross-project reference validation tests
- Follow standard Rust conventions (
cargo fmt) - No warnings from
cargo clippy - Public items should have doc comments
- Tests go in the same file (
#[cfg(test)]module) or intests/
src/
commands/ # CLI command implementations
exports/ # Language export extractors and AST backends
parser.rs # Spec markdown/frontmatter parsing
validator.rs # Bidirectional validation and coverage
generator.rs # Spec and companion generation
config.rs # Configuration loading and migration serialization
tests/
integration/ # CLI and MCP integration-test modules
specs/ # Module contracts and companion files
site/ # Documentation marketing site (Astro + MDX)
vscode-extension/ # VS Code integration
By contributing, you agree that your contributions will be licensed under the MIT License.
Merge confidence and the CI/Trust split are documented in docs/ci-confidence.md. GitHub CI owns the test matrix; Trust must not re-run it.