Severity: medium
Domain: docs / policy
Status: VERIFIED — read + measured against a210d34 on 2026-08-10
Suggested labels: documentation, policy
Summary
AGENTS.md states a flat rule — "New algorithms are float-only … Do NOT
implement Q15/Q31 now" — but that is not the policy actually in force. Fixed-point is
accepted for simple algorithms; it is only disallowed for large/complex operations, where it
inflates implementation complexity for little gain.
Because the canonical file states the strict version, and ~18 downstream files (agent definitions,
Copilot/Claude instructions, review checklists) copy it verbatim, review tooling actively flags
correct code as a violation — and the real boundary between "simple enough for Q" and "too large
for Q" is written down nowhere.
Evidence
The canonical rule is unconditional
AGENTS.md:
## Numeric policy — FLOAT-ONLY (current)
- New algorithms are **float-only**. Write generic `template<typename T>`, add
`static_assert(std::is_floating_point_v<T>, "...")`, and **instantiate/test `float` only**.
- Do **NOT** implement `Q15`/`Q31` now.
But the ROADMAP already encodes the tiered rule correctly
ROADMAP.md:
Numeric-type note. DSP filters and fixed-gain trackers should template all three
types (float, Q15, Q31). Items marked (float-first) involve dynamic range or
iterative conditioning that make fixed-point impractical initially — implement and
validate in float.
This is much closer to the real policy than AGENTS.md is.
And an agent definition already carves out a second exception
.claude/agents/algo-modernizer.md:
Preserve fixed-point. Rows tagged Q/Q* support Q15/Q31. NEVER recommend stripping
is_qnumber, renaming QNumberType→T where it drops fixed-point, or forcing float-only — that
policy is for NEW algorithms only. QNumberType is not, by itself, a defect.
So there are already two unstated dimensions: new vs legacy, and simple vs complex.
The code follows the tiered rule, not the flat one
$ grep -rl 'Q15\|Q31' numerical --include=*.cpp --include=*.hpp | wc -l
41
numerical/math/Statistics.hpp gates on a Q-aware trait:
static_assert(detail::is_supported_type_v<T>,
"Statistical functions only support float or QNumber types");
The actual gap
Not "the ROADMAP is wrong" — the ROADMAP is closer to right. The gap is that AGENTS.md
overstates the rule, and no file defines the simple/complex boundary in reviewable terms.
"Too large" is currently a judgement call that two reviewers will apply differently.
Suggested fix
1. Replace the AGENTS.md numeric policy section with a tiered rule
Draft for editing:
Numeric policy — tiered
Write generic template<typename T>. Which types you instantiate depends on the algorithm:
Tier A — float, Q15, Q31. Bounded dynamic range, no iteration to a tolerance, no
matrix factorisation. Examples: FIR/IIR/biquad/comb/moving-average, fixed-gain trackers
(alpha-beta, complementary), windowing, unit conversions.
Tier B — float only. Add static_assert(std::is_floating_point_v<T>). Any algorithm that
divides by a data-dependent quantity, accumulates products of unbounded magnitude, iterates to a
tolerance, or factorises/inverts a matrix. Examples: Kalman family, DARE/Riccati,
SVD/QR/Cholesky/eigen, optimisation, adaptive filters, ODE solvers.
Legacy algorithms keep the types they already support. Removing Q15/Q31 from an existing
algorithm is a breaking change, not a cleanup.
Adjust the tier boundary to taste — the important part is that it is written down and testable.
2. Propagate to the derived files
The flat rule is replicated in roughly 18 places; all must move together or the contradiction
persists:
Review checklists should ask "is the tier correct for this algorithm?" rather than
"is it float-only?".
3. Tag each algorithm with its tier
Add the tier to each doc/<domain>/<Name>.md so the expected instantiation set is reviewable, and
so the TYPED_TEST question (issue 019) has a definitive answer per algorithm.
Related
- Issue 019 —
TYPED_TEST/Q-number test drift; its resolution depends on this decision.
- Issue 024 — ROADMAP master list is empty (split out of this issue).
Incidental finding
.claude/agents/algo-modernizer.md references
REVIEW_BACKLOG.md, which does not exist in the repository. The agent cannot run as written.
Severity: medium
Domain: docs / policy
Status: VERIFIED — read + measured against
a210d34on 2026-08-10Suggested labels:
documentation,policySummary
AGENTS.md states a flat rule — "New algorithms are float-only … Do NOT
implement
Q15/Q31now" — but that is not the policy actually in force. Fixed-point isaccepted for simple algorithms; it is only disallowed for large/complex operations, where it
inflates implementation complexity for little gain.
Because the canonical file states the strict version, and ~18 downstream files (agent definitions,
Copilot/Claude instructions, review checklists) copy it verbatim, review tooling actively flags
correct code as a violation — and the real boundary between "simple enough for Q" and "too large
for Q" is written down nowhere.
Evidence
The canonical rule is unconditional
AGENTS.md:
But the ROADMAP already encodes the tiered rule correctly
ROADMAP.md:
This is much closer to the real policy than
AGENTS.mdis.And an agent definition already carves out a second exception
.claude/agents/algo-modernizer.md:
So there are already two unstated dimensions: new vs legacy, and simple vs complex.
The code follows the tiered rule, not the flat one
numerical/math/Statistics.hpp gates on a Q-aware trait:
The actual gap
Not "the ROADMAP is wrong" — the ROADMAP is closer to right. The gap is that
AGENTS.mdoverstates the rule, and no file defines the simple/complex boundary in reviewable terms.
"Too large" is currently a judgement call that two reviewers will apply differently.
Suggested fix
1. Replace the
AGENTS.mdnumeric policy section with a tiered ruleDraft for editing:
Adjust the tier boundary to taste — the important part is that it is written down and testable.
2. Propagate to the derived files
The flat rule is replicated in roughly 18 places; all must move together or the contradiction
persists:
.github/instructions/testing.instructions.md
.github/agents/{reviewer,executor,planner,algo-implementer}.agent.mdand the matching.claude/agents/*.mdReview checklists should ask "is the tier correct for this algorithm?" rather than
"is it float-only?".
3. Tag each algorithm with its tier
Add the tier to each
doc/<domain>/<Name>.mdso the expected instantiation set is reviewable, andso the
TYPED_TESTquestion (issue 019) has a definitive answer per algorithm.Related
TYPED_TEST/Q-number test drift; its resolution depends on this decision.Incidental finding
.claude/agents/algo-modernizer.md references
REVIEW_BACKLOG.md, which does not exist in the repository. The agent cannot run as written.