Skip to content

From stated lease-up periods to an explicitly dated stream ​

RFC 0044 ships in core/CLI 2.8.0, with Protocol 2.11.0. The browser-safe projectLeaseUpCashFlows API and read-only CLI copy verified stated amounts onto caller-supplied dates and return source digest/binding evidence.

Install the published CLI with npm install -g @uwmd/[email protected], or invoke npx @uwmd/[email protected] project-lease-up deal.uwx.md cash-dates.json --json. The worked repository example below uses the same published API.

Run it ​

From the repository root, after building:

sh
npm run build
node scripts/verify-lease-up-workflow.mjs

The runner reads the existing RFC 0008 valid-value-add-turnover conformance fixture and the authored scenario in docs/examples/lease-up-dated-cash-flow.json. The source fixture intentionally exercises the legacy reader; this workflow creates no new Markdown document. Its source variant is explicitly base. Each cash date, day count and discount rate is stated in the scenario, not inferred from the period label.

The two amounts, 118475 and 123425, are copied from that synthetic source fixture. The dates 2026-09-30 and 2026-12-31 and the 0.08 rate are illustrative caller inputs, not recommendations. The script:

  1. Calls projectLeaseUpCashFlows with an exact variant and complete date map.
  2. Checks returned binding amounts against the authored scenario. The adapter validates structure and verifies the source before copying any amounts.
  3. Checks the authored dated series through datedFlowsOf.
  4. Uses xnpvOf and the existing currency boundary to report its present value.
  5. Confirms source bytes are unchanged and prints JSON for review.

The sample run reports 239528.83, anchored to 2026-09-30, under actual/365f. That number was generated by the core engine. The workflow smoke test keeps the runner executable; it is not an independent numerical oracle or conformance proof by itself. Separate API tests and the default lease-up-projection conformance suite exercise the adapter contract.

What the numbers mean ​

The source contract defines net_cash_flow as rent revenue plus concessions plus TI/LC capex. Those are the only flows represented here. Operating expenses, reserves, acquisition cost, debt service and disposition proceeds have not been supplied. The result therefore describes this partial stream's present value, not property value, project NPV, equity IRR or Argus parity.

Cash dates are a separate assertion from accrual periods. The first actual cash date is the existing calendar metric's anchor. The runner does not insert a zero acquisition-date flow, infer an exit, annualize NOI or invent cash timing. It computes no investment-return metric from this incomplete stream.

Use the API or CLI ​

ts
import { parseUWFile, projectLeaseUpCashFlows } from '@uwmd/core';

const parsed = parseUWFile(sourceText);
const candidate = await projectLeaseUpCashFlows(parsed, {
  source_variant: 'base',
  day_count: 'actual/365f',
  cash_dates: [
    { period: '2026-Q3', date: '2026-09-30' },
    { period: '2026-Q4', date: '2026-12-31' },
  ],
});

Browser consumers import the same API from @uwmd/core/browser. For the repository fixture and supplied plan, run:

sh
npm run cli -- project-lease-up conformance/lease-up/valid-value-add-turnover/deal.uwx.md docs/examples/lease-up-cash-dates.json --json

The CLI always prints a successful candidate as JSON. With --json, a refusal prints { "error": { ... } } and exits 1; otherwise it prints the error to stderr. Input files are never rewritten and write/output flags are refused. The host owns any subsequent Tier-2 edit and provenance.

candidate.series is a CashFlowSeries with the label Lease-up receipts and TI/LC only, kind: "other" rows and no stated metrics. Amounts retain their exact binary64 values, including zero. candidate.bindings names each canonical period path, date and amount; candidate.source_variant applies to all bindings. candidate.source_envelope_digest identifies the full semantic source envelope, including superseded history, rather than the raw Markdown bytes.

The map must cover every selected source period exactly once. Its input order may differ; output follows source schedule order. Dates must be real calendar days and non-decreasing in that order. Cash dates may differ from accrual periods. Same-day rows remain separate, so a date selector over duplicates still refuses ambiguity. The first actual cash date anchors calendar metrics.

The API throws LeaseUpCashFlowProjectionError. Its serializable .proto contains CALC-LU-PROJECTION, a source/plan pointer and optional evidence: the original selection error, LU structural diagnostics, or verifier verdict and issues. Failed and unverifiable schedules remain distinct. Missing amounts are refused rather than filled with zero. No period/date defaults are supplied.

Remaining implementation boundary ​

Full DCF assembly requires a separate contract for economic coverage, valuation anchor and double-count prevention. Speculative leasing additionally needs renewal/vacancy, rent resets and TI/LC timing rules. A dated projection alone does not supply them.

Released under the MIT License.