Contributing
Repository structure, development setup, testing expectations, and contribution workflow for A.T.O.M.
Start with an existing GitHub issue, or use the repository's bug and feature issue forms to describe a reproducible problem. Issues are the public discussion route. Check the issue's priority, prerequisites and acceptance criteria before starting; see the product roadmap and desktop roadmap for context, and the live issue for current status.
This is the maintained contribution guide. The root CONTRIBUTING.md and README point here. Repository-specific coding instructions are in AGENTS.md.
Choose a small change
- Identify the issue's observable outcome and the files responsible for it. Confirm that required evidence or upstream work is available.
- Create a branch, for example
git switch -c fix/issue-82-contribution-guide. - Reproduce a bug with a focused regression test, make the smallest coherent fix, and run the affected tests first.
- Run the applicable full checks below, update documentation and add user-visible changes under Unreleased in CHANGELOG.md.
- Open a PR using the repository template. Explain the impact, link the issue, list actual validation commands/results, and include screenshots for UI changes. Mention any unrun check and its reason.
For an initial contribution, prefer bounded documentation, pure helpers or a clearly scoped workflow repair. RF equations, observation semantics, dataset provenance, optimizer objectives, request budgets, portable-project contracts and desktop security need maintainer review. A synthetic test or a successful run does not establish measured RF accuracy. Read modeling limits before proposing RF changes; external evidence gates remain in force.
Repository map and ownership boundaries
| Location | Responsibility | Useful starting point |
|---|---|---|
backend-go/ |
Gin routes, validation, jobs, dataset runtime and HTTP contracts | main.go, server_lifecycle.go and their
tests |
backend-go/raytracer/ |
Deterministic RF, geometry, spatial index and optimization | Focused implementation and table-driven tests |
frontend-react/src/components/ |
React UI and interaction | Component plus *.test.jsx |
frontend-react/src/hooks/ |
Workspace state and workflow orchestration | Relevant hook and workflow tests |
frontend-react/src/utils/ |
Pure helpers and *.test.js |
projectStore.js and
projectFileReliability.test.js for portable files |
core-lab-adapter/ |
Optional 5G-only Core Lab adapter | Separate Go module and tests |
data-pipeline/ |
Dataset manifest, LFS data, pack generation and QA | Validate a pack before changing data assumptions |
docs/ |
Markdown sources, generated reference HTML, search index and validators | Edit the source and rebuild generated pages |
examples/ |
Importable portable projects and public fixtures | Keep legacy input-only files compatible |
desktop/spike/ |
Disposable qualification probes | Evidence for desktop gates, not a production shell |
Keep API input validation at routes and preserve cancellation
contexts. Use gofmt for Go, exported PascalCase names where
appropriate, PascalCase component filenames, use-prefixed
hooks and camelCase helpers. Prefer focused modules and pure utilities
to expanding App.jsx. Preserve deterministic ordering and
the existing 4G/5G/6G availability contract.
Get a complete checkout
Install Git and Git LFS before cloning. Docker Engine with Compose or Docker Desktop is sufficient to run the full app; source development also needs Node.js 24 or newer and the Go version declared in backend-go/go.mod and core-lab-adapter/go.mod. CI reads those module files. Documentation and data tooling use Python 3.12 in CI.
git lfs install
git clone https://github.com/Berk-Unsal/atom.git
cd atom
git lfs pullThe Ankara building GeoJSON is about 111 MiB. A small file starting
with version https://git-lfs.github.com/spec/v1 is a
pointer, not a usable dataset. Fetch its LFS object before building or
validating the pack. Do not regenerate the dataset to work around a
missing LFS download.
Run the full app with Docker
From the repository root:
docker compose up --build -d atom
curl --fail http://localhost:8080/readyz
docker compose logs -f atomWait for /readyz to return success, then open
http://localhost:8080. Readiness covers dataset and
frontend assets; /healthz only checks liveness. Use
docker compose down from the root to stop the app. Internet
access is needed for the initial build and online basemap tiles. The
optional Core Lab profile is documented in Download and Use.
Develop with Go and Vite
Run these in separate terminals, each starting at the repository root:
# Terminal 1: existing Go HTTP API
cd backend-go
go mod download
go run .# Terminal 2: shared React frontend
cd frontend-react
npm ci
npm run devOpen http://localhost:5173. Vite proxies API traffic to
port 8080. Check http://localhost:8080/healthz and
http://localhost:8080/api/meta for the API/dataset, and
verify that Vite serves the UI. In this split workflow
/readyz can report missing frontend assets until
npm run build creates frontend-react/dist; it
is the combined-server readiness check, not a prerequisite for Vite HMR.
A dataset error still needs fixing. Stop a competing Compose instance
before reusing port 8080.
Validate the public pack from backend-go:
go run ./cmd/validate-dataset ../data-pipelineSet up documentation and Python tools
From the repository root, use a Python 3.12 virtual environment. Install the hash-pinned documentation lock without source builds or dependency re-resolution:
python3.12 -m venv .venv
. .venv/bin/activate
python -m pip install --require-hashes --only-binary=:all: -r docs/requirements.txtInstall Pandoc 3.10 exactly, the version required by
docs/build-reference-pages.sh and the documentation
workflows. Confirm pandoc --version before building; a
newer version can change committed HTML. The build script rejects
another version.
Only data-pipeline work needs the separate scientific/geospatial Python environment:
python -m pip install --require-hashes --only-binary=:all: -r data-pipeline/Requirements.txtDirect dependency inputs are in the matching .in files.
For an intentional dependency update, use uv==0.12.0 and
the lock-generation command recorded at the top of the relevant
lockfile; commit the input and lock together. Do not edit hashes by
hand.
Choose focused checks, then full validation
Run the narrow regression test while editing. These examples use real existing tests and files:
# From frontend-react: portable-project helpers
npm test -- src/utils/projectFileReliability.test.js
# From backend-go: HTTP server lifecycle
go test . -run TestServeHTTPServerDrainsInflightRequestOnShutdown -count=1
# From the repository root: documentation builder tests
python3 -m unittest discover -s docs -p 'build_reference_pages_test.py'Use the appropriate rows before opening a PR. Commands in a row run in the stated directory; a UI bug needs an interaction regression and relevant responsive browser checks. Frontend tests use Vitest with React Testing Library; browser workflows use Playwright.
| Change surface | Directory | Full checks |
|---|---|---|
| React/UI/helpers | frontend-react |
npm run lint, npm test,
npm run build, npm run audit:security |
| Browser workflows | frontend-react |
npx playwright install --with-deps chromium, then
npm run test:e2e |
| Go API/RF | backend-go |
go vet ./..., go test -race ./...,
go run ./cmd/validate-dataset ../data-pipeline |
| Core Lab | core-lab-adapter |
go vet ./..., go test -race ./... |
| Go vulnerability checks | Each affected Go module | go install golang.org/x/vuln/cmd/govulncheck@v1.6.0,
then govulncheck ./... (ensure Go's bin directory is on
PATH) |
| Python data tooling | Repository root | Install the data lock, import
geopandas, numpy, osmnx, pandas, shapely, then
python -m compileall -q -x '/\.venv/' data-pipeline |
| Documentation | Repository root | Run the documentation commands below |
| Version/policy/dependency metadata | Repository root | Run the consistency commands below |
The default Playwright suite uses its configured local Vite server
and mocked API workflows. Real-backend qualification is separate; see frontend-react/playwright.config.js
and the ATOM_REAL_E2E tests. Default browser tests do not
establish real-pack RF parity or native desktop compatibility.
Documentation checks
Edit Markdown sources rather than generated reference HTML. The build mapping is in docs/build-reference-pages.sh. From the root, with the documentation environment active and Pandoc 3.10 on PATH:
sh docs/build-reference-pages.sh
node --check docs/assets/docs.js
node --check docs/assets/docs-theme.js
python3 -m unittest discover -s docs -p '*_test.py'
python3 docs/validate_claims.py
python3 docs/validate_docs.pyCommit the changed generated HTML,
docs/search-index.json and any generated theme asset
alongside source changes. Rebuilding a second time should leave those
outputs unchanged. Preview locally with
python3 -m http.server 9000 --directory docs and open
http://localhost:9000. Link/asset and strict OpenAPI
validation run in validate_docs.py.
Consistency checks
From the repository root:
python3 scripts/versioning.py check
python3 scripts/check_runtime_versions.py
python3 scripts/check_supply_chain.py
python3 scripts/check_workflow_action_pins.py
python3 -m unittest scripts/check_supply_chain_test.py scripts/check_workflow_action_pins_test.py
python3 scripts/generate_policy.py --check
python3 -m unittest scripts/generate_policy_test.pyQuality CI is the full source of required gates, including dependency review and production container/SBOM vulnerability scans. Use it to check current pins and additional checks for the changed surface. Passing a focused test alone does not replace the affected CI jobs.
Pull requests and releases
Use concise imperative Conventional Commit-style subjects such as
fix: preserve per-cell network azimuths or
docs: clarify model limits. Keep a PR scoped to a
reviewable outcome. Include a regression for every bug fix and describe
any change to compatibility or scientific assumptions explicitly.
VERSION
is canonical. Normal contributor PRs record user-visible changes under
Unreleased; they do not edit main.go
version strings or publish tags. Maintainers prepare a release through
scripts/versioning.py,
update the release metadata/changelog together, check consistency, and
create the matching vX.Y.Z tag. CI then publishes the
configured images and release notes. See release.yml
for the release workflow.
For questions, proposals and blockers, use GitHub Issues. Share only public-safe logs and fixtures; omit private route recordings, credentials and operator data.