Files
Just.PreciseMath/AGENTS.md
T
just 082fd84c87
.NET Test / .NET tests (push) Successful in 1m14s
ported legacy DoubleDouble with tests
2026-09-13 22:19:23 +04:00

8.7 KiB

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/: source-free BenchmarkDotNet library scaffold, not yet a runnable benchmark suite.
  • 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:

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:

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:

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.