Tier-3 Calc Host conformance
Tier-3 Calc Hosts evaluate custom_calculations blocks (and the calculations declared by loaded modules) using the safe-expression language defined in UW_PROTOCOL_v1.md Part VIII.
A Tier-3 host MUST:
- Parse the safe-expression grammar exactly as specified (no eval, no arbitrary code execution).
- Resolve variable references via
parser.deepGetsemantics against the parsed file. - Implement the built-in functions:
sum,avg,npv,irr,pmt,if,coalesce,round. - Be deterministic: same inputs → same outputs, every run.
- Surface
CalcErrorobjects per the taxonomy in Part XI.
Fixtures
fixtures/<scenario-id>/
├── deal.uw.md Input deal file
├── calc.json The calculation declaration to evaluate
└── expected-result.json Expected CalcResultProvided scenarios
| Scenario | Tests |
|---|---|
fixtures/revpar-basic | RevPAR = adr × occupancy with literal inputs from quick_metrics |
fixtures/dscr-from-section | DSCR derived by deepGet path resolution across noi_model and debt_structure sections |
Refinement scenarios
A separate refinement/ subdirectory exercises the dependency-graph extraction used by the v1.1 refinement engine (extractDependencyGraph from @uwmd/core/calc/dependencies):
refinement/<scenario-id>/
├── deal.uw.md Input deal file
└── expected-graph.json Expected projection of the dependency graph
(sorted maps and sets for stable comparison)| Scenario | Tests |
|---|---|
refinement/dependency-graph-multifamily | Multifamily pack only (no custom_calculations); asserts the calc → input edge set matches the recorded shape |
Run via:
bash
node scripts/run-conformance.mjs --tier=3Comparison strips the volatile evaluated_at timestamp from expected-result.json. The refinement scenario uses byte-exact comparison against expected-graph.json after sorting maps and sets.