The assembly swiss army knife — built with discipline, shipped with intent.
Thank you for considering a contribution to fz. This document establishes the standards and workflow expected of all contributors. Please read it in full before opening issues or submitting pull requests.
- Code of Conduct
- Getting Started
- Development Setup
- Building and Testing
- Code Standards
- Commit Convention
- Pull Request Process
- Proposing New Features
- Reporting Issues
- License
All contributors are expected to engage professionally and constructively. Disrespectful, dismissive, or hostile behaviour will not be tolerated. We are here to build good software together.
Contributions are welcome in the following forms:
- Bug reports — reproducible, well-documented issues filed via GitHub Issues
- Feature proposals — opened as issues before any implementation begins
- Pull requests — bug fixes, features, refactors, or documentation improvements
- Documentation — corrections, clarifications, and examples
Run the following commands locally. If any of them fails, fix it before opening the PR:
go fmt ./...
go mod tidy
go test -race ./...
go vet ./...
staticcheck ./...| Requirement | Version |
|---|---|
| Go | ≥ 1.21 |
| NASM | any recent |
| GCC + Binutils | any recent |
| Clang (optional) | for sanitizer tests |
git clone https://github.com/forgezero-cli/ForgeZero.git
cd ForgeZero# Required for assembly tests
sudo apt install nasm gcc binutils
# Optional: strict sanitizer tests
sudo apt install clanggo build -o fz ./cmd/fzgo test ./... -covergo test -race ./...Install staticcheck if not already present:
go install honnef.co/go/tools/cmd/staticcheck@latestThen run:
go vet ./...
staticcheck ./...All checks must pass with zero warnings before a pull request is considered ready for review.
-
Formatting — run
go fmt ./...before every commit; no exceptions -
Functions — keep them small, focused, and with a single clear responsibility
-
Naming — use meaningful, unambiguous names; avoid abbreviations unless they are idiomatic in Go
-
Comments — omit comments where the code is self-explanatory; add them only where intent cannot be inferred from reading the code
-
Coverage — new code must not decrease the overall test coverage percentage
-
Error handling — every error must be handled explicitly; do not swallow errors silently
-
Tests must pass — no pull request will be reviewed if
go test ./...fails -
No debugging code — remove all
fmt.Println,log.Print, or commented-out code before committing -
No panic (except unrecoverable errors) — use error returns where possible
Every pull request must include proof that all tests pass. No exceptions.
Run these commands before submitting your PR:
# Full test suite with race detection (MUST pass)
go test -race ./...
# Verbose output for clarity (MUST pass)
go test -v ./...
# Performance benchmarks (must not regress)
go test -bench=. -run=^$ ./...If any of these commands fails, your PR will be rejected automatically.
All new functionality must be placed in internal/ with the following structure:
internal/your_feature_name/
├── feature.go # core logic
├── feature_test.go # unit tests (MANDATORY)
└── ... # any auxiliary files
Rule: feature_test.go must exist. No tests = no merge.
# Run tests for a specific feature
go test -v ./internal/your_feature_name/...
# Run a specific test function by name
go test -v -run TestFunctionName ./internal/your_feature_name/...
or ./fz -alex
ForgeZero Test Runner (v4.8.0-dev)
────────────────────────────────────────────────────────────
[✓] Environment Check (doctor) [PASS] (36 ms)
[✓] Unit Tests (go test -race) [PASS] (8090 ms)
[✓] Code Coverage [PASS] (2007 ms)
[✓] Static Analysis (go vet) [PASS] (397 ms)
[✓] Linter (staticcheck) [PASS] (0 ms)
[✓] Code Formatting (go fmt) [PASS] (94 ms)
[✓] Build Test (fz build) [PASS] (1468 ms)
[✓] Gloria Compilation [PASS] (2 ms)
[✓] HADES Codegen [PASS] (0 ms)
[✓] Integration Tests [PASS] (178 ms)
[✓] Citadel Zero-Allocations [PASS] (1748 ms)
[✓] Race Detector (full) [PASS] (14345 ms)
[✓] Aegis Audit [PASS] (131 ms)
────────────────────────────────────────────────────────────
STATUS: SUCCESS (13 stages passed, 28507 ms)
And if you add your new functional also make test in testrunner/Every function name must clearly describe what it does.
BAD:
func v(s string)
func proc(d []byte)
func f() intGOOD:
func PrintStringOnVGA(msg string) string
func ParseElfHeader(data []byte) (*ElfHeader, error)
func CalculateChecksum(buffer []byte) uint32Use descriptive names. Single-letter variables are forbidden except for short loops.
BAD:
v := something...
x := process(d)
t := time.Now()GOOD:
message := something...
result := process(data)
currentTime := time.Now()Exception: Loop indices (i, j, k) are allowed for short, simple loops.
| BAD | GOOD |
|---|---|
internal/x |
internal/elf_parser |
internal/utils |
internal/string_utils or internal/file_utils |
internal/feature |
internal/watchdog |
ForgeZero targets performance-critical environments. Avoid allocations where possible.
message := fmt.Sprintf("error: %s", err)
var buf bytes.Buffer
buf.WriteString(data)
tmp := []string{...}writeFmt(2, "error: %s\n", err)
buf := bytes.NewBuffer(make([]byte, 0, 4096))
var bufferPool = sync.Pool{
New: func() interface{} { return make([]byte, 4096) },
}go test -bench=. -benchmem ./...Look for 0 allocs/op in the output for performance-critical functions.
grep -r "fmt.Println\|fmt.Printf\|log.Print\|println(" internal/ cmd/ --include="*.go"writeFmt()writeStderr()- Logging via
-verbose
fmt.Printlnlog.Print(outside tests)println()
go test -race ./...passesgo test -v ./...passesgo test -bench=. -run=^$ ./...shows no regression- New features include
_test.go - No single-letter variables (except loop indices)
- No debug prints
go fmt ./...rungo vet ./...andstaticcheck ./...clean
Attach test output to your PR.
To protect the project's long-term maintainability and code quality, the following rules apply:
- No AI-generated code — code that is obviously machine-generated without human review will be rejected. We can tell.
- Plagiarism is forbidden — copying code or documentation from other contributors (or from external sources) without attribution is grounds for immediate PR closure and a permanent ban.
- You must build and test locally — if you cannot build
fzon your machine, do not open a PR. Figure out the build process first. - No "drive-by" PRs — every PR must include tests and documentation (if applicable). Skeleton PRs without content will be closed.
Violations will be reported to GitHub if repeated.
This project follows the Conventional Commits specification. All commit messages must conform to this format:
<type>: <short imperative summary>
| Type | When to use |
|---|---|
feat |
A new user-facing feature |
fix |
A bug fix |
test |
Adding or improving tests |
docs |
Documentation changes only |
refactor |
Code restructuring without behaviour change |
chore |
Tooling, CI, or dependency updates |
perf |
Performance improvements |
Examples:
feat: add --watch flag for incremental builds
fix: handle empty object files in linker stage
test: improve coverage for linker error paths
docs: document --output flag behaviour
refactor: extract runner into a standalone interface
Commit messages are part of the project's permanent history. Write them as if they will be read by someone debugging a regression two years from now — because they will be.
- Fork the repository and create a feature branch from
main - Write tests — all new behaviour must be covered; failure paths are not optional
- Verify —
go test -race ./...,go vet ./..., andstaticcheck ./...must all pass - Update documentation — if your change affects behaviour visible to users, update the relevant docs
- Open the PR with a clear title (following commit convention) and a description that explains:
- What changed
- Why it was changed
- Any relevant context or trade-offs
PRs that lack tests, break existing tests, or do not follow code standards will be returned for revision before review begins.
Open an issue before writing any code. This is not a bureaucratic step — it is a practical one. A brief discussion upfront saves everyone time by confirming the feature aligns with the project's direction before implementation begins.
A good feature proposal includes:
- The problem being solved
- The proposed solution or interface
- Any known trade-offs or alternatives considered
When filing a bug report, include the following:
fzversion — output offz -version- Operating system and architecture — e.g.
Linux amd64,macOS arm64 - Steps to reproduce — minimal, complete, and unambiguous
- Expected behaviour — what should have happened
- Actual behaviour — what happened instead
Reports that cannot be reproduced from the information provided may be closed without action.
By submitting a contribution, you agree that your work will be licensed under the MIT License that covers this project.
Thank you for taking the time to contribute to fz.
(c) alexvoste