← Commit history

docs: add GitHub community files and tools/bench_compare.sh performance gate

lennoxrose committed on Oct 19, 2026 at 02:44 UTC

42edb76parent1307bc7

11 files changed+349−0

.github/CODEOWNERSadded

+2−0
@@ -0,0 +1,2 @@
1+# Every file is reviewed by the maintainer; add narrower owners above this line as the project grows.
2+* @lennoxrose

.github/CODE_OF_CONDUCT.mdadded

+80−0
@@ -0,0 +1,80 @@
1+# Contributor Covenant Code of Conduct
2+
3+## Our Pledge
4+
5+We as members, contributors, and leaders pledge to make participation in our community a harassment-free
6+experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex
7+characteristics, gender identity and expression, level of experience, education, socio-economic status,
8+nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
9+
10+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy
11+community.
12+
13+## Our Standards
14+
15+Examples of behavior that contributes to a positive environment for our community include:
16+
17+* Demonstrating empathy and kindness toward other people
18+* Being respectful of differing opinions, viewpoints, and experiences
19+* Giving and gracefully accepting constructive feedback
20+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
21+* Focusing on what is best not just for us as individuals, but for the overall community
22+
23+Examples of unacceptable behavior include:
24+
25+* The use of sexualized language or imagery, and sexual attention or advances of any kind
26+* Trolling, insulting or derogatory comments, and personal or political attacks
27+* Public or private harassment
28+* Publishing others' private information, such as a physical or email address, without their explicit permission
29+* Other conduct which could reasonably be considered inappropriate in a professional setting
30+
31+Technical disagreement is welcome and expected: attack the code, the benchmark or the argument, never the person.
32+
33+## Enforcement Responsibilities
34+
35+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will
36+take appropriate and fair corrective action in response to any behavior that they deem inappropriate,
37+threatening, offensive, or harmful.
38+
39+Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki
40+edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate
41+reasons for moderation decisions when appropriate.
42+
43+## Scope
44+
45+This Code of Conduct applies within all community spaces (issues, pull requests, discussions, and any other
46+place the project is represented), and also applies when an individual is officially representing the
47+community in public spaces.
48+
49+## Enforcement
50+
51+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders
52+responsible for enforcement by contacting the maintainer [@lennoxrose](https://github.com/lennoxrose) through
53+GitHub (a private message, or a report through GitHub's "Report content" feature on the offending content).
54+All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to
55+respect the privacy and security of the reporter of any incident.
56+
57+## Enforcement Guidelines
58+
59+Community leaders will follow these Community Impact Guidelines in determining the consequences for any
60+action they deem in violation of this Code of Conduct:
61+
62+1. **Correction**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome.
63+ *Consequence*: A private, written warning, providing clarity around the nature of the violation and an
64+ explanation of why the behavior was inappropriate. A public apology may be requested.
65+2. **Warning**: A violation through a single incident or series of actions.
66+ *Consequence*: A warning with consequences for continued behavior. No interaction with the people
67+ involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified
68+ period of time. Violating these terms may lead to a temporary or permanent ban.
69+3. **Temporary Ban**: A serious violation of community standards, including sustained inappropriate behavior.
70+ *Consequence*: A temporary ban from any sort of interaction or public communication with the community for
71+ a specified period of time.
72+4. **Permanent Ban**: Demonstrating a pattern of violation of community standards, including sustained
73+ inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of
74+ individuals.
75+ *Consequence*: A permanent ban from any sort of public interaction within the community.
76+
77+## Attribution
78+
79+This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
80+version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

.github/CONTRIBUTING.mdadded

+74−0
@@ -0,0 +1,74 @@
1+# Contributing to Ash
2+
3+Thanks for helping. Ash is a from-scratch language in C with no external dependencies, and it stays fast on
4+purpose. Read this once; it is short.
5+
6+## The law: nothing gets slower
7+
8+**A change must never make Ash slower. A speed-up is welcome; a slowdown is rejected, whatever else it
9+brings.** This covers the VM (`hearth/ashvm/src/vm`), the compiler's fused ops, the front end, and the code
10+`kiln` generates. A feature that costs run-time speed must be restructured until it costs none (do the work
11+at compile time, behind a flag that is off by default, or in a path that only runs when the feature is used).
12+
13+Prove it, do not claim it. Before you open a PR:
14+
15+```sh
16+# 1. baseline: build main and keep the binary
17+git checkout main && make @ashvm && cp bin/ashvm /tmp/ashvm_base
18+# 2. your branch
19+git checkout - && make @ashvm
20+# 3. compare every benchmark in hearth/ashvm/benchmarks (best of 7 alternating runs)
21+tools/bench_compare.sh /tmp/ashvm_base bin/ashvm
22+```
23+
24+It exits non-zero if any benchmark is more than 2% slower (the measured noise of identical code relinked in
25+a different order) or if the new binary fails on one. Paste its output into the PR. Changes to `kiln` code
26+generation also need before/after timings of the compiled programs. Reference points: `fib(30)` about 0.06 s,
27+sum to 20M about 0.12 s.
28+
29+## Setup
30+
31+```sh
32+tools/install.sh # toolchain: gcc, make, Rust (mnemo), mingw, ...; --check only reports
33+make # clean build of everything into bin/
34+make @ashvm # clean build of one project (also @kiln, @apm, ...)
35+```
36+
37+The tests expect a checkout of [`ash-stdlib`](https://github.com/lennoxrose/ash-stdlib) next to this repo
38+(or `ASH_PATH` pointing at its `src/main/ash`).
39+
40+## Tests
41+
42+Run the suites for what you touched, and `make` warning-free (`-Wall -Wextra -std=c11 -O2`):
43+
44+```sh
45+hearth/ashvm/tests/scripts/run_regression.sh
46+hearth/kiln/tests/scripts/run_regression.sh
47+hearth/front/tests/scripts/check_types.sh
48+hearth/mnemo/tests/scripts/run_regression.sh
49+hearth/apm/tests/scripts/smoke_test.sh
50+```
51+
52+Output must be byte-identical to the `.out` files unless the change is intentional. A new feature or a bug
53+fix comes with a test: `hearth/<project>/tests/cases/<feature>/Name.ash` plus its `.out`. A bug fix starts
54+with a test that fails.
55+
56+## Code rules
57+
58+- Follow the layout in `AGENTS.md`: mirrored `C/ H/ D/ O/` trees, about 20 files per directory, features in
59+ folders, other languages only behind a C ABI header. Reuse an existing module before adding one.
60+- Match the surrounding code: naming, comment density, style. No new dependencies.
61+- Keep structural moves separate from behavior changes, so regression diffs stay meaningful.
62+- Add a `CHANGELOG.md` entry at the **top**, headed `## YYYY-MM-DD (topic)`, describing what really changed.
63+- Update `README.md` when user-visible behavior or layout changes.
64+
65+## Pull requests
66+
67+1. Open an issue first for anything big; small fixes can go straight to a PR.
68+2. One topic per PR, on a branch from `main`. Commit messages look like `feat(kiln): ...`, `fix(front): ...`.
69+3. Fill in the PR template, including the benchmark output.
70+4. A maintainer reviews. Correctness, memory safety and speed are the review criteria, in that order of
71+ "cannot be compromised".
72+
73+By contributing you agree that your contribution is licensed under the [MIT License](../LICENSE).
74+Everyone taking part follows the [Code of Conduct](CODE_OF_CONDUCT.md).

.github/ISSUE_TEMPLATE/bug_report.ymladded

+43−0
@@ -0,0 +1,43 @@
1+name: Bug report
2+description: Something behaves wrongly, crashes, or produces different output on ashvm and kiln
3+labels: [bug]
4+body:
5+ - type: input
6+ id: version
7+ attributes:
8+ label: Version
9+ description: Output of `ashvm --version` (and `kiln --version` if kiln is involved), or the commit
10+ placeholder: ashvm beta-v0.1.0
11+ validations: {required: true}
12+ - type: input
13+ id: platform
14+ attributes:
15+ label: OS and architecture
16+ placeholder: Ubuntu 24.04, x86_64
17+ validations: {required: true}
18+ - type: dropdown
19+ id: tool
20+ attributes:
21+ label: Which tool
22+ options: [ashvm, kiln, apm, "ashvm and kiln differ", other]
23+ validations: {required: true}
24+ - type: textarea
25+ id: program
26+ attributes:
27+ label: Minimal program
28+ description: The smallest `.ash` program that shows it, and the command you ran
29+ render: java
30+ validations: {required: true}
31+ - type: textarea
32+ id: expected
33+ attributes:
34+ label: Expected versus actual output
35+ validations: {required: true}
36+ - type: checkboxes
37+ id: checks
38+ attributes:
39+ label: Checked
40+ options:
41+ - label: It also happens with `memory-safety: off` / it does not (say which in the description)
42+ - label: I searched existing issues
43+ required: true

.github/ISSUE_TEMPLATE/config.ymladded

+8−0
@@ -0,0 +1,8 @@
1+blank_issues_enabled: false
2+contact_links:
3+ - name: Security vulnerability
4+ url: https://github.com/lennoxrose/ash/security/advisories/new
5+ about: Report security problems privately, not as a public issue.
6+ - name: Standard library (ash-stdlib)
7+ url: https://github.com/lennoxrose/ash-stdlib/issues
8+ about: Problems with ash.util, ash.io, ash.json and the other library packages.

.github/ISSUE_TEMPLATE/feature_request.ymladded

+24−0
@@ -0,0 +1,24 @@
1+name: Feature request
2+description: Propose a language feature, tool option or improvement
3+labels: [enhancement]
4+body:
5+ - type: textarea
6+ id: problem
7+ attributes:
8+ label: Problem
9+ description: What can you not do today, or do badly?
10+ validations: {required: true}
11+ - type: textarea
12+ id: proposal
13+ attributes:
14+ label: Proposal
15+ description: Syntax or behavior you would like, with a short example
16+ validations: {required: true}
17+ - type: textarea
18+ id: performance
19+ attributes:
20+ label: Cost
21+ description: >
22+ Ash never gets slower. How can this be done with no cost to programs that do not use it
23+ (compile-time work, an opt-in flag, a separate path)?
24+ validations: {required: true}

.github/ISSUE_TEMPLATE/performance_regression.ymladded

+16−0
@@ -0,0 +1,16 @@
1+name: Performance regression
2+description: Something got slower between two versions or commits
3+labels: [performance]
4+body:
5+ - type: input
6+ id: versions
7+ attributes:
8+ label: Fast and slow versions
9+ placeholder: "fast: beta-v0.1.0, slow: a1b2c3d"
10+ validations: {required: true}
11+ - type: textarea
12+ id: bench
13+ attributes:
14+ label: Benchmark
15+ description: The program and the output of `tools/bench_compare.sh <fast ashvm> <slow ashvm>` or your timings
16+ validations: {required: true}

.github/PULL_REQUEST_TEMPLATE.mdadded

+23−0
@@ -0,0 +1,23 @@
1+## What and why
2+
3+<!-- One paragraph. Link the issue: Fixes #123 -->
4+
5+## Performance (required)
6+
7+Ash must never get slower. Paste the output of `tools/bench_compare.sh /tmp/ashvm_base bin/ashvm`
8+(see CONTRIBUTING.md). For `kiln` code-generation changes, add before/after timings of compiled programs.
9+If the change cannot affect speed (docs, tests, tooling), say so.
10+
11+```
12+<output here>
13+```
14+
15+## Checklist
16+
17+- [ ] No benchmark is slower than `main` (output above ends with `OK`)
18+- [ ] `make` builds warning-free
19+- [ ] Relevant suites pass with unchanged output: ashvm / kiln / front / mnemo / apm
20+- [ ] New test in `hearth/<project>/tests/cases/<feature>/` (feature or bug fix)
21+- [ ] `CHANGELOG.md` entry added at the top
22+- [ ] `README.md` updated if user-visible behavior changed
23+- [ ] Follows the layout rules in `AGENTS.md` (mirrored `C/ H/ D/ O/`, small directories, no new dependencies)

.github/SECURITY.mdadded

+25−0
@@ -0,0 +1,25 @@
1+# Security Policy
2+
3+## Supported versions
4+
5+Ash is in beta. Only the **latest release** (see the
6+[Releases page](https://github.com/lennoxrose/ash/releases/latest)) and `main` receive fixes.
7+
8+## Reporting a vulnerability
9+
10+Please do **not** open a public issue for a security problem.
11+
12+Report it privately through GitHub: **Security tab -> [Report a vulnerability](https://github.com/lennoxrose/ash/security/advisories/new)**.
13+
14+Include the Ash version (`ashvm --version`), the platform, a minimal `.ash` program or input that triggers
15+it, and what you expected versus what happened. Memory errors in `ashvm`, `kiln`'s generated code, the
16+compiler front end, `apm` (path handling, downloads) or the ownership pass (a use-after-free, a double free
17+or a missed move on code that `memory-safety: on` accepts) are all in scope.
18+
19+You can expect an acknowledgement within a week. Confirmed issues are fixed on `main`, released as a new
20+version, and credited in the changelog unless you prefer otherwise.
21+
22+## Out of scope
23+
24+Bugs that need `memory-safety: off` or `System.free`, which are explicitly unchecked, and denial of service
25+by a program you chose to run (an infinite loop is a valid Ash program).

.github/SUPPORT.mdadded

+10−0
@@ -0,0 +1,10 @@
1+# Getting help
2+
3+- **A bug?** [Open a bug report](https://github.com/lennoxrose/ash/issues/new?template=bug_report.yml).
4+- **An idea?** [Open a feature request](https://github.com/lennoxrose/ash/issues/new?template=feature_request.yml).
5+- **A security problem?** Do not file an issue: see [SECURITY.md](SECURITY.md).
6+- **How do I use it?** Start with the [README](../README.md) and the programs in
7+ [`examples/`](../examples). Each has its expected output next to it (`.out`).
8+- **Standard library questions** belong to [ash-stdlib](https://github.com/lennoxrose/ash-stdlib).
9+
10+Please include `ashvm --version` (or `kiln --version`) and your OS with every report.

tools/bench_compare.shadded

+44−0
@@ -0,0 +1,44 @@
1+#!/bin/sh
2+# Performance gate: Ash must never get slower. Compares two ashvm binaries on hearth/ashvm/benchmarks
3+# and fails if the new one is slower than the baseline on any benchmark by more than the tolerance.
4+#
5+# tools/bench_compare.sh <baseline-ashvm> <new-ashvm> [runs=7] [tolerance-percent=2]
6+#
7+# Typical use, from a checkout of your branch:
8+# git stash -q 2>/dev/null; git checkout -q main && make @ashvm && cp bin/ashvm /tmp/ashvm_base
9+# git checkout -q - && make @ashvm && tools/bench_compare.sh /tmp/ashvm_base bin/ashvm
10+#
11+# Each program runs <runs> times per binary, alternating, and the best (minimum) time counts, which
12+# filters out machine noise. The default 2% tolerance is the measured link-layout noise of identical code
13+# (see CHANGELOG, "relinking the same ashvm objects ... moves single benchmarks by about 1.5%").
14+# A real regression is always a few percent or more; if the tool reports one, fix the code, not the number.
15+set -eu
16+[ $# -ge 2 ] || { sed -n '2,6p' "$0" | sed 's/^# \{0,1\}//'; exit 2; }
17+BASE=$1; NEW=$2; RUNS=${3:-7}; TOL=${4:-2}
18+cd "$(dirname "$0")/.."
19+[ -x "$BASE" ] && [ -x "$NEW" ] || { echo "bench_compare: both ashvm binaries must exist and be executable" >&2; exit 2; }
20+# the optional standard library is a sibling checkout unless ASH_PATH says otherwise (the hashmap benchmark needs it)
21+export ASH_PATH="${ASH_PATH:-$PWD/../ash-stdlib/src/main/ash}"
22+
23+now() { date +%s%N; }
24+fail=0
25+printf '%-16s %10s %10s %8s\n' benchmark base_s new_s ratio
26+for f in hearth/ashvm/benchmarks/*.ash; do
27+ n=$(basename "$f" .ash)
28+ "$BASE" run "$f" >/dev/null 2>&1 || { echo "bench_compare: baseline fails on $n; skipping" >&2; continue; }
29+ "$NEW" run "$f" >/dev/null 2>&1 || { echo "bench_compare: NEW BINARY FAILS on $n" >&2; fail=1; continue; }
30+ bb=""; nb=""; i=0
31+ while [ "$i" -lt "$RUNS" ]; do
32+ s=$(now); "$BASE" run "$f" >/dev/null 2>&1; e=$(now); bb="$bb $((e - s))"
33+ s=$(now); "$NEW" run "$f" >/dev/null 2>&1; e=$(now); nb="$nb $((e - s))"
34+ i=$((i + 1))
35+ done
36+ line=$(printf '%s\n%s\n' "$bb" "$nb" | awk -v n="$n" -v tol="$TOL" '
37+ NR == 1 { b = $1; for (i = 2; i <= NF; i++) if ($i < b) b = $i }
38+ NR == 2 { w = $1; for (i = 2; i <= NF; i++) if ($i < w) w = $i }
39+ END { r = w / b; printf "%-16s %10.4f %10.4f %8.3f%s\n", n, b / 1e9, w / 1e9, r, (r > 1 + tol / 100) ? " SLOWER" : "" }')
40+ echo "$line"
41+ case $line in *SLOWER) fail=1 ;; esac
42+done
43+if [ "$fail" = 0 ]; then echo "OK: no benchmark slower than the baseline by more than ${TOL}%"; else echo "FAIL: performance regression (or the new binary fails); see above" >&2; fi
44+exit $fail