HG907 quotation engine without LLM: deterministic-legal precision
Why our HG907 quotation engine uses no LLM at all — Decimal precision, ROUND_HALF_UP, and 14 validation rules to guarantee an audit-pass result.
Why our HG907 quotation engine uses no LLM at all (and that is a feature)
Three procurement consultants asked us the same question in the first week of the Bid365 demo: „what AI model runs in the back end for quotations?” The answer surprised them: none. The Bid365 quotation engine is fully algorithmic, with not a single token produced by a language model. In this article we explain why this decision is not a technical compromise but a legal requirement.
TL;DR
- Quotations built under the Romanian regulation HG 907/2016 are deterministic-legal objects: the same input must, by law, produce exactly the same result — to the cent.
- Language models produce probabilistic output. For exact arithmetic, they become a liability, not an asset.
- The Bid365 engine uses decimal arithmetic with ROUND_HALF_UP rounding, 14 ANAP validation rules, and a strict T1→T4 hierarchy with no variability.
- Across 1,000 quotations generated independently from the same input, output variance is zero — bit-for-bit identical.
- The resulting document passes ANAP audit without remarks on the calculation component; remaining remarks fall on technical descriptions, where human decision is required anyway.
What an HG907 quotation is and why precision matters
HG 907/2016 is the Romanian government decision that defines how a general quotation („deviz”) is calculated for public investment works. The document has dozens of articles prescribing exactly how expenses are grouped, how the indirect-cost rate is applied, how profit is calculated, how VAT is applied.
For a bidder responding to a public tender, the quotation is not an approximate calculation. It is a legal object: if the total value cannot be reconstructed from components according to HG907, the bid can be rejected for non-compliance. „Approximately” is a non-existent category. „Approximately correct” is, in law, „wrong”.
This requirement rules out from the start any approach based on a generative model. There is no prompt strict enough for an LLM to guarantee that 12,547.32 + 8,213.41 + 1,502.84 = 22,263.57 on every invocation, across billions of possible combinations. Language models perform arithmetic by statistical approximation; even models with chain-of-thought and an external calculator introduce variability at the routing decision level.
Anatomy of an HG907 quotation from the engine’s point of view
The Bid365 engine models the quotation as a four-level tabular hierarchy named T1, T2, T3, T4. Each level adds a specific component on top of the previous level’s sum.
T1 — Direct cost. The sum of the three base chapters: labour, materials, equipment. The input data is a list of items with quantity and unit price.
T1 = Σ(quantity_i × unit_price_i) for labour
+ Σ(quantity_j × unit_price_j) for materials
+ Σ(quantity_k × unit_price_k) for equipment
T2 — T1 plus indirect costs. Indirect costs are applied as a percentage on top of T1, according to the bidder’s policy stated in the form.
T2 = T1 × (1 + indirect_rate)
T3 — T2 plus profit. Profit is applied as a percentage on top of T2, not on top of T1, by ANAP rule.
T3 = T2 × (1 + profit_rate)
T4 — T3 plus mandatory insurance. For some categories of works, an execution-related insurance component is added.
T4 = T3 + mandatory_insurance
Total quotation with VAT = T4 × (1 + VAT_rate), where the VAT rate depends on the work category.
The hierarchy looks trivial in presentation. The complexity emerges when applied to a real quotation with 800 items, each with a fractional quantity, a unit price to four decimals, and intermediate roundings at each chapter subtotal.
Why ROUND_HALF_UP rounding matters
The default rounding standard in IEEE 754 floating point is „bankers’ rounding” (ROUND_HALF_EVEN): on an exact half, round to the nearest even number. This rule is statistically correct — it introduces no bias over large sets of calculations.
For an HG907 quotation, ROUND_HALF_EVEN is wrong. ANAP requires standard arithmetic rounding (ROUND_HALF_UP): 0.5 always rounds up. If the engine uses ROUND_HALF_EVEN, systematic differences of a few cents will appear at every subtotal compared with the commission’s reference calculation.
A one-cent difference at a subtotal does not look serious; on a quotation of 800 items, after chapter aggregation and percentage application, it becomes a difference of tens of lei at T4. That is enough for the commission’s auditor, who reconstructs the total with standard arithmetic, to report „mathematical non-compliance”.
The Bid365 engine uses pure decimal arithmetic (Decimal type with controlled precision), not floating point. All roundings are explicit, ROUND_HALF_UP, at the step prescribed by HG907 (typically 2 decimals for monetary values, 4 decimals for quantities). This decision was made in phase 1 of the project and has never been renegotiated.
The 14 validation rules
Correct calculation is a necessary condition, not sufficient. A quotation can be arithmetically perfect and entirely unacceptable to ANAP if it misses structural rules. The Bid365 engine applies 14 validation rules after calculation, extracted by working with three evaluation commissions from three different contracting authorities. We do not publish the full list (it is product IP), but a few categories illustrate it:
- Structural rules. Every item must be assigned to a valid chapter (labour, materials, equipment, transport, other expenses). Items with a null or invalid chapter are rejected.
- Coherence rules. The indirect-cost rate and the profit rate must fall within the ranges declared in the bid form. A discrepancy means rejection.
- Completeness rules. Some chapters are mandatory for certain types of works (for example, civil construction works must include a labour chapter).
- VAT coherence rules. The VAT rate applied must match the work category. An exempt work with VAT applied is an automatic rejection.
- Format rules. Item codes must comply with the national nomenclature; descriptions must meet a minimum length; quantities must be positive.
Each rule produces a textual error message with a reference to the relevant HG907 or ANAP article. The bidder sees exactly what to fix and why. This traceability matters: in a contestation, the bidder has proof that the engine applied rules with normative reference.
Why an LLM cannot do this
There is an obvious temptation for anyone building procurement software: „let us use an LLM to generate the quotation from the textual specification of the work.” It demos beautifully. In production it fails for three structural reasons.
Variability. The same prompt with the same data will, across a million invocations, produce a significant number of slightly different outputs. For a bidder submitting a single bid on date X, that is acceptable. For a system that must reproduce the same quotation when the commission recalculates at audit, it is catastrophic.
Arithmetic. Language models are not calculators. They can look like calculators on simple examples. On 800 items with chained roundings and compound percentage applications, they will make mistakes. Using an external calculation tool (function calling) reduces but does not eliminate the problem, because the model still decides when and how to call the tool.
Auditability. A quotation rejected by the commission must be reconstructed. The bidder must be able to show, step by step: these items multiplied by these quantities, summed, with this rate, give this T1; T1 multiplied by this rate gives T2 and so on. An LLM produces opaque output: there is no verifiable „calculation chain” beyond the generated text. The algorithmic engine produces an explicit audit trail.
Where we use LLMs in Bid365 (and where we do not)
The important distinction: we reject LLMs for calculation but use them deliberately for linguistic tasks.
The LLM runs for:
- generating technical descriptions of items in correct legal-economic language, starting from the standard nomenclature;
- drafting answers to clarification requests from the commission, starting from the bid documentation;
- translating tender documents from other EU languages.
The LLM never runs for:
- calculating any monetary value;
- applying any validation rule;
- deciding the chapter assignment of an item;
- choosing the VAT rate;
- generating quantities or unit prices.
The line is clear for us: language is the LLM’s responsibility, arithmetic and legality are the deterministic engine’s responsibility. The bidder reads the final output as a single document, but the underlying architecture keeps each component within its zone of competence.
What this means for a bidder evaluating quotation software
Three questions we recommend before any quotation-software purchase:
-
„Does it reproduce exactly the same result on every invocation?” Ask to run the same input twice and compare outputs at binary level, not just visually. Any difference is a red flag.
-
„Do you use Decimal or floating point?” Floating point for monetary values in a quotation is a latent problem that surfaces at audit. Decimal with explicit rounding is the standard.
-
„Do you have a per-rule audit trail?” On a commission rejection, the bidder needs to see exactly which rule was applied and which norm was used. A generic error message („invalid quotation”) is not enough for a challenge.
Operational conclusion
For deterministic-legal calculations, the deterministic engine is not a conservative fallback for clients who do not „understand AI”. It is the correct choice, supported by the very nature of the task. AI has its place in Bid365 — in linguistic generation, translation, drafting assistance. It has no place in mathematical calculation that must be reconstructed identically at audit.
This architectural discipline is hard to defend in public against a competitor promising „AI everywhere”. In production, however, bidders who lost a tender because of a one-cent error at T4 understand it instantly.
Related articles
- Anti-hallucination for legal chatbots
- Pillar Bid365 — the CAI Technology public procurement platform
- Propose-then-act architecture for production AI agents
External sources
- Romanian Government Decision 907/2016 — consolidated version (legislatie.just.ro)
- IEEE Standard 754 for floating-point arithmetic — for technical context
- Python
decimaldocumentation — ROUND_HALF_UP - Romanian National Public Procurement Agency (ANAP) — the regulator
- Procurement Practitioner Manual — World Bank Group (international public procurement reference)
Next step
If your team works on public procurement bids and you want a technical evaluation of the Bid365 engine on a real quotation, we offer a 30-minute technical consultation at no cost.