IC summary verdict
Hold
Coverage on the financing proposed in the OM is using underwriting NOI; the ask is above the value the OM’s own financing and return terms support. The seller’s rooms-revenue claim exceeds the operator statement by .
USALI-structured hotel underwriting
KeyTwelve normalizes a hotel deal package to the USALI 12th Revised Edition and checks the seller's numbers against the seller's own documents — every figure naming the cell it came from.
IC summary verdict
Coverage on the financing proposed in the OM is using underwriting NOI; the ask is above the value the OM’s own financing and return terms support. The seller’s rooms-revenue claim exceeds the operator statement by .
| Account | T‑12 Actual | Underwriting |
|---|---|---|
| Rooms Revenue | $4,373,655 | |
| Total Operating Revenue | $4,998,000 | |
| Net Operating Income (NOI) | $1,387,366 | $1,176,666 |
⋯ 21 further statement lines ⋯
The offering memorandum states one figure for current trailing-twelve rooms revenue. The operating statement attached to it states another. Same department, same period, $426,345 apart.
Current performance
Trailing-twelve rooms revenue of $4,800,000 reflects a stabilized occupancy base and sustained rate performance, with the airport submarket absorbing recent supply ahead of expectation.
$4,800,000T-12 Operating Statement
B14 · $4,373,655T-12 ending June 30, 2026
both stated as actualsThe lineage is not a log written after the fact. It is the operation: lineage::sum returns the value and its operand tree in the same call, so there is no path through the kernel that produces a figure without producing its provenance.
Rooms + F&B + Other Operated + Miscellaneous
crate/src/registry/pl.rs · assemble · v0.9.0
// every metric returns a tree, not a scalar
let total_operating_revenue = lineage::sum(vec![
lines.rooms_revenue.clone(),
lines.fb_revenue.clone(),
lines.other_operated_revenue.clone(),
lines.misc_income.clone(),
])
.labeled("Total Operating Revenue");Source revision 2579ddea6af5 · lines 176–182
Riverton_Landing_T12_Operating_Statement.xlsx
| # | B |
|---|---|
| 14 | Rooms Revenue$4,373,655 |
| 15 | Food & Beverage Revenue$385,000 |
| 16 | Other Operated Departments Revenue$142,500 |
| 17 | Miscellaneous Income$96,845 |
Four cells, boxed. Nothing between them and the figure.
Tax rate × Purchase price, reassessed at sale
crate/src/registry/pl.rs · build_underwriting · v0.9.0
// one operand is ours, and the tree says so
let property_tax = lineage::round(
lineage::mul(deal.property_tax_rate.clone(), deal.asking_price.clone()),
0,
)
.labeled("Property Tax (Fixed)");Source revision 2579ddea6af5 · lines 511–515
Riverton_Landing_Offering_Memorandum.pdf
p. 1 · $21,500,000One operand is cited. The other is ours, and carries no box.
requires Property RevPAR and Comp-Set RevPAR; this computation carries no usable Comp-Set RevPAR (parsed for it: Riverton_Landing_Market_Overview.pdf)
Property RevPAR ÷ Comp-Set RevPAR × 100
The ? is where honesty lives: a missing operand returns a withheld state instead of a number.
Requires Comp-Set RevPAR; the package carries no competitive set. It is not zero, and it is not blank.
crate/src/registry/kpis.rs · market_index · v0.9.0
// the ? that refuses to guess
match computed {
Some(value) => Metric::computed(channel, value),
None => Metric::data_dependent(channel, Withholding::derive(ctx, channel.requirements())),
}Same function shape as the figures above. The missing operand propagates a named state, which is why a withheld metric keeps its row.
Source revision 2579ddea6af5 · lines 229–232
Riverton_Landing_Market_Overview.pdf
T-12 ending June 30, 2026
No competitive set is included in this package.
The market report is in the package. It carries demand segmentation, not a competitive set — so the box marks an absence rather than a citation.
The boxed region moves with the metric — and where a number is ours, there is nothing to box.
Both figures feed the verdict above — the same nodes, not a second calculation done for display.
Every line of the underwriting is set against the trailing statement that should support it. Agreement is stated as plainly as disagreement, because a reconciliation that only reports problems is not a reconciliation.
| Line | T-12 records | Underwriting applies |
|---|---|---|
| Management Fees | $0 | $149,940 |
| Property Taxes | $149,940 | $210,700 |
The sample deal is recomputed from the sealed extraction on every release, and the output hashes are published.
Three steps, each shown by the thing it produces.
Whatever the broker sent. Extraction is model-assisted and disclosed as such; what a document does not contain is recorded, not filled in.
producer source observations
⋯ 14 further mapped lines ⋯
One chart of accounts, so two deals are comparable. A sample of the mapping, not a statement — the totals are struck on the deal page. Structured to the USALI 12th Revised Edition.
Ungated, on its own URL, including the parts that did not resolve.
Three documents on a 102-key select-service asset.
Riverton Airport Market · T-12 ending June 30, 2026 · asking $21,500,000.
A $544,004 pro-forma gap that foots exactly, and a rooms-revenue figure the seller's own two documents disagree on.
One metric, naming the input it lacked.
RGI — no competitive set in the package.
The backend stores deal documents; Anthropic assists extraction and normalization; server-side calculations produce the finished deliverable.
Deal content is not used to train models — not by us, and under Anthropic's Commercial Terms, not by Anthropic.
The sample deal is public and ungated, including the rooms-revenue break and the withheld metric.