Thank you for your interest in contributing to SpecFact CLI! This document provides guidelines for contributing to the project.
This project adheres to the Code of Conduct. By participating, you are expected to uphold this code.
- Use the GitHub issue tracker
- Include detailed steps to reproduce the bug
- Provide system information and error logs
- Check if the issue has already been reported
- Use the GitHub issue tracker with the "enhancement" label
- Describe the feature and its benefits clearly
- Consider the impact on existing functionality
- Spec-Driven Development (SDD): All feature requests should ideally be accompanied by a spec update in the
openspec/folder- Review existing specs in
openspec/specs/to understand current capabilities - Create a change proposal in
openspec/changes/following the OpenSpec OPSX workflow (or legacy openspec/AGENTS.md if present) - This ensures clear requirements, scenarios, and implementation guidance before coding begins
- Review existing specs in
- Fork the repository
- Review OpenSpec specs: Check
openspec/specs/to understand existing capabilities - Create spec proposal (if needed): For new features, create a change proposal in
openspec/changes/following the OpenSpec OPSX workflow (or legacy openspec/AGENTS.md if present) - Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes following the coding standards below
- Update specs: Ensure
openspec/specs/reflects your changes - Test your changes: Run
hatch test --cover -vto ensure all tests pass - Commit your changes: Use Conventional Commits format
- Push to your fork:
git push origin feature/your-feature-name - Create a Pull Request: Provide a clear description of your changes and reference any OpenSpec change proposals
- Python 3.10+
- Docker (for containerized development)
- Git
# Clone the repository
git clone https://github.com/nold-ai/specfact-cli.git
cd specfact-cli
# Install dependencies
pip install -e ".[dev]"
# Run contract-first tests
hatch run contract-test-full
# Run all tests
hatch test --cover -v- Python: Follow PEP 8 style guidelines
- Contracts: All public APIs must have
@icontractdecorators - Type Hints: Use type hints with
@beartyperuntime checking - Testing: Contract-first testing with scenario tests
- Documentation: Update relevant documentation
- Docs site (
docs/): Jekyll pages keep existing frontmatter (layout,title,permalink, …). Pages listed indocs/.doc-frontmatter-enforcedmust includedoc_owner,tracks,last_reviewed, andexempt;exempt_reasonis required only whenexempt: true. See docs/contributing/docs-sync.md. - Docstrings: Follow Google Python Style Guide
Local hooks use fail_fast: true and a modular layout aligned with specfact-cli-modules:
branch-aware module verify (skip if no staged module tree changes; flags from scripts/module-verify-policy.sh — strict on main, relaxed PR-style verify elsewhere) → sync version files when those paths are staged → format (always) →
YAML / Markdown / workflow lint when matching paths are staged → hatch run lint when Python
is staged → Block 2 (scoped code review + contract tests, with a safe-change short-circuit for
docs-only and similar commits). See .pre-commit-config.yaml and scripts/pre-commit-quality-checks.sh.
# Install framework hooks (recommended; matches CI-style stages)
pre-commit install
# Optional: copy raw script into .git/hooks/pre-commit (runs full `all` pipeline via shim)
scripts/setup-git-hooks.sh
# Manual full pipeline (same as shim)
hatch run pre-commit-checks
# Format code
hatch run format
# Type check
hatch run type-check
# Lint code
hatch run lint
# Run contract-first tests
hatch run contract-test-fullThe supported local hook path is the repo-owned smart-check wrapper installed by the commands above. It keeps local semantics aligned with CI:
- Merge-blocking local gates: module signature verification (branch-aware; see
scripts/pre-commit-verify-modules.sh), formatter safety, Markdown/YAML checks, workflow lint for staged workflow changes, and contract-test fast feedback when code changes. - Review gate behavior:
specfact code review runreviews staged Python files and blocks the commit only onFAIL.PASS_WITH_ADVISORYremains green but still prints the JSON report path for remediation in Copilot/Cursor. - Advisory review surfaces: CodeRabbit and other PR review comments remain advisory unless a branch protection rule explicitly promotes a check to required.
- Workflow linting requires
actionlintonPATHor a Docker-enabled environment. CI installs a pinnedactionlintrelease explicitly; local contributors should install it globally, for example withgo install github.com/rhysd/actionlint/cmd/actionlint@v1.7.11.
Before we can accept your pull request, you need to agree to our Contributor License Agreement. By opening a pull request, you acknowledge that you've read and agreed to the terms.
The CLA ensures that:
- SpecFact CLI can use your contributions in any way needed
- You're not liable for your contributions
- The project can relicense code if necessary
- Enterprise users can trust the codebase
This project uses various third-party libraries listed in pyproject.toml. Each library retains its original license. For license information on specific dependencies, please refer to the individual package documentation.
# Run contract validation
hatch run contract-test-contracts
# Run contract exploration (CrossHair)
hatch run contract-test-exploration
# Run scenario tests
hatch run contract-test-scenarios
# Run all contract-first tests
hatch run contract-test-full
# Run specific test file
hatch test --cover -v tests/unit/specfact_cli/test_cli.py- Write contracts (
@icontractdecorators) for all new public APIs - Add property-based tests with Hypothesis for complex logic
- Write scenario tests for CLI command workflows
- Use descriptive test names following
test_<command>_<scenario>pattern - Ensure tests are deterministic and fast
SpecFact CLI uses Spec-Driven Development (SDD) via OpenSpec to ensure clear requirements and maintainable code.
- Review existing specs: Check
openspec/specs/to understand current capabilities - Create change proposals: For new features or significant changes, create proposals in
openspec/changes/ - Follow OpenSpec guidelines: See OPSX migration and optionally
openspec/AGENTS.mdfor workflow instructions - Update specs: When implementing changes, update the relevant spec files to reflect the new behavior
Create a spec proposal when:
- Adding new features or functionality
- Making breaking changes (API, schema)
- Changing architecture or patterns
- Optimizing performance (changes behavior)
- Updating security patterns
Skip spec proposals for:
- Bug fixes (restore intended behavior)
- Typos, formatting, comments
- Dependency updates (non-breaking)
- Configuration changes
- Tests for existing behavior
- Project config (OPSX):
openspec/config.yaml- Schema, context, and per-artifact rules (primary) - Project overview (legacy):
openspec/project.md- High-level conventions (fallback if no config.yaml) - Workflow guide: OPSX migration; optionally
openspec/AGENTS.mdif present - Current specs:
openspec/specs/- Specifications for all capabilities - Active changes:
openspec/changes/- Proposed changes and implementations
- Update relevant documentation when adding features
- Include code examples where appropriate
- Follow the existing documentation style
- Test documentation examples
- Update OpenSpec specs: When implementing features, ensure
openspec/specs/reflects the new behavior
The repository README, docs/index.md, and other first-contact surfaces must preserve the same
first-contact story.
When editing those surfaces, make sure a new visitor can quickly answer:
- What is SpecFact?
- Why does it exist?
- Why should I use it?
- What do I get?
- How do I get started?
Keep the hierarchy in this order:
- Product identity
- Why it exists
- User value
- How to get started
- Deeper topology and cross-site handoff
For first-contact pages, define SpecFact as the validation and alignment layer for software delivery and present “keep backlog, specs, tests, and code in sync” as the user-visible outcome of that positioning.
GitHub-facing repo metadata must reinforce the same story. Keep the repository description, topics, and other above-the-fold cues aligned with the README hero so visitors see the same product identity before and after opening the repository.
README.md: Project overview and quick startAGENTS.md: Repository guidelines and development patternsopenspec/: Spec-Driven Development (SDD) specifications and change proposalsopenspec/config.yaml: OPSX project config (schema, context, rules)openspec/project.md: Legacy project conventions (used if no config.yaml)openspec/AGENTS.md: Legacy workflow instructions (optional after OPSX)openspec/specs/: Current capability specificationsopenspec/changes/: Proposed changes and implementations
.cursor/rules/: Cursor AI development rulesCONTRIBUTING.md: Contribution guidelines and workflow
- Follow Semantic Versioning
- Update
CHANGELOG.mdwith all changes - Update version in
pyproject.tomlandsetup.py
- All tests pass
- Documentation is updated
- CHANGELOG.md is updated
- Version numbers are updated
- Release notes are prepared
- GitHub Issues: For bugs and feature requests
- Documentation: Check the README.md first
- Discussions: Use GitHub Discussions for questions
- Email: hello@noldai.com
Contributors will be recognized in:
- The CHANGELOG.md
- The project README (for significant contributions)
- Release notes
Thank you for contributing to SpecFact CLI!
Copyright (c) 2025 Nold AI (Owner: Dominikus Nold)