Files
Just.PreciseMath/AGENTS.md
T
just cb2524980d
.NET Test / .NET tests (push) Successful in 1m9s
basic arithmetic benchmarks added
2026-09-14 00:04:39 +04:00

163 lines
8.8 KiB
Markdown

# Agent guidelines
These rules apply throughout this repository. Keep purpose, status, usage, and
development instructions in `README.md`; keep agent workflow rules here. Neither
file is a session log.
## Scope and repository map
This is a WIP .NET double-double arithmetic library, not arbitrary-precision math.
Do not claim API completeness or accuracy beyond tested contracts.
- `0-source/Just.PreciseMath/`: library implementation and package metadata.
- `1-tests/Just.PreciseMath.Tests/`: xUnit v3 tests, Shouldly assertions, and
Microsoft.Testing.Platform (MTP) with `coverlet.MTP` coverage.
- `2-benchmarks/Just.PreciseMath.Benchmarks/`: executable BenchmarkDotNet arithmetic
comparisons; use the Dry job for smoke validation, not performance conclusions.
- Root `Directory.Build.props` holds shared settings. Each numbered directory's
props explicitly imports it; preserve this import chain.
- `review-legacy/`: optional local reference material, excluded by `.gitignore`.
Start with `review-legacy/Review-Revisited-DoubleDouble.md` when present. The code
and proposed fixes contain known defects: reproduce findings against current
code rather than treating them as correctness oracles. Do not compile, copy
wholesale, or force-add these files. If absent, proceed without them; do not
invent their contents or make validation depend on them.
- Use the ignored, repository-local `.hermes/` directory for plans, checklists,
investigation notes, and handoff context. Create or update notes as useful;
keep them concise and revalidate them against current files. Optional
`.hermes/README.md` indexes active notes and `.hermes/project-context.md` holds
condensed implementation context. Treat `.hermes/archive/` as historical, not
current instructions or status. Do not store secrets, force-add this directory,
or make builds or tests depend on it.
## Working rules
- Check both staged and unstaged changes before starting. Preserve the user's
work and index; do not stage, commit, push, publish packages, or rewrite history
without an explicit request. Do not read or expose credentials.
- Read definitions, callers, tests, and relevant configuration before editing.
Limit changes to the request; do not implement the roadmap or repair unrelated WIP code.
- Reproduce numerical bugs with a failing regression test before fixing them.
For new behavior, define the contract and test cases before implementation.
Exercise sibling overloads and operand orders that can share the defect.
- Do not weaken analyzers, nullable checks, warnings-as-errors, or assertions to
get a green build. Explain necessary policy changes before making them.
- Keep dependencies minimal. Check existing references, compatibility, and current
stable releases before adding or upgrading packages.
## C# conventions
Follow `.editorconfig`, not incidental style in unfinished code.
- Use file-scoped namespaces, explicit types rather than `var`, and block-bodied
methods. Preserve the configured expression-bodied property/accessor preferences.
- Use `_camelCase` for non-public instance fields, including internal fields;
`s_camelCase` for non-public mutable static fields; PascalCase for constants
and static readonly fields. Do not rename internal fields to remove underscores.
- Preserve parentheses that make mathematical grouping readable. `IDE0047` is
intentionally disabled; do not re-enable it or remove grouping as style cleanup.
- Document public APIs and non-obvious numerical preconditions. Explain algorithms,
error behavior, and range constraints rather than narrating syntax.
- Tests and benchmarks already have internal access through `InternalsVisibleTo`;
do not widen the public API merely to make a helper testable.
## Numerical correctness
- Treat floating-point evaluation order as part of the algorithm. Do not reassociate
expressions, discard residuals, replace fused multiply-add with multiply-plus-add,
or simplify error-free transforms without justification and regression tests.
Mathematically equivalent formulas can round differently.
- State and verify algorithm preconditions, especially magnitude ordering for
quick-sum transforms, normalization assumptions, and overflow/underflow limits.
- The internal two-component `DoubleDouble` constructor does not normalize or
validate. Use `FromComponents` for arbitrary pairs and reserve raw construction
for proven normalized/canonical results. Preserve the documented normalization,
NaN, infinity, and signed-zero contracts across construction, equality, hashing,
ordering, and classification; do not change one in isolation.
- For affected operations, cover cancellation, widely separated magnitudes, zero
and signed zero, subnormals, extreme finite values, infinities, and NaNs. Check
intermediate overflow/underflow even when the final result is representable.
- Derive expected values from independent high-precision references or exact
binary/rational cases, never from the implementation under test. Record the
reference source or reproducible derivation and justify tolerances.
- Do not collapse both components to `double` or `decimal` to validate double-double
accuracy: that can discard precisely the bits being tested. Use component-aware
or higher-precision comparisons, and inspect sign bits when testing signed zero.
- Smoke tests, coverage percentages, and benchmark output are not proof of
numerical correctness.
## Build and verification
Run commands from the repository root. Read SDK and runner selection from
`global.json`; read framework, language, and dependency versions from project and
props files rather than duplicating version pins here.
For documentation-only changes, validate referenced paths and any new or changed
commands, then run `git diff --check`.
Report commands actually run, their outcomes, and anything not verified. Distinguish
pre-existing failures from failures introduced by the change.
### Code or build changes
Use targeted tests while iterating, then run the full sequence:
```sh
dotnet restore Just.PreciseMath.slnx --locked-mode
dotnet build Just.PreciseMath.slnx -c Release --no-restore
dotnet test --solution Just.PreciseMath.slnx -c Release --no-build --minimum-expected-tests 1
dotnet format Just.PreciseMath.slnx --verify-no-changes --no-restore
git diff --check
```
Use verify-only formatting first. Report unrelated existing violations separately
and validate the changed files; do not reformat the repository to hide failures.
### Test or coverage pipeline changes
After the code/build checks, also run:
```sh
dotnet test --solution Just.PreciseMath.slnx -c Release --no-build --minimum-expected-tests 1 --report-xunit-trx --coverlet --coverlet-output-format cobertura --coverlet-include "[Just.PreciseMath]*"
```
Keep MTP-native options and the empty-suite failure. Do not substitute VSTest
collector commands or remove compile assets from `coverlet.MTP`; generated MTP
registration requires them. Inspect actual TRX and Cobertura output, including
failed-test behavior when changing report collection.
### Packaging changes
After the code/build checks, run:
```sh
dotnet pack 0-source/Just.PreciseMath/Just.PreciseMath.csproj -c Release --no-build
```
Inspect package metadata and the included `README.md` and `LICENSE`. Do not publish.
### Dependency changes
For intentional dependency changes, run `dotnet restore --force-evaluate` and review
all affected `packages.lock.json` files before the locked restore above. Include
lock-file updates in the change; never regenerate them to bypass unexpected restore failures.
## CI and benchmarks
- `.gitea/workflows/test-dotnet.yaml` is the CI source of truth. Keep reports
artifact-only: no badges, publication branches, or repository-write publishing jobs.
- Preserve upload-on-failure and both report globs: `1-tests/**/TestResults/**/*.trx`
and `1-tests/**/TestResults/**/*cobertura*.xml`. Cobertura filenames can be timestamped;
`*.cobertura.xml` alone will miss them.
- Cache NuGet packages, not `bin/` or `obj/`; restore remains necessary on a cache hit.
A local restore does not prove CI cache reuse or remote artifact upload succeeded.
- Before upgrading actions, check each action's required Node runtime against both
the Gitea runner and job image. A recent runner can still launch an old Node image;
`ubuntu-latest` is a configured label, not a guarantee of GitHub's environment.
- Do not add an empty benchmark job. When benchmarks are introduced, add an executable
entry point and cases, then smoke-run them in Release with BenchmarkDotNet's Dry job.
Require discovered/executed cases and verify that benchmark failures fail CI.
- Keep smoke validation separate from performance measurement. Do not gate timing
regressions on a shared runner or compare coverage-instrumented measurements.
Use controlled, repeatable baseline/candidate runs before proposing performance gates.