Surfaced by the common schema resolution, which established that price is a typed rate function
evaluated against an RFP-declared scenario, and flagged the rate structure as the most intricate
object in the schema and the one most likely to need extending.
Resolve: which rate shapes v1 supports (flat unit rate, volume bands, tiered breaks with marginal
vs. whole-basket application, minimums, surcharges, fixed fees); how each is represented; the
evaluation function that turns a rate structure plus a scenario quantity into a comparable cost;
what happens when a vendor's pricing does not fit any supported shape; and whether unsupported
shapes degrade to an attachment with the ranking engine abstaining on price for that bid.
Note the fairness constraint from the parent decision: the scenario is published with the RFP, so
the evaluation function must be deterministic and reproducible — a recomputation months later
during a protest has to produce the same number.
## Question
Surfaced by the common schema resolution, which established that price is a typed rate function
evaluated against an RFP-declared scenario, and flagged the rate structure as the most intricate
object in the schema and the one most likely to need extending.
Resolve: which rate shapes v1 supports (flat unit rate, volume bands, tiered breaks with marginal
vs. whole-basket application, minimums, surcharges, fixed fees); how each is represented; the
evaluation function that turns a rate structure plus a scenario quantity into a comparable cost;
what happens when a vendor's pricing does not fit any supported shape; and whether unsupported
shapes degrade to an attachment with the ranking engine abstaining on price for that bid.
Note the fairness constraint from the parent decision: the scenario is published with the RFP, so
the evaluation function must be deterministic and reproducible — a recomputation months later
during a protest has to produce the same number.
---
Parent: #1
Built, not just decided. src/pricing/ is real code — rate.ts, scenario.ts, evaluate.ts, exception.ts — and npm run check:pricing asserts it against the Friendship PCS
response set. This ticket was takeable ahead of the other seven precisely because the corpus can falsify it: the other frontier tickets resolve by argument, this one resolves by arithmetic.
Decision 1 — a scenario is a closed vocabulary, not a quantity map
The seam here was evaluate(rate, {[priceLineId]: number}): number. Both halves were wrong. Potomac
needs one number. Chesapeake needs deliveries-per-week, site count and weeks. Anacostia needs volume distributed across months. So a rate structure consumes a typed set of variables, and v1 names
them centrally: siteCount, deliveriesPerWeek, instructionalWeeks, plus the one vector, monthlyWeights.
Free-form retailer-authored keys were rejected. The scenario is published with the RFP so every
bid in a field is priced against identical assumptions; let vendors reference arbitrary keys and two
bids in one field read different variables, which is the single thing derived cost exists to
prevent. A closed set also turns "your structure needs a variable this RFP does not publish" into a validation error at bid time, while the vendor can still fix it — not a null in the evaluator
months later when nobody can act on it.
Extending the vocabulary is a schema change on purpose, the same posture #26 took on the category
spine.
One thing named explicitly in the code, because it will otherwise be asked during a protest: a
scenario variable is an assumption for comparison, not a contract term. Chesapeake's delivery
frequency is changeable mid-term on two weeks' notice, so the awarded price will not match the
derived cost.
Decision 2 — composition, not an enumeration of shapes
Three vendors on one small RFP produced three structures, and two of them are the same object
wearing different decoration. Enumerating whole shapes costs a cross-product — flat, flat+surcharge, banded, banded+seasonal, seasonal+surcharge — before anyone has met a fourth
vendor.
So a structure is one base schedule deciding unit price, plus closed modifiers, plus an
optional floor:
Banded-and-seasonal composes for free without anyone designing it, which matters because it is
obviously real and no corpus vendor happens to bid it. Extending v1 adds one union member rather
than a row and a column.
whole_basket vs marginal is explicit and never inferred. Potomac's bands are a retroactive
year-end rebate repricing every case; marginal ladders are equally common elsewhere. One word of
data, and on this bid a $10,200 difference. No default is right more than about half the time,
so the extractor must state what it saw.
Structures attach to price lines, not to bids. Anacostia's seasonal multiplier applies to produce
only; grocery, dairy and protein are flat. The seam's per-line keying was already right about this.
Deferred: greater_of — SLC's MAX(1/12 x MAG, % of gross receipts). Genuinely recursive, it
belongs to concessions rather than supply, and SLC extraction is still fog. It falls to shape_unsupported and abstains, which is the right outcome for a shape we cannot evaluate — better
than a half-built one we can evaluate wrong.
Decision 3 — three outcomes, because the corpus has three
The ticket offered two: it fits, or it degrades to an attachment. Chesapeake is the third and the
one that matters.
Outcome
Cause
Recoverable
priced
shape_unsupported
no supported shape represents it
no — attachment, permanently
input_missing
shape supported, a field is absent
yes — ask the vendor
Chesapeake's flat_unit + per_event_charge is fully supported. Its unit case price is simply absent,
living in an Excel sheet the extractor never received (KM-1). Collapsing that into "doesn't fit"
throws away the only actionable fact. So money leaves in the type are nullable on purpose,
extraction produces a structure with holes, and the evaluator's missing[] names them — that array is the clarification request. A parse that rejected the whole structure would lose which field to
ask about.
Three rules on top:
Abstain is not zero and not exclusion. Price is 40 points at Friendship. A null scored as zero
disqualifies on arithmetic; a null dropped from the field does it more quietly. "This bid has no
price" is a decision, and #15 says the system does not make those. It routes to a human, achromatic
and dashed, the same encoding #36 gave indeterminate — because it is the same statement.
A partial sum is never shown as a total. If any required line abstains the bid total is null and
the surface shows 3/4 lines priced. The check asserts the withheld partial is $736,792.00 —
arithmetically correct, and not this bid's price. Exactly #37's roll-up bug, in money.
Stated never substitutes for computed. Chesapeake's stated total is $541,280 — the lowest number
in the field, unverifiable, on the bid that fails two gates. Separate columns; only computed ranks.
Where both exist and disagree — Potomac's planted $400 — that is a finding on the bid, not a
tiebreak.
Decision 4 — the derivation is the record, not the number
Data persists; the evaluator is code, and code moves. Recomputing during a challenge and getting a
different answer than the award is this ticket's worst failure.
Stored per computation: { amount, reason, breakdown, evaluatorVersion, inputsHash }. The breakdown does the real work — band chosen, seasonal factor, each modifier's contribution, floor
if it bound. A protest asks why did this bid rank here, and a bare scalar can only assert.
Recompute on read is a check: matching is silent, divergence is a flagged finding, the stored
number stays authoritative. evaluatorVersion exists to explain divergence, not to promise old
versions stay runnable forever.
Rounding is pinned, not discovered. A line accumulates as an exact rational in bigint —
numerator and denominator, never divided — and rounds once at the end, half-up. Nothing quantizes on
the way through.
A scenario amendment voids derived costs rather than recomputing them, consistent with #16 and #37. Every figure was computed against assumptions that no longer hold, and a silently recomputed
price is more dangerous than a silently recomputed score, because nobody watches arithmetic the way
they watch a rubric.
Decision 5 — the exception that has no price
An exception modifies the terms and sometimes carries a price consequence. It is not a price
field. Anacostia labels three: two carry deltas, and EX-3 says that if declined the vendor cannot bid
produce at all. A nullable priceDeltaIfDeclined reads that as "no cost impact" — the inverse of the
truth, on the most consequential of the three.
So the consequence is a closed union: price_delta / withdrawal / unquantified.
Two figures, one ranks.asBid is what the vendor is offering and the only comparable number.
As-if-declined is computed and shown beside it and never ranks — accepting an exception is the
retailer's call, and folding it into the ordering is the system pre-deciding it.
A withdrawal exception makes as-if-declined null, reason withdrawal_conditioned, reusing
the Decision 3 machinery. Anacostia's own arithmetic (624,315 + 18,400 + 9,750 = 652,465) is
internally consistent and still incomplete, because it silently omits the exception that cannot be
added.
Unlabelled exceptions never move arithmetic. Chesapeake's is a polite sentence in the Pricing
section. Detecting it is valuable; pricing it is a model deciding. It surfaces as a finding and
renders indeterminate.
Absence is recorded affirmatively. Potomac has none. "Read the pricing section, found none" and
"never checked" must not look alike — the answered / not_answered distinction from #36.
Two defects the corpus check caught that review would not have
Both were found by assertions failing, not by reading the code.
The band ladder priced two different ways depending on a flag. Bands read naturally as [0, 11999] then [12000, 23999], and subtracting those bounds in the marginal path loses the unit
between them — one unit in 21,400, invisible in the total and wrong in the record. to is inclusive
for whole-basket selection; marginal reads the next band's from and treats the ladder as
half-open. bandsContiguous now rejects any ladder where the two readings disagree, because a
structure that prices differently depending on a flag is not something to discover during a protest.
The published scenario was quantizing the seasonal factor.monthlyDistribution started as
twelve basis-point shares. Rounding twelve shares moved the weighted factor by 3e-5 — about $19
on a $624,000 line — and #22 is emphatic that rounding erases results. The fix was to stop
normalising: the field is now monthlyWeights, raw non-negative integers, and a school calendar
publishes instructional days per month as an exact integer nobody has to round. The evaluator takes
the ratio last. The independent float check now agrees to nine decimal places instead of five.
The second one is the more interesting finding. The evaluator was exact the whole time; the input
format was throwing away precision before the evaluator ever saw it, which no amount of careful
arithmetic downstream could recover.
Verified
Potomac computes $589,570.00 at 21,400 cases — and does NOT reproduce the
stated $589,970.00 (divergence $400.00)
marginal application yields $599,770.00, pricing every unit exactly once
Chesapeake abstains; reason input_missing (not shape_unsupported);
names base.unitPrice as the field to ask for;
never substitutes the stated $541,280.00
Anacostia abstains with no calendar, naming scenario.monthlyWeights;
$649,792.00 with it — MORE than the $624,000.00 a flat assumption gives;
weighted factor 1.041333333 vs independent 1.041333333
exceptions as-bid ranks; the withdrawal exception makes as-if-declined undefined,
not $652,465.00; EX-3's C.3 target surfaces as a completeness finding;
Chesapeake's unlabelled exception moves nothing
roll-up 3/4 lines price, total withheld, and the $736,792.00 partial is
asserted to be a number that must never be shown as a total
PRICING OK tsc --noEmit clean
Schema updated alongside: price_line.required, evaluation_scenario.monthly_weights, a new scenario_variable table under the basket's disclosure class, exception rebuilt around the
consequence union, and derived_cost carrying nullable amount + reason + breakdown +
evaluator_version + inputs_hash + voided_by_amendment_id.
Handoffs
#21 — derived_cost is now an evidentiary row, not a cached number. The recompute-as-check
rule and the void-on-amendment rule both belong to the audit design, and the "database-level tests
are not optional" note already sitting on that ticket now has a concrete first subject.
#16 — an exception can target a section the extractor never enumerated (EX-3 points at C.3,
absent from the truth file). That makes exceptions a completeness signal feeding the sweep, not
merely a response field.
#28 — the scenario vocabulary is category-shaped. instructionalWeeks is a school food
contract's variable; logistics and facilities will want their own. Worth checking the spine's
groups against it rather than discovering the gap per-RFP.
What this does not settle
Translating a PDF into these structures is extraction (#16) and is unbuilt — the corpus check
transcribes structures by hand from the truth files, so it verifies the evaluator, not the
extractor. The greater-of shape stays deferred behind shape_unsupported. And every number here
comes from one solicitation in one category: the vocabulary has met food service and nothing else.
## Resolution
Built, not just decided. `src/pricing/` is real code — `rate.ts`, `scenario.ts`,
`evaluate.ts`, `exception.ts` — and `npm run check:pricing` asserts it against the Friendship PCS
response set. This ticket was takeable ahead of the other seven precisely because the corpus can
**falsify** it: the other frontier tickets resolve by argument, this one resolves by arithmetic.
---
### Decision 1 — a scenario is a closed vocabulary, not a quantity map
The seam here was `evaluate(rate, {[priceLineId]: number}): number`. Both halves were wrong. Potomac
needs one number. Chesapeake needs deliveries-per-week, site count and weeks. Anacostia needs volume
*distributed across months*. So a rate structure consumes a **typed set of variables**, and v1 names
them centrally: `siteCount`, `deliveriesPerWeek`, `instructionalWeeks`, plus the one vector,
`monthlyWeights`.
Free-form retailer-authored keys were rejected. The scenario is published **with** the RFP so every
bid in a field is priced against identical assumptions; let vendors reference arbitrary keys and two
bids in one field read different variables, which is the single thing derived cost exists to
prevent. A closed set also turns "your structure needs a variable this RFP does not publish" into a
**validation error at bid time**, while the vendor can still fix it — not a null in the evaluator
months later when nobody can act on it.
Extending the vocabulary is a schema change on purpose, the same posture #26 took on the category
spine.
One thing named explicitly in the code, because it will otherwise be asked during a protest: a
scenario variable is an **assumption for comparison, not a contract term**. Chesapeake's delivery
frequency is changeable mid-term on two weeks' notice, so the awarded price will not match the
derived cost.
### Decision 2 — composition, not an enumeration of shapes
Three vendors on one small RFP produced three structures, and two of them are the same object
wearing different decoration. Enumerating whole shapes costs a cross-product — `flat`,
`flat+surcharge`, `banded`, `banded+seasonal`, `seasonal+surcharge` — before anyone has met a fourth
vendor.
So a structure is **one base schedule** deciding unit price, plus **closed modifiers**, plus an
optional floor:
| | Members |
|---|---|
| Base | `flat_unit`, `volume_banded` (with explicit `application`) |
| Modifiers | `seasonal_multiplier`, `per_event_charge`, `fixed_fee` |
| Floor | `minimumCharge` |
Banded-and-seasonal composes for free without anyone designing it, which matters because it is
obviously real and no corpus vendor happens to bid it. Extending v1 adds one union member rather
than a row and a column.
**`whole_basket` vs `marginal` is explicit and never inferred.** Potomac's bands are a retroactive
year-end rebate repricing every case; marginal ladders are equally common elsewhere. One word of
data, and on this bid a **$10,200** difference. No default is right more than about half the time,
so the extractor must state what it saw.
**Structures attach to price lines, not to bids.** Anacostia's seasonal multiplier applies to produce
only; grocery, dairy and protein are flat. The seam's per-line keying was already right about this.
**Deferred: `greater_of`** — SLC's `MAX(1/12 x MAG, % of gross receipts)`. Genuinely recursive, it
belongs to concessions rather than supply, and SLC extraction is still fog. It falls to
`shape_unsupported` and abstains, which is the right outcome for a shape we cannot evaluate — better
than a half-built one we can evaluate wrong.
### Decision 3 — three outcomes, because the corpus has three
The ticket offered two: it fits, or it degrades to an attachment. Chesapeake is the third and the
one that matters.
| Outcome | Cause | Recoverable |
|---|---|---|
| priced | | |
| `shape_unsupported` | no supported shape represents it | no — attachment, permanently |
| `input_missing` | shape supported, **a field is absent** | **yes — ask the vendor** |
Chesapeake's `flat_unit + per_event_charge` is fully supported. Its unit case price is simply absent,
living in an Excel sheet the extractor never received (KM-1). Collapsing that into "doesn't fit"
throws away the only actionable fact. So money leaves in the type are **nullable on purpose**,
extraction produces a structure with holes, and the evaluator's `missing[]` names them — that array
*is* the clarification request. A parse that rejected the whole structure would lose which field to
ask about.
Three rules on top:
**Abstain is not zero and not exclusion.** Price is 40 points at Friendship. A null scored as zero
disqualifies on arithmetic; a null dropped from the field does it more quietly. "This bid has no
price" is a decision, and #15 says the system does not make those. It routes to a human, achromatic
and dashed, the same encoding #36 gave `indeterminate` — because it is the same statement.
**A partial sum is never shown as a total.** If any required line abstains the bid total is null and
the surface shows `3/4 lines priced`. The check asserts the withheld partial is **$736,792.00** —
arithmetically correct, and not this bid's price. Exactly #37's roll-up bug, in money.
**Stated never substitutes for computed.** Chesapeake's stated total is $541,280 — the lowest number
in the field, unverifiable, on the bid that fails two gates. Separate columns; only computed ranks.
Where both exist and disagree — Potomac's planted $400 — that is a finding on the bid, not a
tiebreak.
### Decision 4 — the derivation is the record, not the number
Data persists; the evaluator is code, and code moves. Recomputing during a challenge and getting a
different answer than the award is this ticket's worst failure.
Stored per computation: `{ amount, reason, breakdown, evaluatorVersion, inputsHash }`. The
**breakdown** does the real work — band chosen, seasonal factor, each modifier's contribution, floor
if it bound. A protest asks *why did this bid rank here*, and a bare scalar can only assert.
Recompute on read is a **check**: matching is silent, divergence is a flagged finding, the stored
number stays authoritative. `evaluatorVersion` exists to explain divergence, not to promise old
versions stay runnable forever.
**Rounding is pinned, not discovered.** A line accumulates as an exact rational in bigint —
numerator and denominator, never divided — and rounds once at the end, half-up. Nothing quantizes on
the way through.
**A scenario amendment voids derived costs rather than recomputing them**, consistent with #16 and
#37. Every figure was computed against assumptions that no longer hold, and a silently recomputed
price is more dangerous than a silently recomputed score, because nobody watches arithmetic the way
they watch a rubric.
### Decision 5 — the exception that has no price
An exception modifies the **terms** and sometimes carries a price consequence. It is not a price
field. Anacostia labels three: two carry deltas, and EX-3 says that if declined the vendor cannot bid
produce at all. A nullable `priceDeltaIfDeclined` reads that as "no cost impact" — the inverse of the
truth, on the most consequential of the three.
So the consequence is a closed union: `price_delta` / `withdrawal` / `unquantified`.
- **Two figures, one ranks.** `asBid` is what the vendor is offering and the only comparable number.
As-if-declined is computed and shown beside it and never ranks — accepting an exception is the
retailer's call, and folding it into the ordering is the system pre-deciding it.
- **A `withdrawal` exception makes as-if-declined null**, reason `withdrawal_conditioned`, reusing
the Decision 3 machinery. Anacostia's own arithmetic (624,315 + 18,400 + 9,750 = 652,465) is
internally consistent and still incomplete, because it silently omits the exception that cannot be
added.
- **Unlabelled exceptions never move arithmetic.** Chesapeake's is a polite sentence in the Pricing
section. Detecting it is valuable; pricing it is a model deciding. It surfaces as a finding and
renders indeterminate.
- **Absence is recorded affirmatively.** Potomac has none. "Read the pricing section, found none" and
"never checked" must not look alike — the `answered` / `not_answered` distinction from #36.
---
### Two defects the corpus check caught that review would not have
Both were found by assertions failing, not by reading the code.
**The band ladder priced two different ways depending on a flag.** Bands read naturally as
`[0, 11999]` then `[12000, 23999]`, and subtracting those bounds in the marginal path loses the unit
between them — one unit in 21,400, invisible in the total and wrong in the record. `to` is inclusive
for whole-basket *selection*; marginal reads the next band's `from` and treats the ladder as
half-open. `bandsContiguous` now rejects any ladder where the two readings disagree, because a
structure that prices differently depending on a flag is not something to discover during a protest.
**The published scenario was quantizing the seasonal factor.** `monthlyDistribution` started as
twelve basis-point shares. Rounding twelve shares moved the weighted factor by 3e-5 — about **$19**
on a $624,000 line — and #22 is emphatic that rounding erases results. The fix was to stop
normalising: the field is now `monthlyWeights`, raw non-negative integers, and a school calendar
publishes instructional days per month as an exact integer nobody has to round. The evaluator takes
the ratio last. The independent float check now agrees to nine decimal places instead of five.
The second one is the more interesting finding. The evaluator was exact the whole time; the *input
format* was throwing away precision before the evaluator ever saw it, which no amount of careful
arithmetic downstream could recover.
### Verified
```
Potomac computes $589,570.00 at 21,400 cases — and does NOT reproduce the
stated $589,970.00 (divergence $400.00)
marginal application yields $599,770.00, pricing every unit exactly once
Chesapeake abstains; reason input_missing (not shape_unsupported);
names base.unitPrice as the field to ask for;
never substitutes the stated $541,280.00
Anacostia abstains with no calendar, naming scenario.monthlyWeights;
$649,792.00 with it — MORE than the $624,000.00 a flat assumption gives;
weighted factor 1.041333333 vs independent 1.041333333
exceptions as-bid ranks; the withdrawal exception makes as-if-declined undefined,
not $652,465.00; EX-3's C.3 target surfaces as a completeness finding;
Chesapeake's unlabelled exception moves nothing
roll-up 3/4 lines price, total withheld, and the $736,792.00 partial is
asserted to be a number that must never be shown as a total
PRICING OK tsc --noEmit clean
```
Schema updated alongside: `price_line.required`, `evaluation_scenario.monthly_weights`, a new
`scenario_variable` table under the basket's disclosure class, `exception` rebuilt around the
consequence union, and `derived_cost` carrying nullable amount + reason + breakdown +
evaluator_version + inputs_hash + voided_by_amendment_id.
### Handoffs
- **#21** — `derived_cost` is now an evidentiary row, not a cached number. The recompute-as-check
rule and the void-on-amendment rule both belong to the audit design, and the "database-level tests
are not optional" note already sitting on that ticket now has a concrete first subject.
- **#16** — an exception can target a section the extractor never enumerated (EX-3 points at C.3,
absent from the truth file). That makes exceptions a **completeness signal** feeding the sweep, not
merely a response field.
- **#28** — the scenario vocabulary is category-shaped. `instructionalWeeks` is a school food
contract's variable; logistics and facilities will want their own. Worth checking the spine's
groups against it rather than discovering the gap per-RFP.
### What this does not settle
Translating a PDF into these structures is extraction (#16) and is unbuilt — the corpus check
transcribes structures by hand from the truth files, so it verifies the **evaluator**, not the
extractor. The greater-of shape stays deferred behind `shape_unsupported`. And every number here
comes from one solicitation in one category: the vocabulary has met food service and nothing else.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Question
Surfaced by the common schema resolution, which established that price is a typed rate function
evaluated against an RFP-declared scenario, and flagged the rate structure as the most intricate
object in the schema and the one most likely to need extending.
Resolve: which rate shapes v1 supports (flat unit rate, volume bands, tiered breaks with marginal
vs. whole-basket application, minimums, surcharges, fixed fees); how each is represented; the
evaluation function that turns a rate structure plus a scenario quantity into a comparable cost;
what happens when a vendor's pricing does not fit any supported shape; and whether unsupported
shapes degrade to an attachment with the ranking engine abstaining on price for that bid.
Note the fairness constraint from the parent decision: the scenario is published with the RFP, so
the evaluation function must be deterministic and reproducible — a recomputation months later
during a protest has to produce the same number.
Parent: #1
Resolution
Built, not just decided.
src/pricing/is real code —rate.ts,scenario.ts,evaluate.ts,exception.ts— andnpm run check:pricingasserts it against the Friendship PCSresponse set. This ticket was takeable ahead of the other seven precisely because the corpus can
falsify it: the other frontier tickets resolve by argument, this one resolves by arithmetic.
Decision 1 — a scenario is a closed vocabulary, not a quantity map
The seam here was
evaluate(rate, {[priceLineId]: number}): number. Both halves were wrong. Potomacneeds one number. Chesapeake needs deliveries-per-week, site count and weeks. Anacostia needs volume
distributed across months. So a rate structure consumes a typed set of variables, and v1 names
them centrally:
siteCount,deliveriesPerWeek,instructionalWeeks, plus the one vector,monthlyWeights.Free-form retailer-authored keys were rejected. The scenario is published with the RFP so every
bid in a field is priced against identical assumptions; let vendors reference arbitrary keys and two
bids in one field read different variables, which is the single thing derived cost exists to
prevent. A closed set also turns "your structure needs a variable this RFP does not publish" into a
validation error at bid time, while the vendor can still fix it — not a null in the evaluator
months later when nobody can act on it.
Extending the vocabulary is a schema change on purpose, the same posture #26 took on the category
spine.
One thing named explicitly in the code, because it will otherwise be asked during a protest: a
scenario variable is an assumption for comparison, not a contract term. Chesapeake's delivery
frequency is changeable mid-term on two weeks' notice, so the awarded price will not match the
derived cost.
Decision 2 — composition, not an enumeration of shapes
Three vendors on one small RFP produced three structures, and two of them are the same object
wearing different decoration. Enumerating whole shapes costs a cross-product —
flat,flat+surcharge,banded,banded+seasonal,seasonal+surcharge— before anyone has met a fourthvendor.
So a structure is one base schedule deciding unit price, plus closed modifiers, plus an
optional floor:
flat_unit,volume_banded(with explicitapplication)seasonal_multiplier,per_event_charge,fixed_feeminimumChargeBanded-and-seasonal composes for free without anyone designing it, which matters because it is
obviously real and no corpus vendor happens to bid it. Extending v1 adds one union member rather
than a row and a column.
whole_basketvsmarginalis explicit and never inferred. Potomac's bands are a retroactiveyear-end rebate repricing every case; marginal ladders are equally common elsewhere. One word of
data, and on this bid a $10,200 difference. No default is right more than about half the time,
so the extractor must state what it saw.
Structures attach to price lines, not to bids. Anacostia's seasonal multiplier applies to produce
only; grocery, dairy and protein are flat. The seam's per-line keying was already right about this.
Deferred:
greater_of— SLC'sMAX(1/12 x MAG, % of gross receipts). Genuinely recursive, itbelongs to concessions rather than supply, and SLC extraction is still fog. It falls to
shape_unsupportedand abstains, which is the right outcome for a shape we cannot evaluate — betterthan a half-built one we can evaluate wrong.
Decision 3 — three outcomes, because the corpus has three
The ticket offered two: it fits, or it degrades to an attachment. Chesapeake is the third and the
one that matters.
shape_unsupportedinput_missingChesapeake's
flat_unit + per_event_chargeis fully supported. Its unit case price is simply absent,living in an Excel sheet the extractor never received (KM-1). Collapsing that into "doesn't fit"
throws away the only actionable fact. So money leaves in the type are nullable on purpose,
extraction produces a structure with holes, and the evaluator's
missing[]names them — that arrayis the clarification request. A parse that rejected the whole structure would lose which field to
ask about.
Three rules on top:
Abstain is not zero and not exclusion. Price is 40 points at Friendship. A null scored as zero
disqualifies on arithmetic; a null dropped from the field does it more quietly. "This bid has no
price" is a decision, and #15 says the system does not make those. It routes to a human, achromatic
and dashed, the same encoding #36 gave
indeterminate— because it is the same statement.A partial sum is never shown as a total. If any required line abstains the bid total is null and
the surface shows
3/4 lines priced. The check asserts the withheld partial is $736,792.00 —arithmetically correct, and not this bid's price. Exactly #37's roll-up bug, in money.
Stated never substitutes for computed. Chesapeake's stated total is $541,280 — the lowest number
in the field, unverifiable, on the bid that fails two gates. Separate columns; only computed ranks.
Where both exist and disagree — Potomac's planted $400 — that is a finding on the bid, not a
tiebreak.
Decision 4 — the derivation is the record, not the number
Data persists; the evaluator is code, and code moves. Recomputing during a challenge and getting a
different answer than the award is this ticket's worst failure.
Stored per computation:
{ amount, reason, breakdown, evaluatorVersion, inputsHash }. Thebreakdown does the real work — band chosen, seasonal factor, each modifier's contribution, floor
if it bound. A protest asks why did this bid rank here, and a bare scalar can only assert.
Recompute on read is a check: matching is silent, divergence is a flagged finding, the stored
number stays authoritative.
evaluatorVersionexists to explain divergence, not to promise oldversions stay runnable forever.
Rounding is pinned, not discovered. A line accumulates as an exact rational in bigint —
numerator and denominator, never divided — and rounds once at the end, half-up. Nothing quantizes on
the way through.
A scenario amendment voids derived costs rather than recomputing them, consistent with #16 and
#37. Every figure was computed against assumptions that no longer hold, and a silently recomputed
price is more dangerous than a silently recomputed score, because nobody watches arithmetic the way
they watch a rubric.
Decision 5 — the exception that has no price
An exception modifies the terms and sometimes carries a price consequence. It is not a price
field. Anacostia labels three: two carry deltas, and EX-3 says that if declined the vendor cannot bid
produce at all. A nullable
priceDeltaIfDeclinedreads that as "no cost impact" — the inverse of thetruth, on the most consequential of the three.
So the consequence is a closed union:
price_delta/withdrawal/unquantified.asBidis what the vendor is offering and the only comparable number.As-if-declined is computed and shown beside it and never ranks — accepting an exception is the
retailer's call, and folding it into the ordering is the system pre-deciding it.
withdrawalexception makes as-if-declined null, reasonwithdrawal_conditioned, reusingthe Decision 3 machinery. Anacostia's own arithmetic (624,315 + 18,400 + 9,750 = 652,465) is
internally consistent and still incomplete, because it silently omits the exception that cannot be
added.
section. Detecting it is valuable; pricing it is a model deciding. It surfaces as a finding and
renders indeterminate.
"never checked" must not look alike — the
answered/not_answereddistinction from #36.Two defects the corpus check caught that review would not have
Both were found by assertions failing, not by reading the code.
The band ladder priced two different ways depending on a flag. Bands read naturally as
[0, 11999]then[12000, 23999], and subtracting those bounds in the marginal path loses the unitbetween them — one unit in 21,400, invisible in the total and wrong in the record.
tois inclusivefor whole-basket selection; marginal reads the next band's
fromand treats the ladder ashalf-open.
bandsContiguousnow rejects any ladder where the two readings disagree, because astructure that prices differently depending on a flag is not something to discover during a protest.
The published scenario was quantizing the seasonal factor.
monthlyDistributionstarted astwelve basis-point shares. Rounding twelve shares moved the weighted factor by 3e-5 — about $19
on a $624,000 line — and #22 is emphatic that rounding erases results. The fix was to stop
normalising: the field is now
monthlyWeights, raw non-negative integers, and a school calendarpublishes instructional days per month as an exact integer nobody has to round. The evaluator takes
the ratio last. The independent float check now agrees to nine decimal places instead of five.
The second one is the more interesting finding. The evaluator was exact the whole time; the input
format was throwing away precision before the evaluator ever saw it, which no amount of careful
arithmetic downstream could recover.
Verified
Schema updated alongside:
price_line.required,evaluation_scenario.monthly_weights, a newscenario_variabletable under the basket's disclosure class,exceptionrebuilt around theconsequence union, and
derived_costcarrying nullable amount + reason + breakdown +evaluator_version + inputs_hash + voided_by_amendment_id.
Handoffs
derived_costis now an evidentiary row, not a cached number. The recompute-as-checkrule and the void-on-amendment rule both belong to the audit design, and the "database-level tests
are not optional" note already sitting on that ticket now has a concrete first subject.
absent from the truth file). That makes exceptions a completeness signal feeding the sweep, not
merely a response field.
instructionalWeeksis a school foodcontract's variable; logistics and facilities will want their own. Worth checking the spine's
groups against it rather than discovering the gap per-RFP.
What this does not settle
Translating a PDF into these structures is extraction (#16) and is unbuilt — the corpus check
transcribes structures by hand from the truth files, so it verifies the evaluator, not the
extractor. The greater-of shape stays deferred behind
shape_unsupported. And every number herecomes from one solicitation in one category: the vocabulary has met food service and nothing else.