7.4 KiB
AGENTS.md
Platform and build
Production packages target Linux x86-64 AMD Strix Halo (gfx1151); Windows
is a supported native build target for development. CMake owns
compiler flags, dependencies and installation; Nix supplies the pinned toolchain.
Linux source-build prerequisites are in README.md.
nix build # development package, all discovered extensions
nix build .#release # shipped lock-mode package, no tests/tools
./result/bin/gufo diagnose
nix flake check # hosted CPU/repository checks
nix develop # GPU development and reference tools
# Same production build without Nix, with the documented dependencies installed
cmake --preset release # discovery build
# Add -DGUFO_EXTENSIONS_FROM_LOCK=ON for the shipped extension selection.
cmake --build --preset release --parallel 4
Stage only task-owned paths before Nix builds; flakes include tracked files.
Measure performance with result/bin/gufo or build/release/gufo. Preserve
compiler/dependency versions when comparing results.
Focused tests
Formatting and Python repository checks may run on the editing host; they do not need the remote GPU. Before committing C++ changes, run the shared CI check:
nix shell --inputs-from . nixpkgs#clang-tools -c python3 tools/ci/check-format.py
# Add --fix to apply formatting, then rerun the check.
Tests selected by nix flake check should stay fast and cache-friendly where
possible. Reuse expensive setup and compiler caches when valid, use the smallest
deterministic fixtures that preserve the assertions, and avoid redundant builds,
fixed sleeps and repeated whole-tree work. Measure added wall time; keep expensive
stress/model qualification explicitly selectable without weakening correctness.
Run the smallest check covering the change. gpu-test is RelWithDebInfo with
assertions enabled. Build only the affected target during iteration:
nix develop -c cmake --preset gpu-test
nix develop -c cmake --build --preset gpu-test --target <test-target>
nix develop -c ctest --preset gpu-full -R '^<test-name>$' --output-on-failure
The same CMake/CTest commands work outside Nix. cmake --build --preset pr
runs the focused contract subset after configuring cpu-test; nix flake check
runs the canonical CPU/repository gate. Full CPU checks,
sanitisers, GPU/operator/model checks and H3 quality tools remain available
locally; see docs/TESTING.md. Do not run full model sweeps,
video generation or duplicate suites for routine edits. A missing-model skip
is not a quality pass. Broaden checks when shared behavior changes or failures
expose risk.
Text API functional/regression tests live in tests/functional/.
Select suites explicitly. Model-specific changes need the affected model/modes;
use all four profiles only for shared behavior changes. Run correctness on the
candidate; use main for matched affected timing controls and suspected regressions,
not a duplicate full correctness run. Reuse baseline evidence only when revision,
toolchain, harness, model, settings and cache history match. Include long-context
and cache for continuation changes; verify loaded mode and actual drafts.
Correctness and expected prefill/cache work are strict; timings are
mandatory per request/phase at 5% and 10 ms, never averaged across requests.
Run once, investigate flags, then alternate main/PR only for affected histories;
use unchanged-main controls when needed and retain every result. Fix confirmed
regressions before publishing. Noisy evidence stays visibly inconclusive and
unqualified; do not widen margins or stop at reporting failures. Devlab keeps
inconclusive timing advisory on both ordinary and release PRs. Use the code
diff to select affected metrics; unrelated timing variance does not justify
another full matrix.
For reported coding-agent loops, also replay the affected workflow with
tests/functional/pi_agent.py; retain its sessions and inspect actual tool results.
Retain numerical quality tests and the standard speed benchmark. Keep these
tests in tests/functional/, outside hosted model CI; avoid full sweeps.
Profiling and kernels
Apply .agents/skills/optimize-kernel/SKILL.md.
Use tools/bench/build.sh for standalone HIP experiments,
tools/bench/gfx1151_peak.hip for measured hardware ceilings,
tools/prof/prof.py for pipeline/wall-time profiles, and
tools/prof/isa_mix.py for instruction analysis. Production paths must retain
quality; successful optimizations become the default, without extra switches.
Development
- Keep model code, tests, tools and numerical contracts with their model.
- Use the shared Qwen control-token constants for framing; see src/families/qwen/AGENTS.md. Inspect their definitions when reviewing or changing behavior, and keep reference fixtures independent.
- Put Windows-specific code in
src/core/platform/: one leaf per OS facility (files, pages, sockets), whose sources may branch on_WIN32or split into<leaf>_posix.cpp/<leaf>_windows.cppselected in CMake. Outside it and vendored code, call the leaf, with nowindows.hor_WIN32/_MSC_VERchecks. POSIX code moves into a leaf, verbatim, once it gains a Windows counterpart. Never emulate POSIX with macros or copy a file per OS; when the logic itself differs, add<file>_windows.cppbeside it. - Use one canonical long option and backend name per behavior; avoid aliases.
- Use
ghfor GitHub operations after checkinggh auth status. - Follow Conventional Commits with a single-line message. Title pull requests
according to the release policy; squash merging retains
that title on
main. Mark breaking changes with!in the title, and leave version and changelog updates to the release workflow. - Prefer
jjwhen available (jj version); otherwise use Git. - The source extension API is versioned independently from Gufo. Public headers
under
include/gufo/ext/, their transitiveSURFACEclosure (including forwarded core/cache headers), the metadata schema and public CMake contracts require anext-apiPR label and one new, uniquely named Markdown record underinclude/gufo/ext/changes/<major>.<minor>/when declarations/contracts change. Records are permanent and immutable. CMake derives the API revision from the active series ininclude/gufo/ext/api-series.jsonplus its revision-record count. Thebaseline.mdrecord documents the initial contracts without advancing it. Do not manually bump versions for additive changes. Runpython3 tools/ci/check-extension-api.py --writeafter header/include changes; the PR diff gate also checks forwarded declarations. Before 1.0, a minor bump may break extensions; revision bumps are additive. Fix in-tree users together. The guarantee is source compatibility after rebuilding, never binary ABI. Breaking changes explicitly advance the compatibility series in api-series.json and add a record in the new series, retaining all historical records. Extension API and the future experimental flakeextensionsargument are excluded from Gufo's release compatibility surface; CLI/HTTP/public existing flake breaks still require!. See the release policy. - Follow the user's remote workflow and preserve unrelated work.