Skip to content

Contributing to Harbour Credentials

Thank you for your interest in contributing to Harbour Credentials!

Getting Started

  1. Fork and clone the repository:
git clone https://github.com/YOUR_USERNAME/harbour-credentials.git
cd harbour-credentials

Submodules are cloned flat (direct submodules only) by just setup in the next step. To initialize them manually: git submodule update --init (do not force --depth 1). The LinkML compiler fork is installed as a .[dev] git dependency, not a submodule; the omb package is installed from PyPI by uv sync --extra dev (no OMB submodule required).

  1. Set up the development environment (requires uv and just, plus Node.js 22 with Corepack for TypeScript):
just setup

# `just` recipes run through `uv run` — activation is optional, only for
# direct python/pip commands:
# PowerShell
.\.venv\Scripts\Activate.ps1

# macOS / Linux / Git Bash
source .venv/bin/activate
  1. Verify everything works:
just test-full
just lint

Development Workflow

Branching

  • Create feature branches from main
  • Use descriptive branch names: feat/add-kb-jwt-support, fix/sd-jwt-verification

Making Changes

  1. Python code lives in src/python/harbour/ and src/python/credentials/
  2. TypeScript code lives in src/typescript/harbour/
  3. Tests live in tests/ (see structure in README)
  4. Documentation lives in docs/

Code Style

Python

  • Python 3.12+ with type hints on public APIs
  • Use pathlib.Path (not os.path)
  • All modules must have main() with argparse and --help
  • Run just lint and just format before committing

TypeScript

  • TypeScript 5.x with strict mode
  • Use async/await for crypto operations
  • Export types alongside functions
  • Run just lint-ts before committing

Testing

# Run all tests
just test-full

# Python only
just test

# TypeScript only
just test-ts

# Single Python test file
uv run --extra dev pytest tests/python/harbour/test_keys.py -v

# Single TypeScript test
cd src/typescript/harbour && corepack yarn vitest run --config vitest.config.ts ../../../tests/typescript/harbour/keys.test.ts

Feature Parity

When adding features, implement in both Python and TypeScript to maintain feature parity. Use consistent API naming:

Python (snake_case) TypeScript (camelCase)
generate_p256_keypair() generateP256Keypair()
sign_vc_jose() signVcJose()
verify_sd_jwt_vc() verifySdJwtVc()

Commit Guidelines

Commit Message Format

Use Conventional Commits:

feat(harbour): add KB-JWT verification
fix(sd-jwt): handle empty disclosure arrays
docs: update quickstart guide
test(interop): add cross-runtime signing test
chore: update dependencies

Signing Commits

All commits must be signed:

git commit -s -S -m "feat(harbour): add feature"
  • -s adds Signed-off-by line (DCO)
  • -S adds GPG signature

Pull Requests

Before Submitting

  • [ ] All tests pass (just test-full)
  • [ ] Linting passes (just lint)
  • [ ] Documentation is updated if needed
  • [ ] Commit messages follow conventional format
  • [ ] Commits are signed (-s -S)

PR Description

Include:

  • Summary of the changes
  • Testing performed
  • Related issues (e.g., Closes #42)

Architecture Decisions

Major design decisions are documented in Architecture Decision Records (ADRs):

When proposing significant changes, consider creating a new ADR.

Reporting Issues

  • Bugs: Include steps to reproduce, expected vs actual behavior, and environment details
  • Features: Describe the use case and proposed solution
  • Security: Report security vulnerabilities privately (do not create public issues)

Code of Conduct

Be respectful and inclusive. We welcome contributors of all backgrounds and experience levels.

License

By contributing, you agree that your contributions will be licensed under the EPL-2.0 License.