← Commit history
docs: add GitHub community files and tools/bench_compare.sh performance gate
lennoxrose committed on Oct 19, 2026 at 02:44 UTC
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 Conduct2
+3
+## Our Pledge4
+5
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free6
+experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex7
+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 healthy11
+community.12
+13
+## Our Standards14
+15
+Examples of behavior that contributes to a positive environment for our community include:16
+17
+* Demonstrating empathy and kindness toward other people18
+* Being respectful of differing opinions, viewpoints, and experiences19
+* Giving and gracefully accepting constructive feedback20
+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience21
+* Focusing on what is best not just for us as individuals, but for the overall community22
+23
+Examples of unacceptable behavior include:24
+25
+* The use of sexualized language or imagery, and sexual attention or advances of any kind26
+* Trolling, insulting or derogatory comments, and personal or political attacks27
+* Public or private harassment28
+* Publishing others' private information, such as a physical or email address, without their explicit permission29
+* Other conduct which could reasonably be considered inappropriate in a professional setting30
+31
+Technical disagreement is welcome and expected: attack the code, the benchmark or the argument, never the person.32
+33
+## Enforcement Responsibilities34
+35
+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will36
+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, wiki40
+edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate41
+reasons for moderation decisions when appropriate.42
+43
+## Scope44
+45
+This Code of Conduct applies within all community spaces (issues, pull requests, discussions, and any other46
+place the project is represented), and also applies when an individual is officially representing the47
+community in public spaces.48
+49
+## Enforcement50
+51
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders52
+responsible for enforcement by contacting the maintainer [@lennoxrose](https://github.com/lennoxrose) through53
+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 to55
+respect the privacy and security of the reporter of any incident.56
+57
+## Enforcement Guidelines58
+59
+Community leaders will follow these Community Impact Guidelines in determining the consequences for any60
+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 an64
+ 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 people67
+ involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified68
+ 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 for71
+ a specified period of time.72
+4. **Permanent Ban**: Demonstrating a pattern of violation of community standards, including sustained73
+ inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of74
+ individuals.75
+ *Consequence*: A permanent ban from any sort of public interaction within the community.76
+77
+## Attribution78
+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 Ash2
+3
+Thanks for helping. Ash is a from-scratch language in C with no external dependencies, and it stays fast on4
+purpose. Read this once; it is short.5
+6
+## The law: nothing gets slower7
+8
+**A change must never make Ash slower. A speed-up is welcome; a slowdown is rejected, whatever else it9
+brings.** This covers the VM (`hearth/ashvm/src/vm`), the compiler's fused ops, the front end, and the code10
+`kiln` generates. A feature that costs run-time speed must be restructured until it costs none (do the work11
+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
+```sh16
+# 1. baseline: build main and keep the binary17
+git checkout main && make @ashvm && cp bin/ashvm /tmp/ashvm_base18
+# 2. your branch19
+git checkout - && make @ashvm20
+# 3. compare every benchmark in hearth/ashvm/benchmarks (best of 7 alternating runs)21
+tools/bench_compare.sh /tmp/ashvm_base bin/ashvm22
+```23
+24
+It exits non-zero if any benchmark is more than 2% slower (the measured noise of identical code relinked in25
+a different order) or if the new binary fails on one. Paste its output into the PR. Changes to `kiln` code26
+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
+## Setup30
+31
+```sh32
+tools/install.sh # toolchain: gcc, make, Rust (mnemo), mingw, ...; --check only reports33
+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 repo38
+(or `ASH_PATH` pointing at its `src/main/ash`).39
+40
+## Tests41
+42
+Run the suites for what you touched, and `make` warning-free (`-Wall -Wextra -std=c11 -O2`):43
+44
+```sh45
+hearth/ashvm/tests/scripts/run_regression.sh46
+hearth/kiln/tests/scripts/run_regression.sh47
+hearth/front/tests/scripts/check_types.sh48
+hearth/mnemo/tests/scripts/run_regression.sh49
+hearth/apm/tests/scripts/smoke_test.sh50
+```51
+52
+Output must be byte-identical to the `.out` files unless the change is intentional. A new feature or a bug53
+fix comes with a test: `hearth/<project>/tests/cases/<feature>/Name.ash` plus its `.out`. A bug fix starts54
+with a test that fails.55
+56
+## Code rules57
+58
+- Follow the layout in `AGENTS.md`: mirrored `C/ H/ D/ O/` trees, about 20 files per directory, features in59
+ 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 requests66
+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 of71
+ "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 report2
+description: Something behaves wrongly, crashes, or produces different output on ashvm and kiln3
+labels: [bug]4
+body:5
+ - type: input6
+ id: version7
+ attributes:8
+ label: Version9
+ description: Output of `ashvm --version` (and `kiln --version` if kiln is involved), or the commit10
+ placeholder: ashvm beta-v0.1.011
+ validations: {required: true}12
+ - type: input13
+ id: platform14
+ attributes:15
+ label: OS and architecture16
+ placeholder: Ubuntu 24.04, x86_6417
+ validations: {required: true}18
+ - type: dropdown19
+ id: tool20
+ attributes:21
+ label: Which tool22
+ options: [ashvm, kiln, apm, "ashvm and kiln differ", other]23
+ validations: {required: true}24
+ - type: textarea25
+ id: program26
+ attributes:27
+ label: Minimal program28
+ description: The smallest `.ash` program that shows it, and the command you ran29
+ render: java30
+ validations: {required: true}31
+ - type: textarea32
+ id: expected33
+ attributes:34
+ label: Expected versus actual output35
+ validations: {required: true}36
+ - type: checkboxes37
+ id: checks38
+ attributes:39
+ label: Checked40
+ options:41
+ - label: It also happens with `memory-safety: off` / it does not (say which in the description)42
+ - label: I searched existing issues43
+ required: true.github/ISSUE_TEMPLATE/config.ymladded
+8−0@@ -0,0 +1,8 @@1
+blank_issues_enabled: false2
+contact_links:3
+ - name: Security vulnerability4
+ url: https://github.com/lennoxrose/ash/security/advisories/new5
+ about: Report security problems privately, not as a public issue.6
+ - name: Standard library (ash-stdlib)7
+ url: https://github.com/lennoxrose/ash-stdlib/issues8
+ 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 request2
+description: Propose a language feature, tool option or improvement3
+labels: [enhancement]4
+body:5
+ - type: textarea6
+ id: problem7
+ attributes:8
+ label: Problem9
+ description: What can you not do today, or do badly?10
+ validations: {required: true}11
+ - type: textarea12
+ id: proposal13
+ attributes:14
+ label: Proposal15
+ description: Syntax or behavior you would like, with a short example16
+ validations: {required: true}17
+ - type: textarea18
+ id: performance19
+ attributes:20
+ label: Cost21
+ description: >22
+ Ash never gets slower. How can this be done with no cost to programs that do not use it23
+ (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 regression2
+description: Something got slower between two versions or commits3
+labels: [performance]4
+body:5
+ - type: input6
+ id: versions7
+ attributes:8
+ label: Fast and slow versions9
+ placeholder: "fast: beta-v0.1.0, slow: a1b2c3d"10
+ validations: {required: true}11
+ - type: textarea12
+ id: bench13
+ attributes:14
+ label: Benchmark15
+ description: The program and the output of `tools/bench_compare.sh <fast ashvm> <slow ashvm>` or your timings16
+ validations: {required: true}.github/PULL_REQUEST_TEMPLATE.mdadded
+23−0@@ -0,0 +1,23 @@1
+## What and why2
+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
+## Checklist16
+17
+- [ ] No benchmark is slower than `main` (output above ends with `OK`)18
+- [ ] `make` builds warning-free19
+- [ ] Relevant suites pass with unchanged output: ashvm / kiln / front / mnemo / apm20
+- [ ] New test in `hearth/<project>/tests/cases/<feature>/` (feature or bug fix)21
+- [ ] `CHANGELOG.md` entry added at the top22
+- [ ] `README.md` updated if user-visible behavior changed23
+- [ ] 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 Policy2
+3
+## Supported versions4
+5
+Ash is in beta. Only the **latest release** (see the6
+[Releases page](https://github.com/lennoxrose/ash/releases/latest)) and `main` receive fixes.7
+8
+## Reporting a vulnerability9
+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 triggers15
+it, and what you expected versus what happened. Memory errors in `ashvm`, `kiln`'s generated code, the16
+compiler front end, `apm` (path handling, downloads) or the ownership pass (a use-after-free, a double free17
+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 new20
+version, and credited in the changelog unless you prefer otherwise.21
+22
+## Out of scope23
+24
+Bugs that need `memory-safety: off` or `System.free`, which are explicitly unchecked, and denial of service25
+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 help2
+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 in7
+ [`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/sh2
+# Performance gate: Ash must never get slower. Compares two ashvm binaries on hearth/ashvm/benchmarks3
+# 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_base9
+# git checkout -q - && make @ashvm && tools/bench_compare.sh /tmp/ashvm_base bin/ashvm10
+#11
+# Each program runs <runs> times per binary, alternating, and the best (minimum) time counts, which12
+# filters out machine noise. The default 2% tolerance is the measured link-layout noise of identical code13
+# (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 -eu16
+[ $# -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=025
+printf '%-16s %10s %10s %8s\n' benchmark base_s new_s ratio26
+for f in hearth/ashvm/benchmarks/*.ash; do27
+ 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=031
+ while [ "$i" -lt "$RUNS" ]; do32
+ 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
+ done36
+ 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 ;; esac42
+done43
+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; fi44
+exit $fail