Thank you for your interest in contributing to 1000Langs! This document provides guidelines and information for contributors.
This project uses a graduated trust model for contributions:
-
Who: Project maintainers only
-
Access: Direct commit to main branch
-
Scope: Architecture decisions, security-critical code, release management
-
Review: Self-review with documentation
-
Who: Trusted contributors with demonstrated expertise
-
Access: Protected branches, requires 1 maintainer review
-
Scope: Feature development, complex bug fixes, performance optimizations
-
Review: Code review by Perimeter 1 member
-
Who: All contributors
-
Access: Fork and pull request
-
Scope: Bug fixes, documentation, tests, minor features
-
Review: Code review by Perimeter 2+ member
-
Node.js 20+
-
Just command runner
-
Nix (recommended) or npm
-
Git
# Clone your fork
git clone https://github.com/YOUR_USERNAME/1000Langs.git
cd 1000Langs
# Add upstream remote
git remote add upstream https://github.com/Hyperpolymath/1000Langs.git
# Enter development environment
nix develop # or: npm install
# Run tests to verify setup
just test# Update main
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feature/your-feature-name-
Write code following the style guide
-
Add tests for new functionality
-
Update documentation as needed
-
Ensure SPDX headers are present
# Run all checks
just check
# Or individually:
just lint # Check code style
just typecheck # Type checking
just test # Run tests
just prove # Verify proofsWe follow conventional commits:
type(scope): description
[optional body]
[optional footer]
Types:
-
feat: New feature -
fix: Bug fix -
docs: Documentation changes -
style: Code style changes (formatting, etc.) -
refactor: Code refactoring -
test: Adding or updating tests -
chore: Maintenance tasks -
perf: Performance improvements -
proof: Proof additions or updates
Example:
feat(crawler): add support for ebible.org source
Implements the eBible crawler with support for USFM and USX formats.
Includes rate limiting and retry logic.
Closes #42
git push origin feature/your-feature-nameThen create a pull request on GitHub.
-
Use descriptive module and function names
-
Prefer pattern matching over if/else chains
-
Use labeled arguments for functions with multiple parameters
-
Add SPDX headers to all source files
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell and Contributors
/**
* Module documentation goes here.
*/
module MyModule = {
// ...
}-
Use AsciiDoc for documentation (not Markdown, except SECURITY.md)
-
Include code examples where helpful
-
Keep documentation close to the code
-
Test one thing per test
-
Use descriptive test names
-
Mock external dependencies
describe("Iso639.Validation", () => {
test("isValidIso639_3 returns true for valid codes", () => {
expect(Iso639.Validation.isValidIso639_3("eng"))->toBe(true)
})
test("isValidIso639_3 returns false for invalid codes", () => {
expect(Iso639.Validation.isValidIso639_3("english"))->toBe(false)
})
})-
Test interactions between modules
-
Use realistic test data
-
Clean up after tests
-
Verify mathematical properties
-
Document proof obligations
-
Link to formal specifications
-
All tests pass (
justtest) -
Code is formatted (
justformat) -
No linting errors (
justlint) -
Types check (
justtypecheck) -
Documentation updated if needed
-
SPDX headers present on new files
-
Conventional commit messages used
## Summary
Brief description of changes.
## Changes
- Change 1
- Change 2
## Testing
How was this tested?
## Checklist
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] CHANGELOG.md updated-
Automated checks must pass
-
At least one approval from appropriate perimeter
-
All comments addressed
-
Squash merge preferred
Include:
-
ReScript/Node.js version
-
Operating system
-
Steps to reproduce
-
Expected vs actual behavior
-
Error messages/logs
Include:
-
Use case description
-
Proposed solution
-
Alternatives considered
-
Willingness to implement
Do not report security vulnerabilities through public issues.
See SECURITY for responsible disclosure guidelines.
By contributing to 1000Langs, you agree that your contributions will be licensed under the project’s dual MIT + Palimpsest v0.8 license.
-
Open a discussion on GitHub
-
Check existing issues and discussions
-
Review the documentation
Thank you for contributing!
Every commit that reaches the default branch must be signed; a ruleset refuses unsigned pushes. Estate policy: SIGNING-POLICY.
- People and interactive agents sign with an SSH key registered on GitHub
as a signing key (
gpg.format=ssh,user.signingkey=<key>.pub,commit.gpgsign=true). The committer email must be verified on that account. - Apps, bots and workflows never
git pushlocal commits. They write through the API (createCommitOnBranchor the estatesigned-pushaction) so that GitHub signs each commit. - Merge PRs with squash. The ruleset checks every commit on the PR branch,
not just the result, so one unsigned commit blocks the merge. Re-create such a
branch with signed commits (
git cherry-pick -S) and open a new PR. Rebase-merge replays commits unsigned and is disabled.