diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1f7ec5e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +# the tree is canonical byte for byte on every host: a windows checkout must not +# turn LF into CRLF, or `mach fmt --check` there reads a different file from the +# one that was formatted +* text=auto eol=lf diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000..049d58c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,34 @@ +--- +name: Bug +about: Defect, unexpected crash, or behavior contradicting specification +title: "" +labels: ["fix", "patch"] +--- + + + +## What + + + +## Repro + + + +## Expected + + + +## Actual + + + +## Environment + + diff --git a/.github/ISSUE_TEMPLATE/chore.md b/.github/ISSUE_TEMPLATE/chore.md new file mode 100644 index 0000000..bba4808 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/chore.md @@ -0,0 +1,22 @@ +--- +name: Chore +about: Routine upkeep, dependency bumps, code refactoring, or pruning +title: "" +labels: ["chore", "patch"] +--- + + + +## What + + + +## Acceptance + +- [ ] diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 0000000..bb88e96 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,22 @@ +--- +name: Feature +about: New capability, functional addition, or performance enhancement +title: "" +labels: ["feature", "minor"] +--- + + + +## What + + + +## Acceptance + +- [ ] diff --git a/.github/ISSUE_TEMPLATE/rfc.md b/.github/ISSUE_TEMPLATE/rfc.md new file mode 100644 index 0000000..35e93b5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/rfc.md @@ -0,0 +1,30 @@ +--- +name: RFC +about: Design discussion, architecture proposal, or open debate +title: "RFC: " +labels: ["discussion", "minor"] +--- + + + +## Problem + + + +## Proposal + + + +## Alternatives + + + +## Open Questions + +- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..2bd580f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ + +Closes # + +## What + + + +## Checklist +- [ ] Linked to an issue +- [ ] Conventional Commit messages +- [ ] Build and tests pass diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..d7ad273 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,15 @@ +name: CD + +# nothing is released yet. the release pipeline replaces this job. + +on: + workflow_dispatch: + +permissions: + contents: read + +jobs: + release: + runs-on: ubuntu-latest + steps: + - run: echo "no release pipeline yet" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6feb2f3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +name: CI + +# every pull request builds and tests on linux. a dispatch can name other +# runners to test a change on windows or darwin before it merges. + +on: + pull_request: + workflow_dispatch: + inputs: + runners: + description: runners to test on, as a JSON array, e.g. ["macos-15", "windows-latest"] + type: string + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + MACH_VERSION: 6.10.1 + +jobs: + # every runner builds every artifact for every target and tests the ones it can run + test: + name: test (${{ matrix.runner }}) + runs-on: ${{ matrix.runner }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + runner: ${{ fromJSON(inputs.runners || '["ubuntu-latest"]') }} + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v6 + - name: install mach + run: | + export MACH_INSTALL_DIR="$RUNNER_TEMP/mach" + url="https://raw.githubusercontent.com/briar-systems/mach/v$MACH_VERSION/dist" + if [ "$RUNNER_OS" = Windows ]; then + pwsh -NoProfile -Command "irm $url/install.ps1 | iex" + else + curl -fsSL "$url/install.sh" | sh + fi + echo "$MACH_INSTALL_DIR" >> "$GITHUB_PATH" + - run: mach dep pull . + - if: strategy.job-index == 0 + run: mach fmt --check . + - run: mach build . --all + - run: mach test . --all --timeout 10m + + gate: + if: always() + needs: [test] + runs-on: ubuntu-latest + steps: + - run: exit ${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && 1 || 0 }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89f9ac0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +out/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ceb86f0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dep/std"] + path = dep/std + url = https://github.com/briar-systems/mach-std diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..45e2ab1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +Each release groups its entries under `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed` and `Security`, and marks a breaking change inside the entry. + +## [Unreleased] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f0e2aec --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,110 @@ +# Contributing to mach-math + +Thank you for your interest in contributing to mach-math. Be respectful, +constructive, and professional. + + +## Building + +mach-math is built with the released Mach compiler that CI pins (`MACH_VERSION` in +`.github/workflows/ci.yml`). Install that release for your host and put `mach` +on `PATH`. + +```bash +git clone https://github.com/briar-systems/mach-math.git +cd mach-math +mach dep pull . +mach build . +``` + +The library artifact is `math`, whose entry is `src/lib/math.mach`. + +Dependencies are `[dep.]` tables in `mach.toml`, and the exact commit of +each is the committed gitlink under `dep/`. There is no lock file. +`mach dep pull .` realizes the committed pins and `mach dep update` moves them. + + +## Testing and formatting + +```bash +mach test . +mach fmt --check . +``` + +The tree is canonical: `mach fmt .` must leave it unchanged before a pull +request is opened. + +Unit tests cover the pieces that can be tested directly, each once, at the +layer that owns it. A table is checked by one test that walks its rows. There +are no regression tests: a defect is fixed in the code, and a test is added +only when the behaviour had no coverage. Checks that need outside tools, such +as agreement with reference implementations, round trips over a corpus and +validators, run locally and never in CI. CI builds every target and runs the +unit tests. + + +## Branching + +- `main` holds tagged releases only. It takes integration merges from `dev`. +- `dev` is the integration branch and the target of every pull request. +- `feat/` and `fix/` branch off `dev` and return to it. +- `hotfix/` branches off `main` and merges into both `main` and `dev`. + + +## Commits + +Commits are small, self-contained, and conventional. The issue number is the +scope: + +``` +fix(#1234): brief description + +Longer explanation if needed. +``` + +The types are `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `style`, +`ci`, and `perf`. A breaking change marks the type with `!` before the colon: +`feat(#139)!: brief description`. A change with no issue uses `chore: ...` with +no scope, and a release commit is `chore(release): `. + + +## Pull requests + +- Open as a draft targeting `dev`, and mark it ready when it is done. +- Link the issue with `Closes #N`. +- Leave `CHANGELOG.md` alone. The changelog is written from the merged + commits when `dev` is released to `main`. +- Say briefly what changed and which checks you ran. Every pull request runs + CI on linux. To test a windows or darwin change before it merges, dispatch + CI on the branch with `-f runners='["macos-15"]'` or another runner. +- Merge with a merge commit. Never rebase or fast-forward. +- When the target is not the default branch, close the linked issue by hand + after the merge. + + +## Issues + +File issues through the templates and label them across these sets: + +- SemVer magnitude: `patch`, `minor`, `major` +- Kind of work: `feature`, `fix`, `removal`, `chore`, `performance` +- Where: `testing`, `tooling`, `doc` +- Severity and state: `critical`, `blocked`, `parked`, `security` +- Discussion: `discussion` + +There are no milestones. Work in flight is an open draft pull request, `parked` +marks an issue deliberately set aside until something changes, and every other +open issue is backlog. Themes are epic issues with native sub-issues. + + +## Versioning + +mach-math follows [semantic versioning](https://semver.org/). A release bump updates +`[project].version` in `mach.toml`, and tags are created on `main` after the +integration merge from `dev`. + + +## License + +By contributing, you agree that your contributions will be licensed under the +[MIT License](LICENSE). diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d0545d9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2026 Briar Systems LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c86dae1 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# mach-math + +

+ CI + License +

+ +**A Mach library for vector-space math, starting with 4x4 matrices and quaternions.** + +## Usage + +Add the dependency to `mach.toml`: + +```toml +[dep.math] +git = "https://github.com/briar-systems/mach-math" +version = "^0.1" +``` + +Then bind the library in a source file: + +```mach +use math; +``` + + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for building, testing and the contribution rules. + + +## License + +[MIT](LICENSE) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..892b75b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +Security fixes are applied to the latest release only. Older releases are not patched. + +## Reporting a Vulnerability + +Please report security vulnerabilities privately through GitHub's +[private vulnerability reporting](https://github.com/briar-systems/mach-math/security/advisories/new) +rather than opening a public issue. + +mach-math parses no external formats, so its input is the numbers a caller passes in. A defect that makes math crash on valid input, or read or write out of bounds, is a vulnerability and is welcome as a report. + +Expect an acknowledgement within a few days. If the report is confirmed we will +prepare a fix and coordinate disclosure with you. If it is declined we will +explain why. diff --git a/dep/std b/dep/std new file mode 160000 index 0000000..ba2b27c --- /dev/null +++ b/dep/std @@ -0,0 +1 @@ +Subproject commit ba2b27c9fa62f6022032f0ddb231b15b8ef578f7 diff --git a/mach.toml b/mach.toml new file mode 100644 index 0000000..b44b2c6 --- /dev/null +++ b/mach.toml @@ -0,0 +1,68 @@ +[project] +id = "math" +version = "0.1.0" +mach = "^6.10" +src = "src" +out = "out/{target.name}/{profile.name}" + +[target.linux-x86_64] +isa = "x86_64" +os = "linux" +abi = "sysv64" + +[target.linux-aarch64] +isa = "aarch64" +os = "linux" +abi = "aapcs64" + +[target.windows-x86_64] +isa = "x86_64" +os = "windows" +abi = "win64" + +[target.darwin-x86_64] +isa = "x86_64" +os = "darwin" +abi = "sysv64" + +[target.darwin-aarch64] +isa = "aarch64" +os = "darwin" +abi = "aapcs64" + +# the library, what a dependent's `use math;` binds +[artifact.math] +kind = "static" +default = true +entry = "lib/math.mach" +out = "lib/math" +targets = ["*"] +link = ["kernel32"] +need = [] + +[link.kernel32] +source = "system" +name = "kernel32.dll" +os = ["windows"] +isa = ["*"] +abi = ["*"] +export = false + +[profile.debug] +default = true +opt = 0 +debug = true +simd = "scalarize" +vectorize = false +float_reassoc = false + +[profile.release] +opt = 2 +debug = false +simd = "scalarize" +vectorize = true +float_reassoc = false + +[dep.std] +git = "https://github.com/briar-systems/mach-std" +version = "^9.5" diff --git a/src/lib/math.mach b/src/lib/math.mach new file mode 100644 index 0000000..d66f475 --- /dev/null +++ b/src/lib/math.mach @@ -0,0 +1,5 @@ +# the math library, what a dependent's `use math;` binds +# Vector-space math, starting with 4x4 matrices and quaternions. + +# the startup a test dispatcher of this library links +use std.runtime;