build 20260518-0000 Military Bases Colleges Seattle Rate AI / Chips
← Explorer MILBASE — Thesis & Research Research · Not Advice

Military-Base Housing: The Data-Driven Thesis

MILBASE aggregates US military installation data — BAH rates, troop counts, base locations — into a single sourced, NULL-honest store and visualizes it as a rental-investment screening tool. Every rate is real. Every NULL is declared. The moat is assembly, not the raw facts.

What is MILBASE?

MILBASE is a data aggregation and visualization project. It pulls together three things that are individually public but collectively painful to assemble:

Core data

BAH Rates

Basic Allowance for Housing — federally set, annually published per Military Housing Area (MHA) × paygrade × dependent status × year. Currently 14 years of history (2013–2026), 24 paygrades, 402 MHAs.

Core data

Installations

~459 US military bases — name, branch, base type, state, lat/lon, troop count, founded year. Sourced from Wikipedia (CC-BY-SA / DoD Base Structure Report) and OpenStreetMap (CC-ODbL).

Derived

Local Real Estate

Market rent and home values for feeder towns near each base. Sourced from Zillow ZORI/ZHVI (free ZIP-level CSVs). Currently covers ~48 bases; expands as geocode joins complete.

The discipline: every row carries a real source, or an explicit NULL. Partial real > fabricated complete. Coverage% is always reported.

The BAH Thesis — Why BAH Creates a Rent Floor

BAH (Basic Allowance for Housing) has three properties that make base-adjacent rental markets commercially interesting:

  1. Predictable. Rates are set per MHA × paygrade × dependent status × year and published in advance. BAH is a forward-looking indicator, not a lagging one. A landlord can look up the 2026 E5 w/dep rate for their MHA before setting asking rent.
  2. Demand-anchoring. Near a base, a meaningful share of rental demand is effectively underwritten by federal housing allowance. Service members receiving BAH have a budget floor defined by the federal rate schedule — and they must spend it on qualified housing.
  3. Scattered + access-hostile. The source data is fragmented across DoD tables, MHA crosswalks, and base fact sheets. The DoD lookup tool is bot-walled (403). The moat is assembly, not the raw facts — public information that is painfully hard to aggregate in one place.

The Investment Screen

The thesis translates into a three-factor screen for acquisition targets:

Factor 1

High BAH Yield

BAH rate vs. local home price = implied gross yield. A market where BAH supports a meaningful yield relative to acquisition cost is the starting filter.

Factor 2

Low Price-to-Rent

Market rent vs. home price. A low ratio means the income is real relative to the cost basis — not compressed by speculation. Combined with BAH, this defines the buy-box.

Factor 3

Acceptable Risk Gate

Closure risk (BRAC indicators), physical hazard (FEMA NRI), and area trajectory (population/jobs/permits). Risk enters the score as a multiplier — a fatal risk base can't be rescued by yield.

The Honest Constraint

"Guaranteed floor" is an overclaim. BAH is set annually by DoD/Congress; rates can be cut or the formula changed — it has been adjusted before. The correct framing: BAH is a support signal, not a guarantee. Underwrite to market rent; treat BAH as a floor reference, not a contractual ceiling. Stress BAH −10%/−20% in any model.

The thesis is designed, not validated. Historical backtest methodology is specified (see Research Library → Thesis Validation) but has not been run. Do not market returns until the pre-registered backtest completes.

How to Read the Tool

The MILBASE tool has three views. Each answers a different question in the investment decision path.

1

Explorer

Search and sort all bases. Select a base → see its BAH chart over 14 years, all paygrades. Sort by troop count, acres, or founding year. This is the primary screening surface.

2

Map

All ~459 installations plotted on a US map. Dot size = troop count (area-proportional). Click a dot → syncs with Explorer. Drag to pan, scroll to zoom. Identifies geographic clustering and sub-markets.

3

All Bases

Scatter plot: pick any two features as X and Y axes. All 459 bases plot on that scatter, colored by state. Use this to find outliers — unusual BAH yield, unusually old/large bases, high-troops low-price markets.

The Decision Path

  1. Map → Discovery. Big dots = large troop count = more BAH-paying tenants. Identify sub-markets by geography.
  2. Explorer → BAH chart. Select a base. Is the BAH trend rising? Flat? Multi-year history shows whether the rent floor is growing or stagnant.
  3. Explorer → RE panel. (arriving when Y-city-econ expands) Market rent and home price for feeder towns. Price-to-rent ratio is the headline entry metric.
  4. All Bases → Screen. BAH yield vs. price-to-rent scatter finds the high-yield, low-cost quadrant — the fund's sourcing shortlist.
  5. Score vector → Risk gate. (arriving when scoring impl lands) Composite 0–100, always shown with Yield / Stability / Risk sub-scores. Elevated closure or hazard tier = exit regardless of yield.

Reading the BAH Chart

Research Library

The following analyses were authored by the research lane (pink) and are published here without modification. CYAN is a read-only surface — it does not alter research findings. All numbers are [ASSUMPTION] tagged unless structural facts of the dataset. No figures fabricated.

Source: projects/milbase/ETF-THESIS.md pink · shipped 2026-05-17 · commit 1ddc6f9

1. Mechanics — and the Honest Structural Problem

The common pitch is a "military-housing ETF." The ETF wrapper is the wrong structure, and it matters. ETFs require a liquid, continuously-priced underlying and in-kind creation/redemption. Physical scattered-site single-family homes are illiquid, slow to price, and cannot be delivered in-kind. A literal SFR-holding ETF is not viable.

Realistic structures, ranked [JUDGMENT]:

Best fit

Private RE Fund / LP

Cleanest match. Illiquid capital matched to illiquid assets. Institutional/accredited investors. No liquidity mismatch.

Broader access

Non-traded / Traded REIT

Traded REIT reintroduces a price that can dislocate from NAV. Non-traded REIT has known fee/transparency baggage — disclose it. Both viable, with caveats.

Semi-liquid

Interval Fund

Periodic limited redemptions. Structural risk: illiquid homes inside a redeemable wrapper = classic run/gating setup. Viable only with conservative redemption caps and disclosed cash buffers.

Recommendation: Pitch as a private RE fund (or interval fund with strict gates). Drop the "ETF" label — it misdescribes the legal reality.

2. The Screen — The Genuinely Strong Part

The MILBASE tool is the deal-sourcing engine. The screen is coherent:

  • Rank all bases by BAH-implied yield and price-to-rent (HEURISTICS signals; "N of 459" rank in Explorer).
  • Filter: high BAH yield ∩ low price-to-rent ∩ acceptable Risk gate (SCORING model — closure/hazard/trajectory).
  • Output = ranked, sourced acquisition pipeline with provenance. A real, defensible thing to build a fund's sourcing on.

This is the part of the pitch that holds. The data product has a purpose.

3. Comps

Institutional single-family rental is a proven post-2012 asset class; large operators institutionalized scattered-site SFR at scale, and some carry meaningful Sunbelt / base-adjacent exposure. No tickers, returns, or AUM are asserted here (HARD RULE — the company-side data is an unbuilt pull). The honest statement: precedent for the operational model exists and is investable evidence the mechanics work. Precedent for the specifically base-concentrated variant must come from filings, not assertion.

4. Honest Risks

RiskWhy It's SeriousMitigation (honest)
BRAC / closure concentration A base-concentrated portfolio has correlated tail risk. One BRAC round can impair a whole sub-portfolio at once. This is THE risk. Cap exposure per base/MHA; use Risk gate to exclude Elevated-closure bases; diversify across branches/regions — accept lower yield for it.
"Guaranteed" floor isn't guaranteed BAH is set annually by DoD/Congress; rates have been adjusted before. "Guaranteed rent floor" is overclaim. Underwrite to market rent; treat BAH as support not guarantee. Stress BAH −10%/−20%.
Liquidity mismatch Illiquid homes in any redeemable wrapper → gating/run risk. Private/LP structure, or interval fund with hard redemption caps + cash buffer.
Operational scaling Scattered-site SFR property management is hard; returns erode on bad ops. Concentrated submarkets for PM density; model real opex (not fabricated).
Thesis unproven Outperformance claim is designed, not validated (see Thesis Validation). Do not market returns until the pre-registered backtest runs.

5. Honest Verdict

The mechanics are sound, the wrapper is mislabeled, the edge is real but unproven, and the dominant risk is concentration. This is a credible private real-estate fund thesis with a genuinely differentiated sourcing engine — not an ETF, and not something to attach return figures to until the backtest validates it. Marketed honestly (support not guarantee, concentration disclosed, structure correct), it's a real pitch.
Source: projects/milbase/OPPORTUNITY.md pink · shipped 2026-05-16 · commit 5e1b832

The Underlying Asset

BAH has three properties that make it commercially interesting:

  • Predictable — rates are set per MHA × paygrade × dependent-status × year and published in advance. Forward-looking, not lagging.
  • Demand-anchoring — near a base, a meaningful slice of rental demand is effectively underwritten by the federal government via BAH.
  • Scattered + access-hostile — the source data is fragmented. The moat is assembly, not the raw facts.

Four Angles

Angle 1 — BAH-Anchored Rental Underwriting ("Rent Floor")

An address near a base → resolve MHA → show BAH by paygrade + adjacent base branch/type/troops → underwriting view: BAH-implied rent band vs. asking rent.

  • Feasible on free data? Yes for BAH/base; the ZIP→MHA crosswalk is public but must be sourced separately.
  • Risks: Regulatory (needs disclaimer if advice-adjacent); data-quality (BAH resets annually — must surface year+source); BRAC concentration.
  • Standalone monetization: High — converts a raw rate into an underwriting decision for SFR investors and RE syndicators.

Angle 2 — PCS-Cycle Timing Signal

PCS (Permanent Change of Station) season concentrates housing turnover near bases in roughly the mid-year window. A demand-index by market/month.

  • Feasible? Partially — base/troop side yes; seasonality is directional, not precise.
  • Recommendation: Fold into Angle 1 as a feature; not viable as standalone.

Angle 3 — Public-Equity / Base-Exposure Screen

Map publicly traded SFR/defense-adjacent REIT operators to base concentration via troop_count as BAH-demand proxy.

  • Feasible? Medium-low — company portfolio data is the binding constraint (10-K property schedules, unstructured).
  • No tickers or returns asserted — category-level only until real filing data is ingested.

Angle 4 — The Sourced Dataset Itself, as a Product

Package the assembled store (installations + BAH series + troop counts), every row sourced or explicit NULL, as a queryable screener / downloadable dataset / API.

  • Feasible? Yes — zero additional data beyond what Y ships.
  • Moat: "We did the painful aggregation of bot-walled, scattered DoD sources into one clean, NULL-honest, sourced store."

Ranked Shortlist → Future Tickets

#DirectionFeasibilityDifferentiationStandalone $
1Angle 4 — Sourced dataset/screener Highest (Y's output, nothing extra)High (assembly moat)Medium
2Angle 1 — BAH underwriting tool High (+ ZIP→MHA crosswalk)HighHigh
3Angle 3 — Public-equity screen Medium-lowMedium-highLow
4Angle 2 — PCS timing signal Partial (heuristic)LowLow

All economic characterizations are [ASSUMPTION] pending real comp/market research. No figures fabricated.

Source: projects/milbase/RISK.md pink · shipped 2026-05-16 · commit 5e1b832

1. Closure Risk (BRAC)

US base closures run through the Base Realignment and Closure (BRAC) process — independent commission rounds in 1988, 1991, 1993, 1995, and 2005. A closed or realigned base can collapse the BAH-anchored tenant base that the entire MILBASE thesis depends on. This is the single largest tail risk.

No fabricated closure probabilities. Instead, a reasoned indicator framework — directional, evidence-based, labeled [JUDGMENT]:

IndicatorHigher-risk signalData field
Single-mission concentrationOne mission/tenant unit; no joint use base_type, branch
Force-structure trendDeclining troop_count over time; drawdown branch troop_count (time series needed)
Strategic redundancyFunction duplicated at multiple installations branch + base_type clustering
Prior BRAC exposureRealigned/shrunk in a past round DoD BRAC reports 1988–2005 (public domain)
Base size / infrastructure depthSmall footprint, low capital depth acres, established_year
Political/economic anchoringLow regional economic dependence BEA/BLS regional employment share (external)

Output rule: every base gets a closure-risk tier (Low / Moderate / Elevated) with a one-line reason citing which indicators fired — never a fabricated percentage.

2. Geographic / Physical Risk

HazardFree SourceGeography
Flood, hurricane, wildfire, earthquake, heat — composite FEMA National Risk Indexcounty/tract → join via FIPS
Flood detailFEMA NFHL / flood map serviceparcel/zone
EarthquakeUSGS seismic hazardlat/lon
Hurricane / climate trajectoryNOAAcoastal proximity

FEMA National Risk Index is the recommended spine — one free dataset gives a composite + per-hazard score per county, joinable on installation county FIPS.

3. Area Trajectory (Up vs. Down)

SignalFree SourceRead
Population trendCensus ACS / PEPgrowth = demand tailwind
Jobs / unemploymentBLS LAUS & QCEWdiversification = resilience
Building permitsCensus Building Permits Surveysupply pressure
Price / rent momentumFHFA HPI + Zillow ZORIreuses area-econ outputs

4. Known Data Gaps

  • Troop count time series — current schema holds a point value; force-trend (strongest closure indicator) needs history.
  • Mission / tenant-unit per installation — needed for single-mission concentration; not yet in schema.
  • Regional economic dependence — derivable from BEA/BLS but not yet sourced.
Gaps flagged, not faked. Scoring must down-weight indicators we can't yet populate rather than invent values.

Sources (all free, authoritative)

  • DoD / BRAC Commission final reports (1988, 1991, 1993, 1995, 2005) — public domain
  • FEMA National Risk Index; FEMA NFHL — free, public domain
  • USGS seismic hazard; NOAA climate/hurricane — free, public domain
  • Census ACS / PEP / Building Permits Survey — free, public domain
  • BLS LAUS & QCEW — free, public domain
  • FHFA HPI; Zillow ZORI — free
Source: projects/milbase/SCORING.md pink · shipped 2026-05-16 · commit 5e1b832

A defensible 0–100 ranking of each base as a rental-investment target. Decomposed into three sub-scores: Yield, Stability, and Risk. This is a research spec — implementation is a separate ticket.

1. Feature Set

Numerical

FeatureSourceSub-score
BAH level (paygrade-selected, w/dep)bah_ratesYield
BAH growth (CAGR over years)bah_rates time seriesYield, Stability
rent-to-BAHarea_econ derivedYield
price-to-BAHarea_econ derivedYield
BAH-implied gross yield / caparea_econ derivedYield
troop_countinstallationsStability
acresinstallationsStability
established_year → tenureinstallationsStability
area momentum (FHFA/Zillow)AREA-ECON / RISK §3Stability

Categorical → Tiered

FeatureEncodingSub-score
branchone-hot, no implied ordercontext
base_typetier by durability [JUDGMENT]Stability
closure-risk tierLow→1.0 / Mod→0.6 / Elevated→0.2Risk
physical-hazard tierLow→1.0 / Mod→0.6 / Elevated→0.2Risk
trajectory tierImproving→1.0 / Stable→0.6 / Declining→0.3Risk

Tier→multiplier values are [ASSUMPTION] — chosen monotonic and round for transparency, tunable once real data exists.

2. Normalization

  • Continuous features: min–max to [0,1] across the populated base universe (not z-score). Robust min–max: clip to 5th/95th percentile before scaling.
  • Directionality: invert cost-like features so higher = better (e.g. rent-to-BAH: lower is better → use 1−norm).
  • Missing values: do not impute. A NULL feature is excluded; sub-score renormalized over present features; coverage% reported.

3. Formula

Yield = w1·invn(rent_to_BAH) + w2·norm(BAH_implied_yield) + w3·invn(price_to_BAH) + w4·norm(BAH_growth) [ASSUMPTION] w1..w4 = 0.30, 0.35, 0.20, 0.15 Stability = v1·norm(troop_count) + v2·norm(tenure) + v3·norm(acres) + v4·norm(area_momentum) + v5·tier(base_type) [ASSUMPTION] v1..v5 = 0.35, 0.15, 0.10, 0.20, 0.20 Risk = closure_tier_mult × hazard_tier_mult × trajectory_tier_mult (multiplicative: any one fatal dimension dominates) SCORE = 100 × Risk × (0.6·Yield + 0.4·Stability) [ASSUMPTION] Yield weight 0.6, Stability weight 0.4
Key design decision — Risk as multiplier, not additive: A fatal-risk base (Elevated closure, Elevated flood) cannot be rescued by high yield. Multiplication enforces this; addition would let it average away. The composite is never displayed without the sub-score vector — prevents one number hiding a fatal risk.

4. Missing Inputs (→ Data Tickets)

MissingBlocksStatus
BAH multi-year historyBAH growth, momentum ✅ Shipped (14yr 2013–2026)
rent / price (ACS, Zillow)all Yield features ⏳ Partial (48/459 bases)
ZIP→MHA crosswalkevery area join ⏳ Partial (183/459 joined)
troop_count time seriesStability + closure trend ⏳ Pending (point value only)
FEMA NRI / FHFA joinsRisk, momentum ⏳ Pending data ticket
Source: projects/milbase/PRODUCT-DEF.md pink · shipped 2026-05-16 · commit f751e8f

1. Who Uses It

PersonaJob-to-be-donePriority
Base-market residential investor (SFR/BTR, small RE-PE) "Where, near which base, should I buy — and what's the catch?" Primary (MVP target)
RE-fund analyst Screenable, IC-defensible base-market ranking; a credible work artifact Secondary
Relocation / property-mgmt operator Demand durability + rent floor near a base Later

2. The One-Screen Deliverable

┌───────────────────────────┬──────────────────────────────┐
│  LEFT (Explorer)          │  RIGHT (Map)                  │
│  • search/sort base list  │  • US map, size = troop_count │
│  • BAH-over-year chart    │  • click dot ↔ list (postMsg) │
│  • RE panel: price/rent/  │                               │
│    price-to-rent ratio    │                               │
├───────────────────────────┴──────────────────────────────┤
│  DECISION PANEL (selected base)                           │
│  SCORE 0–100  ·  Yield __ | Stability __ | Risk __        │
│  Risk flags: closure / hazard / trajectory (tiers+why)    │
│  Coverage __%  ("NULL — reason" when data thin)           │
└───────────────────────────────────────────────────────────┘

The screen answers one question end-to-end: revenue (BAH) vs. cost (RE panel) → ratio → score → the catch (risk flags) — one decision path, no dead ends, honest NULLs.

3. MVP vs. Later

MVP (buildable on current/near-term tickets)

  • Map + searchable/sortable base list (shipping)
  • BAH chart with 14-year history (shipped)
  • RE panel: price, rent, price-to-rent (G-re-panel + Y-city-econ)
  • Composite score + Yield/Stability/Risk vector + coverage%
  • Risk tier flags with reasons — honest partial coverage, NULL-with-reason

Later (post-MVP backlog)

  • Validated thesis results surfaced in-app (THESIS-VALIDATION, after backtest runs)
  • Watchlist / alerts on score or BAH changes
  • Dataset/API product (Opportunity Angle 4)
  • Public-equity base-exposure screen (Opportunity Angle 3)

4. Decision Path

  1. Map = discovery. Big dots = large demand. Find submarkets.
  2. BAH chart = revenue durability. Is the rent floor rising?
  3. RE panel = cost. Price, market rent, price-to-rent headline.
  4. Score vector = synthesis. Yield + Stability + Risk gate.
  5. Risk flags = disqualifier check. Elevated closure → exit.

5. Non-Goals

  • Not investment advice — data + transparent score, with disclaimer.
  • Not a transaction/marketplace.
  • No fabricated coverage — sparse data shows as NULL+reason, by design.
  • No CDN/online deps — all offline-served.
Source: projects/milbase/COMPETITIVE.md pink · shipped 2026-05-17 · P-MILBASE.competitive

1. The Landscape

A. BAH Calculators / Lookups (the crowded part)

ToolWhat it does
Military.com BAH calcEnter ZIP + paygrade + dependents → current BAH rate. The default consumer tool.
Veteran.com BAHBAH rate tables + yearly comparison content.
CollegeRecon BAHBAH lookup oriented to GI-Bill/student vets. [CATEGORY]
Navy Federal BAHBAH lookup tied to mortgage/banking funnel. [CATEGORY]
travel.dod.milAuthoritative rate lookup; bot-walled (per MILBASE recon).
Common shape: single-purpose rate lookup — "what is BAH here, now." No location-comparison, no real-estate economics, no investment lens.

B. BAH Maps / Visualizations (sparse)

  • mpyne BAH map (github.com/mpyne-navy) — open-source map visualizing BAH geographically. Closest visual analog to MILBASE's map. Gap: visualization only — no RE overlay, risk, or screen.

C. SFR / Military-Housing Investing (separate world)

  • Institutional SFR REITs — own/operate SFR at scale; some Sunbelt/base-adjacent exposure. [CATEGORY]
  • Privatized base housing (MHPI operators) — on-base housing under DoD contracts. [CATEGORY]
  • Generic RE screeners — comps/rent/yield, not BAH-aware.

These have the investment lens but no BAH anchor and no base-closure/risk model.

2. The Honest Verdict

Differentiation (real, but conditional): MILBASE's distinct claim is the combination — BAH × local RE economics × closure/hazard risk × a ranked investment screen — in one tool. That specific combination is genuinely uncommon: the BAH world is rate-lookups; the investing world ignores BAH; the maps are visualization-only. The whitespace is the join, not any single component.
Three honest caveats:
1. Each component exists somewhere. The moat is assembly + the screen + provenance discipline, not novel data — exactly what OPPORTUNITY.md Angle 4 and ETF-THESIS.md already concluded.
2. The differentiator is currently unrealized. The DB is 347/459 and area_econ/established_year are sparse. The BAH×RE×risk combo is the product — and the RE/risk half isn't populated yet. Until fix-sparse runs, MILBASE is, in shipped reality, another BAH map.
3. Low barrier to fast-follow. The durable moat is execution + the validated thesis, not the concept.

3. Whitespace (where to push)

  • The screen/ranking ("N of 459 by BAH-yield, risk-gated") — nobody packages this. Highest-differentiation surface.
  • Time-aligned BAH-vs-local-RE (2013–26) — calculators are point-in-time; the trend join is unoccupied.
  • Closure/risk-adjusted view — absent everywhere.
  • Avoid competing as "a better BAH calculator" — that lane is saturated and not the edge.

Sources: military.com · veteran.com · collegerecon.com · navyfederal.org · travel.dod.mil · github.com/mpyne-navy. Category-level claims labeled [CATEGORY]; no figures, tickers, or features fabricated.

Source: projects/milbase/CLOSURE-PROB.md pink · shipped 2026-05-17 · commit 830411d

Honest Framing

A literal "probability of closure" for a given base cannot be derived from public data — BRAC is an episodic, political, congressionally-authorized process, not a stationary random event. Emitting "Base X: 23%" would be fabrication dressed as math. This delivers a transparent ordinal risk index (0–100, modeled) that ranks relative closure exposure with stated reasoning — and says plainly it is not a calibrated probability.

1. Inputs

InputProxySourceIn DB?
Prior BRAC exposureRealigned/closed in 1988–2005 rounds DoD/BRAC Commission final reports (public domain)external
Single-mission concentrationOne tenant/mission, no joint use base fact sheets; base_typepartial
Force-structure trendTroop_count trend (declining = risk) troop_count time series⏳ gap
Strategic redundancyFunction duplicated elsewhere branch + base_type clusteringderivable
Size / sunk capitalSmall footprint = easier to close acres, established_yearpartial
Economic/political anchoringLow regional payroll share = exposed BEA/BLS regional employment shareexternal

2. Model Formula

closure_index = 100 × Σ wᵢ·sᵢ / Σ wᵢ (over NON-NULL inputs only) [ASSUMPTION] weights: prior-BRAC 0.25 ← demonstrated political will dominates single-mission 0.20 ← indefensibility force-trend 0.20 ← indefensibility redundancy 0.15 size/capital 0.10 ← softener anchoring 0.10 ← softener NULL inputs excluded + renormalized; coverage% reported. No imputation.

Band for display: 0–33 Low · 34–66 Moderate · 67–100 Elevated — same 3-tier vocabulary as RISK.md, now with a documented score behind it.

3. Mandatory Labeling

Always rendered as: "modeled closure-risk index (relative, not a probability) — method: weighted public indicators; see CLOSURE-PROB.md" + coverage%. Any value downstream without this label is a HARD-RULE violation.

4. Gaps → Data Tickets

  • troop_count time series — force-trend input; until then that input is NULL and index renormalizes (lower confidence, flagged).
  • BRAC round membership table — small Y/research ticket from public DoD reports.
Source: projects/milbase/HEURISTICS.md pink · shipped 2026-05-16 · commit 58c2605

1. Ranked Signal List

#SignalFormulaStatus
1BAH yield bah_rates.rate(E5,dep,maxyr)×12 / blended_home_value ⏳ needs area_econ
2price-to-rent home_value / (market_rent×12) (blended, NEIGHBOR-ECON) ⏳ needs area_econ
3rent-to-BAH market_rent / bah_rates.rate(E5,dep,maxyr) ⏳ needs area_econ
4troop-density troop_count / acres ✅ computable now (84 troop, acres partial)
5closure-risk tier RISK.md indicator framework → Low/Mod/Elevated ⏳ needs risk-data
6BAH CAGR 2013–26 (rate_lastyr/rate_firstyr)^(1/Δyr)−1 per MHA ✅ unblocked (14yr series live)

2. Graph Composition — What Goes Together

Only co-plot series that share a unit and a meaningful comparison. Ratios, dollars, and counts do not belong on one axis.

GraphSeriesAxisWhy together
G1 BAH vs Rent BAH $, market rent $ Shared $ y-axis, x = year Same unit; the gap IS the thesis (rent floor vs market) — must share axis to read the spread
G2 Ratios price-to-rent, rent-to-BAH, BAH yield Own axis (unitless) Ratios; never mixed with $ — different meaning, would mislead
G3 Structure troop-density, troop_count Count axis (log if skewed) Structural, not financial — separate panel
G4 Risk closure/hazard/trajectory tier Categorical band, not a line Tiers, not continuous — encode as colored band/badge
GLOBAL-SCALE INVARIANT applies to G1 and any BAH-encoded element: domain = global min→max across ALL MHAs for the active paygrade/dep filter, recomputed only on filter change — never per-base autoscale. G2 ratios likewise use a global ratio domain.

3. Ratio-Rank Rules

  • Rank is N of M where M = bases with a real value (NULLs excluded from M, shown "unranked — no data", never last-by-fiat).
  • One rank per signal; card shows rank + percentile; master chart sortable.
  • Never invent an order for NULLs.
Source: projects/milbase/FORMULATIONS.md Pink branch · shipped 2026-05-17

Six named-view derived formulas that power the curated scatter comparisons. Exact fields from milbase.db; units; sane ranges; data status. NULL propagates — never imputed.

#NameFormula (exact fields)UnitRangeStatus
1BAH-implied gross yield (BAH_E5dep_maxyr × 12) / area_econ.median_home %/yr~0.03–0.15 ⚠ needs area_econ
2Price-to-rent area_econ.median_home / (area_econ.median_rent × 12) × (years)~8–35 ⚠ needs area_econ
3Rent-to-BAH coverage area_econ.median_rent / BAH_E5dep_maxyr ratio~0.6–1.6 ⚠ needs area_econ
4BAH 13-yr CAGR (rate_lastyr / rate_firstyr)^(1/Δyears) − 1, E5/dep per MHA, 2013–26 %/yr~−0.05–0.12 ✓ 14yr series live
5Biggest avg YoY BAH jump max over consecutive yrs of (rate_y − rate_{y−1}) / rate_{y−1}, E5/dep %~−0.10–0.25 ✓ 14yr series live
6Risk-adjusted score 100 × Risk × (0.6·Yield + 0.4·Stability) — Risk = multiplicative gate 0–1000–100 ⚠ needs Yield(#1) + risk-data

Rules

  • NULL propagates: any NULL input → result NULL + reason; never 0, never imputed.
  • Out-of-range values surface as data-quality flags, not silently clamped.
  • Global-scale invariant applies to any cross-base comparison.
  • Named-views show the formula + source/year inline (auditability).
Source: projects/milbase/DSCR-SPEC.md Pink branch · shipped 2026-05-17

DSCR (Debt Service Coverage Ratio) = NOI / annual debt service. The lender test for a leveraged SFR buy — how many times rental income covers the loan payment. DSCR < 1.0 means the property does not self-fund the loan.

DSCR requires median_rent and median_home from area_econ. area_econ scalars (price_to_rent, avg_rent, home_price) are now in data.json (ee8022a). DSCR computation is pending green wiring it to the UI — shows "pending" until then.

Formula (exact)

NOI_annual = median_rent × 12 × (1 − vacancy − opex) [ASSUMPTION] vacancy = 0.06 ; opex = 0.35 (taxes/ins/maint/mgmt; tune per market) loan_amount = median_home × LTV [ASSUMPTION] LTV = 0.75 (typical DSCR loan) r_monthly = (MORTGAGE30US + spread) / 12 [ASSUMPTION] spread = +1.25% above 30-yr fixed (investor DSCR loans; band +1.0–1.5%) n = 360 (30-yr amortization) debt_service_annual = loan_amount × r_monthly × (1+r_monthly)^n / ((1+r_monthly)^n − 1) × 12 DSCR = NOI_annual / debt_service_annual
Known gap — apples-to-apples mismatch (P/Y-MILBASE.apples-to-apples): Current formula uses market_rent_2br (2BR comp) against median_home_value (all-SFR price). 2BR rent understates SFR rent; SFR price overstates a 2BR comp. Fix pending: recompute using ZHVI / ZORI same-universe (ZIP-level SFR-specific). Until resolved, DSCR figures are directional only — not investor-grade.

Interpretation

  • DSCR = 1.0 → breakeven: rental income exactly covers debt service.
  • DSCR ≥ 1.20–1.25 [ASSUMPTION] = common lender minimum. Rendered as the practical "financeable" band.
  • Breakeven rent / breakeven price: solve DSCR = 1.0 for each, holding the other — the actionable underwriting output.

BAH-Floored Variant

A second DSCR uses min(median_rent, BAH_E5dep) as income — the conservative, thesis-relevant variant: "what if only the BAH floor rents?" Primary for the investment thesis; never overclaims the full market rent.

Rate Source

FRED MORTGAGE30US — Freddie Mac 30-yr fixed; free fredgraph.csv, no API key required, official weekly data. Latest value stamped with observation date.

Rules

  • Any NULL input → DSCR = NULL + reason; never imputed (HARD RULE).
  • All five assumptions (vacancy, opex, LTV, spread, lender-min) are labeled, tunable inputs — not hard constants.
  • Coverage% reported; "DSCR pending data" shown where area_econ absent.
Source: projects/milbase/BAH-GROWTH-WINDOW.md Pink branch · shipped 2026-05-17

BAH "growth" can be measured over four time windows. Default locked at trailing-5yr CAGR; all four available as a toggle. Canonical series: paygrade='E5', with_dependents=1.

Window Definitions (exact)

KeyFormulaReads
last-1yrrate(Y) / rate(Y−1) − 1Most recent annual move; %/yr
trailing-3 CAGR(rate(Y) / rate(Y−3))^(1/3) − 1Recent 3-year trend
trailing-5 CAGR ★(rate(Y) / rate(Y−5))^(1/5) − 1Medium trend (default)
full-series CAGR(rate(Y) / rate(Y−n))^(1/n) − 1, n ≈ 13Structural long-run

NULL if required prior year absent for that MHA — no fabrication, no proxy year.

Pros / Cons

WindowStrengthWeakness
last-1yrMost responsiveNoisy — one reset dominates; bad as a standalone read
trailing-3Responsive + smoothed; catches regime changes within ~3yrStill shock-sensitive
trailing-5 ★Stable, robust to one anomalous year; honest multi-year signalLaggy — slow to reflect recent inflection
full-seriesBest structural signalMasks recent dynamics

Recommendation

Primary = trailing-5 CAGR. The thesis is a multi-year buy-and-hold demand-floor argument; a 5yr CAGR is the honest middle — stable enough to rank on, not distorted by one reset, lag acceptable for an asset held years.

Show trailing-3 alongside as the acceleration/deceleration companion. Never display a window unlabeled.

Officer-Average Variant

oavg(mha, year) = mean( rate(mha, year, p, dep=1) for p in {O1..O7} ) officer_growth = same window formula, substituting oavg(·) for rate(·) Rule: require all 7 O1–O7 rows or NULL the year (no partial-mean fudge).

Officer rates read upper-tier demand. Label distinctly from the E5 default; never blend on one axis (HEURISTICS axis-compat rule).

Source: projects/milbase/SURROUND-TOWNS.md Pink branch · shipped 2026-05-17

Deeper than rent/price alone — a livability and demand-depth profile for the feeder and adjacent towns around each base. Answers: is the area attractive and growing independent of the base itself?

Geography: reuses the RE-DATA-SPEC feeder-set (feeder_city ∪ ≤25mi Gazetteer places, capped, tie-broken by distance then FIPS). Same join keys — one geo effort, many metrics.

Metrics and Sources (all free)

DomainMetricSourceGeo join
DemandPopulation + 5–10yr growthCensus ACS / PEPPlace / county FIPS
JobsUnemployment, employment levelBLS LAUSArea → county
JobsIndustry mix / major employersBLS QCEWCounty
Housing supplyBuilding permits (units)Census BPSPlace / county
HousingVacancy rateCensus ACS B25002ZCTA / place
SchoolsSchool qualityNCES EDGE/CCD (primary); GreatSchools public (corroboration, ToS-respecting)District → place
SafetyCrime indexFBI Crime Data Explorer (free API)Agency → place

Demand-Depth Profile

  • Growing & diversified (pop ↑ + low unemployment + multi-industry) = demand cushion beyond the base → lower closure-sensitivity [JUDGMENT].
  • Base-dependent monoculture (employment concentrated in defense) = amplifies BRAC tail risk.
  • Supply pressure (permits ↑↑ vs population flat) = rent-growth headwind.

Each component cites source, year, and coverage%. NULL where unsourced — never imputed.

Handoff

Spec for a surround(base_id, metric, value, year, source) long table — yellow writes per the spec. Feeds the investment thesis (livability/demand depth) and Risk Framework trajectory vector.

Source: projects/milbase/AREA-ECON.md Pink branch · shipped 2026-05-16

Local-Area Economics: Free Authoritative Sources

Establishes the profit input — what housing actually costs near each base — to compare against BAH (the demand-anchored revenue floor). Research only; no fabricated figures.

Recommended source stack

MetricPrimary sourceKey?Notes
Market rentHUD Fair Market Rents APIBearer, free regBAH-comparable geography logic; public domain
Rent momentumZillow ZORI ZIP CSVsNoneMonthly; commercial-use flag — overlay only, not redistributable
Home valueCensus ACS B25077_001EFree keyPublic domain; lagging (5yr rolling) — use for level
Price trendFHFA HPINonePublic domain; use for momentum/cycle signal

Verification finding: HUD FMR and Census ACS are free but require free registration — keyless requests return auth errors (first-hand verified 2026-05-16). Plan a credential step before the Y scrape ticket.

Derived signals (formulas)

  • rent-to-BAH = market_rent / BAH_rate — <1.0 means BAH exceeds market rent (structural landlord margin); >1.0 means thin/negative cushion
  • price-to-BAH = median_home_value / (BAH_rate × 12) — lower = faster BAH-financed payback
  • BAH-implied gross yield = (BAH_rate × 12) / median_home_value
  • BAH-implied cap rate(BAH_rate × 12 × (1 − opex_ratio)) / median_home_value[ASSUMPTION] opex_ratio exposed as tunable

Geography join keys

All external sources key on ZIP / county-FIPS / CBSA. Critical dependency: a ZIP→MHA crosswalk is the single highest-leverage missing join — it unlocks rent, price, and underwriting in one step. Recurring dep across AREA-ECON, SCORING, UNDERWRITING, NEIGHBOR-ECON (9× flagged as of 2026-05-17).

Source: projects/milbase/SCORING-IMPL-SPEC.md Pink branch · shipped 2026-05-16 · commit f751e8f

Scoring: Exact Implementable Spec

Every judgment call from SCORING.md is locked here. Green / yellow can implement with zero discretion. Constants are [ASSUMPTION] but concrete and final for v1.

Locked decisions

DecisionLocked value
Canonical paygradeE-5
Canonical dependent statuswith_dependents = 1
Canonical BAH yearMAX(year) in bah_rates
BAH growth windowCAGR from MIN→MAX year; ≥2 distinct years required, else NULL
area_econ metric keysmarket_rent_2br, median_home_value
Outlier clipP5/P95 robust min–max
Missing featureexcluded + sub-score renormalized; never imputed
Min coverage to emit composite≥60% of sub-score weight present; else sub-score = NULL + reason

Feature list

#FeatureDirectionSource
F1bah_current (E5/dep/MAX_yr)+bah_rates
F2bah_cagr (full series)+bah_rates multi-yr
F3rent_to_baharea_econ market_rent_2br
F4price_to_baharea_econ median_home_value
F5bah_yield (F1×12/home_val)+area_econ
F6troop_count+installations
F7tenure (MAX_yr − established_year)+installations
F8acres+installations
F9momentum (hpi_3yr_pct)+area_econ (Y pending)
C1base_type_tier×installations.base_type
C2closure_tier×RISK.md §1 → 1.0/0.6/0.2
C3hazard_tier×FEMA NRI → 1.0/0.6/0.2
C4trajectory_tier×RISK.md §3 → 1.0/0.6/0.3

Formula

Yield = Σ wi·ni / Σ wi over {F3:0.30, F5:0.35, F4:0.20, F2:0.15} Stability = Σ vj·nj / Σ vj over {F6:0.35, F9:0.20, C1:0.20, F7:0.15, F8:0.10} Risk = C2 × C3 × C4 (multiplicative gate, ∈[0,1]) SCORE = 100 × Risk × (0.60·Yield + 0.40·Stability) Output vector: {score, yield, stability, risk, coverage_pct, reason?}

Normalization: robust P5/P95 clip → (xc−lo)/(hi−lo); direction-− features invert with 1−n. Weights are [ASSUMPTION] — renormalize over present features only. NULL score (with reason) if any sub-score below 60% coverage floor.

Source: projects/milbase/THESIS-VALIDATION.md Pink branch · shipped 2026-05-16 · commit f751e8f

Historical Thesis Validation — Design (Pre-Registration)

Design only. No backtest has been run. No results exist. No figures are asserted. This is a pre-registered methodology — to be executed as a later ticket when data is available.

Thesis under test

Buying residential property in markets adjacent to bases with a high BAH-to-price ratio outperforms a baseline, on a risk-adjusted basis, over multi-year holds.

Hypotheses (pre-registered)

  • H1: Top-quartile-by-bah_yield base markets (at time t) beat an equal-weight all-base portfolio over horizon h.
  • H0: No outperformance after controlling for region and national housing cycle.
  • Falsification (committed up front): if H1 does not beat all three baselines net of region/cycle controls across a majority of rolling windows → thesis rejected. No goalpost moving after seeing data.

Design

  • Signal at t: bah_yield = BAH_E5dep_t × 12 / median_home_value_t — rank, take top quartile.
  • Annual rebalanced cohorts; horizons: 1, 3, 5-year rolling holds.
  • Return proxy: FHFA HPI appreciation + min(BAH, market_rent) income; opex_ratio [ASSUMPTION] swept (0.35–0.50), never a single constant.

Baselines (must beat all three)

  1. All-base-markets equal weight (isolates selection)
  2. National housing (FHFA HPI / Case-Shiller — isolates cycle)
  3. Random base-market bootstrap draws (isolates luck)

Key confounders

ConfounderControl
National rate / housing cycleCycle-relative returns; baseline 2
Sunbelt / region clusteringRegion fixed effects / within-region ranking
Survivorship (BRAC closures)Include closed bases as realized loss — never drop
Look-ahead biasUse as-released data vintages; flag if unavailable
Rolling-window overlapReport non-overlapping + Newey-West; disclose
Rent ≠ BAHUse min(BAH, market_rent); report both variants
Source: projects/milbase/GOV-GENERALIZATION.md Pink branch · shipped 2026-05-16 · commit 9ee21e4

Does the Thesis Generalize to All Government Buildings?

Tested honestly — not force-fit. Research only; no fabrication. Verdict is allowed to be — and largely is — "distraction."

The military edge requires both:

  • (A) Published, location-indexed, guaranteed housing floor — BAH is a per-paygrade cash housing allowance, set by MHA, federally backed. Rare and differentiating.
  • (B) Concentrated, stable, relocation-driven tenant demand — thousands on-station, PCS-cycle turnover, single dominant employer.

B-only (generic stable employer) is a commodity signal with no edge. A is the rare one.

Class-by-class test

Gov class(A) housing floor?(B) concentration?Verdict
Federal civilian / locality payNo — salary adj, not housing-earmarkedWeak (dispersed)Breaks on A
GSA-leased / federal officesNo (office ≠ residential)Building-level onlyBreaks — wrong asset class
VA hospitalsNo housing paymentStable employer, moderateBreaks on A
Agency / lab towns (national labs)No BAH analogStrong single-employerB-only — commodity, no edge

Honest finding

The strongest civilian analog of the BAH mechanic is not a government building class — it is the HUD Housing Choice Voucher / Fair Market Rent system: a published, location-indexed, government-backed rent payment to landlords. Structurally closest to BAH. Already in scope via AREA-ECON.md.

Recommendation

Do not open a "government buildings" product line. The defensible expansion is the HUD voucher/FMR family (already underway), optionally annotated with OPM FedScope single-employer concentration as a secondary stability factor — not a standalone product. This was worth testing precisely so it can now be deliberately set aside.

Source: projects/milbase/PERSONNEL-MODEL.md Pink branch · shipped 2026-05-16 · commit 4d92a95

Personnel-by-Paygrade Estimation Model

"Modeled estimate" label is mandatory downstream. This model re-allocates a real, sourced total — it never invents one. NULL troop_count → no estimate, never imputed.

Formula

est_personnel[base, paygrade] = round( T_base × R_branch[paygrade] ) where: T = installations.troop_count (real, sourced — NULL ⇒ no estimate) R_branch = rank/paygrade distribution vector (E1–E9 / W1–W5 / O1–O10) source: DoD "Population Representation in the Military Services" + DoD/DMDC Active Duty demographics (annual, public) Σ_paygrade est_personnel[base] = T_base (vector must sum to the real total)

Confidence bands

BandCondition
Moderatetroop_count sourced AND branch has a published rank distribution AND base_type matches distribution assumption
LowSourced total but only a service-wide (not base-type) distribution
Nonetroop_count NULL → no estimate emitted

Presentation rule: always rendered as "≈ modeled estimate (method: troop_count × DoD rank distribution; not measured)" with source + confidence band inline. Feeds SCORING only as a modeled feature, weighted below measured fields.

DB grounded (as of 2026-05-16): 84/459 installations have sourced troop_count; 375 NULL = free-data ceiling (DoD doesn't publish clean per-installation counts). See Methodology page for full ceiling detail.

Source: projects/milbase/DEPLOYMENT-MODEL.md Pink branch · shipped 2026-05-16 · commit 4d92a95

Deployment-Tempo Estimation Model

"Modeled / historical-average" label is mandatory downstream. Deployment tempo is volatile (conflict-driven) — source period must be stated; this is not a forecast.

Why it matters: time-deployed proxies tenant turnover/absence near a base → feeds RISK (area trajectory/stability) and the rent-floor durability argument in OPPORTUNITY and underwriting.

Formula

est_deploy_fraction[base] = weighted_avg over tenant unit types of OPTEMPO_b (dwell:deploy ratio → fraction-of-time-deployed) est_years_deployed[base, career_len] = est_deploy_fraction × career_len career_len = [ASSUMPTION] band (4 / 8 / 20 yr) — reported as range, never a single value OPTEMPO_b = GAO / CRS deployment reports by branch/unit type (public)

Confidence bands

BandCondition
ModerateKnown dominant unit type + current GAO/CRS OPTEMPO figure for it
LowBranch-level OPTEMPO only (no unit detail)
NoneBranch unknown → no estimate

Sources: GAO reports on deployment/dwell time · CRS reports on military OPTEMPO/end-strength · DoD posture statements (all public). Implementation = later yellow/green ticket with mandatory "modeled / historical-average" label.

Source: projects/milbase/AREA-SENTIMENT.md Pink branch · shipped 2026-05-16 · commit 4d92a95

Base-Town Area Sentiment: Methodology

HARD GATE: executing a broad multi-site sentiment scrape requires explicit human "go" (mass-scrape gate). This document delivers the method + source design only — not an executed scrape. No fabricated sentiment, no invented scores.

What we're measuring

Public perception of the town/area a base sits in (not the military) — livability, housing, safety, schools, economy — as a risk/quality modifier feeding RISK (trajectory) and SCORING (Stability).

Signal design

area_sentiment[base] = blend( text_polarity (labeled subjective; per-source sampled, scored, aggregated; disclose sample size + date), factual_anchor (Census/BLS/FBI normalized z within peer set) ) → 3-tier label: Positive / Mixed / Negative + confidence + n + sources

Rule: every sentiment claim is anchored to a quantitative public stat where one exists. Public sources only (Census ACS/PEP, BLS LAUS, FBI UCR, public local news, public forums — ToS-respecting); no auth-walled or private data.

Source classes

ClassExamplesCaveat
Local newsRegional outlets, base-town papersEditorial bias
ForumsPublic Reddit (city/military subs)Self-selection
ReviewsPublic neighborhood/area reviewsReview-bombing risk
Gov/quant anchorsCensus, BLS, FBI UCRGround sentiment in fact — primary weight

Follow-on: P/Y-MILBASE.sentiment-pull — execute the bounded public pull under explicit human "go", rate-limited, ToS-respecting, sources logged. Feeds RISK §3 trajectory + SCORING Stability once a real pull exists.

Source: projects/milbase/NEIGHBOR-ECON.md Pink branch · shipped 2026-05-16 · commit 58c2605

Neighboring-Area Economics

Extends AREA-ECON.md from the base ZIP to the feeder area — the adjacent ZIPs/towns that actually house service members. Underwriting on the base ZIP alone is biased; members spread across a commuting radius.

Feeder set definition (locked)

For each base: feeder_set = {feeder_zip} ∪ {ZIPs in feeder_county} ∪ {ZIPs adjacent to feeder_zip}. Adjacency via Census ZCTA boundaries (free, public domain). DB hooks: installations.feeder_city, feeder_county, feeder_zip.

Blended price-to-rent (the deliverable signal)

blended_rent[base] = ACS-renter-household-weighted mean of feeder-set rents blended_value[base] = same weighting over feeder-set home values blended_p2r[base] = blended_value / (blended_rent × 12) Weight = ACS B25003_003E renter-occupied count per ZIP (real, sourced) Equal-weight fallback if weights unavailable — flagged Low confidence Any ZIP with no data: excluded + disclosed, never imputed

The delta between blended_p2r and base-ZIP-only p2r is the output of value — it shows how much the feeder-area picture differs from the centroid.

Output spec

Specs a neighbor_econ(base_id, blended_rent, blended_value, blended_p2r, coverage_pct, source, year) view — yellow writes; pink specifies. Feeds SCORING Yield (replaces base-ZIP p2r with blended) and G-ratio-rank.

Source: projects/milbase/SIGNAL-APIS.md Pink branch · shipped 2026-05-17 · commit 37c7ef9

Free Signal APIs & Datasets

Reference table of all free (no/low-key) APIs usable to estimate real estate, market/equity, and demand signals. Verification status labeled per row — no sample values invented.

Legend: V✓ first-hand verified · V-key free key required (keyless rejected) · V✗env keyless but this env's fetch tool was blocked · K stable public knowledge

Real estate

SourceKey?SignalJoin keyVerif
HUD FMRBearer, free regMarket rent (BAH-comparable)County FIPS / CBSAV-key
Census ACSFree keyMedian rent / home valueState + county / ZCTAV-key
Zillow ZORI/ZHVI CSVsNoneRent / value momentumZIP / metroK (commercial-use flag)
FHFA HPINonePrice index / cycleMSA / ZIP / stateK (public domain)
Redfin Data CenterNoneSale/list, DOMMetro / countyK (attribution; non-commercial)

Market / equity

SourceKey?SignalVerif
Yahoo Finance chartNone (unofficial)Price / returnsK
Stooq CSVNoneDaily OHLCVV✗env (normal client works)
FREDFree key requiredRates / macro seriesK (commonly misremembered as keyless)
SEC EDGARNone + declared User-AgentFilings / fundamentalsV✗env (403 without real UA)

Demand / personnel

SourceKey?SignalVerif
BLS LAUSOptional (higher quota)Local jobs / unemploymentK
Census Building Permits SurveyNoneHousing supply pressureK
DoD/DMDC PopRepNoneRank distribution, end-strengthK

Recommended stack

  • RE: FHFA + Zillow CSV (keyless) for momentum; HUD FMR + Census ACS (key) for levels — system of record.
  • Market: Stooq/Yahoo for prices (keyless, direct client); SEC EDGAR (keyless + UA) for fundamentals; FRED (key) for macro.
  • Demand: BLS (optional key) + Census BPS + DoD/DMDC.
Source: projects/milbase/BASE-AGE.md Pink branch · shipped 2026-05-17 · commit 830411d

Base Founding Year: Sourcing Spec

Defines the sourcing methodology and discipline for installations.established_year + established_src. Bulk per-base population is a yellow data ticket — pink specifies, yellow writes. No fabricated years.

Source hierarchy (per base, highest-trust first)

  1. Official .mil base fact sheet / installation history page — primary
  2. DoD / service historical office publications
  3. Wikipedia infobox "Built/In use" — only with its own cited reference; record the underlying source, not "Wikipedia" alone
  4. Reputable historical references (service museums/registries)

Hard rules

  • No fabrication, no estimation. No credible source → established_year = NULL, established_src = NULL. Partial real > fake.
  • Definition: established_year = year the installation began military operation. Renames do not reset the year (e.g., Fort Liberty was formerly Fort Bragg — the clock starts at Bragg's founding).
  • Joint bases: use the earliest constituent installation's operation year; note the merger year in source string.
  • Conflicting sources: take the official .mil value; flag established_src with "(conflicting sources; .mil used)".

Display: years_around = current_year − established_year (NULL if year NULL). Feeds the All-Bases scatter "years around" sortable axis; NULLs sort last.

Source: projects/milbase/RE-DATA-SPEC.md Pink branch · shipped 2026-05-17 · commit ab41fdb

Rent / Price Engine: Exact Source + Method Spec

Pink writes the spec; yellow scrapes per it. Implementable with zero judgment calls. Real source per row or NULL — no fabrication.

Feeder-town set per base (deterministic)

feeder_places(base) = {installations.feeder_city} # real, in DB ∪ {incorporated places whose centroid ≤ 25 mi of (lat,lon)} # Census Gazetteer Cap at 8 nearest places (tie-break: ascending distance, then place FIPS). Haversine distance from installations.lat/lon to place centroid.

Metrics per place, per year 2013–2026

MetricPrimary sourceKeyFallback
Median home valueCensus ACS5 B25077_001EFree keyZillow ZHVI ZIP CSV
Median gross rentCensus ACS5 B25064_001EFree keyZillow ZORI ZIP CSV → HUD FMR fmr_2 (county)

Priority: ACS for level → Zillow for years ACS lacks → HUD FMR as county fallback. Stamp the actual source used per row. Years with no source → NULL row, not fabricated.

Target table (yellow writes)

area_econ(base_id, year, median_home, median_rent, price_to_rent, source, PRIMARY KEY(base_id, year)) price_to_rent = median_home / (median_rent * 12) -- NULL if either NULL Aggregation place→base: renter-household-weighted mean (ACS B25003_003E renter-occupied count as weight) Equal-weight fallback flagged in source field

Time alignment: 2013–2026 matches the BAH series span so price_to_rent is joinable to bah_rates.year for blended ETF/ratio-rank signals. Any base/year missing on either side → excluded from blended signal, disclosed, never guessed.

Ship report fields (yellow): # bases with ≥1 year, median coverage%, per-source row counts, NULL count, years covered, weight-source used.

Source: projects/milbase/DATASET-PRODUCT-SPEC.md Pink branch · shipped 2026-05-17

The product is the assembly + provenance discipline, not the raw facts. Public data, painfully aggregated, every row sourced or explicit NULL — sold as a clean, queryable, attributed dataset.

Three Export Tiers

TierContents
FreeInstallations (name, branch, type, state, lat/lon) + base count
Core (gated)+ BAH series, troop_count, MHA map — all with source
Pro+ Derived signals (rent/price-to-BAH, BAH-yield), score vector

Formats

  • Bulk: versioned CSV + SQLite snapshot + JSON (data.json contract, extended)
  • Manifest: row counts, coverage%, per-table as_of, source list, schema version
  • API (later ticket): read-only REST; every record carries its source or explicit null

Provenance Contract (the moat)

  • Every fact row: non-empty source OR explicit null + *_src=null
  • manifest.coverage_pct per table published with the data — buyers see exactly what's real
  • Versioned + changelog; never silently mutate a prior release

Licensing

  • Federal source data (HUD/Census/FHFA/DoD) = public domain → redistributable
  • Zillow/Redfin-derived signals = excluded from redistribution; Pro tier flags these fields as non-redistributable
  • LICENSE + SOURCES file enumerating every upstream + its terms ships with every export
Source: projects/milbase/UNDERWRITING-TOOL-SPEC.md Pink branch · shipped 2026-05-17

Near a base, BAH is a federally-set, published rent floor for a large tenant slice. Convert that into a one-screen underwriting view.

Input

  • Address or ZIP or base select
  • Resolves → MHA via ZIP→MHA crosswalk (dependency: backlog #1)
  • Paygrade + dependent-status selector (default E-5, w/dep — canonical)

Output (six blocks, one screen)

BlockContentSource
Demand anchorBAH (selected paygrade/dep, latest yr) + 5yr trendbah_rates
MarketMedian rent (2BR) + median home valuearea_econ
The spreadRent-to-BAH, BAH-implied gross yield, price-to-BAHderived
Base contextBranch · type · troop_count · closure tierinstallations + RISK
The catchClosure / hazard / trajectory risk flags + whyRISK tiers
VerdictScore vector (Yield/Stability/Risk) + coverage%SCORING

Hard Rules

  • Every number traces to a real source or shows "no data" — never a fabricated estimate
  • Sparse inputs → explicit NULL, not a guess; degrades to "data pending," not fake
  • Not advice. Disclaimer banner required on every render
  • Single global scale for any BAH visual (GLOBAL-SCALE INVARIANT)
Depends on ZIP→MHA crosswalk (backlog #1), area_econ data (Y-MILBASE.city-econ), and scoring-impl. Tool is specced; renders when dependencies land.
Source: projects/milbase/EQUITY-SCREEN-SPIKE.md Pink branch · shipped 2026-05-17 · feasibility spike

A time-boxed feasibility spike: can we map public companies/REITs to base-anchored, BAH-backed tenant demand using milbase.db + free SEC filing data?

What We Have (Free)

  • Base side: locations, troop_count, branch — solid, in milbase.db
  • Company side: SEC EDGAR full-text search + filings API (free) — 10-K/10-Q property schedules, but unstructured prose/exhibits

Binding Constraint

Mapping a public operator's properties to base proximity requires parsing property lists from filings. No free, structured, comprehensive property-by-issuer dataset exists.

Go / No-Go Criteria

  • GO if ~10-issuer manual probe shows property locations reliably extractable from EDGAR filings AND base-proximity produces a differentiated signal vs. a naive Sunbelt proxy
  • NO-GO if extraction is bespoke per issuer (no pattern) or signal collapses into "REITs in growth metros" (no military-specific alpha)
Pre-spike prior [JUDGMENT]: Likely NO-GO as a standalone product, conditional GO as a research note. Extraction cost is high; edge is thin vs. generic geographic exposure. A qualitative "which public names have notable base-market exposure" memo is a credible RE-fund work-sample artifact without a productized feed.

Hard rule: no company name, ticker, holding, or financial figure is asserted until pulled from a primary filing with citation. This tab asserts none — it is a feasibility frame, not findings.
Source: projects/milbase/TROOP-WEIGHTED-BAH.md Pink branch · shipped 2026-05-17

Raw per-MHA BAH growth treats a 500-troop post and a 50,000-troop installation equally. For a demand thesis, the question is how fast the BAH-backed tenant-dollar pool grows — which is troop-scaled.

Recommended Formula (troop-weighted BAH CAGR)

Per base b with MHA m, BAH = bah_rates.rate (E5, with_dependents=1): cagr_b = ( rate(m, year_max) / rate(m, year_min) )^(1/(year_max−year_min)) − 1 twb_area = Σ_b ( troop_count_b · cagr_b ) / Σ_b troop_count_b over bases b in the area WITH non-NULL troop_count AND a CAGR Unit: %/yr. Sane range: ~−0.05 … +0.12 (flag outside as data-quality, don't clamp)

Why It Matters

An area where the large bases' BAH is rising fast has a deepening guaranteed-rent pool — the core demand signal for scoring, not distorted by tiny posts.

NULL / Coverage Discipline

troop_count NULL on 375/459 (82%) of installations. Those bases are excluded from weighting; the area is flagged low-coverage. Weights renormalize over present-only. Never impute troop_count (HARD RULE). Areas below 50% troop coverage [ASSUMPTION] return the metric with a prominent "low troop coverage — directional only" label, or NULL.
  • troop_coverage% = (troop-present bases) / total, reported per area
  • Zero troop_count in area → metric = NULL + reason (no fabrication)
  • 84/459 current ceiling — dominant gap; troop enrichment is the follow-on ticket

Data & Coverage

Current live data as of 2026-05-17. All sourced or explicit NULL — no fabricated values.

BAH Rates

231,000+ rows · 2013–2026 (14 years) · 24 paygrades (E1–E9, W1–W5, O1E–O3E, O1–O7) · 402 MHAs · with and without dependents.

Source: military.com BAH rate tables (DoD mirror)

Installations

459 bases · 347 with coordinates (lat/lon) · 165 with area_econ (rent + home value) · 84 with troop count (2023 fact sheets).

Sources: Wikipedia CC-BY-SA / DoD Base Structure Report; OSM Nominatim (CC-ODbL)

Real Estate Data

48 bases with market rent + home value (Zillow ZORI/ZHVI). 164 bases have no feeder ZIP (remote/secure areas). Scoring runs on populated subset; coverage% always shown.

Source: Zillow Research free ZIP-level CSVs

Coverage gaps are features, not bugs. Any NULL field means "not yet sourced" — never "assumed zero" or "interpolated." Data expands as yellow lane ships geocode joins, BAH crosswalk coverage, and Census ACS pulls.
Disclaimer: MILBASE is a data aggregation and research tool. Nothing on this site constitutes investment advice, financial advice, or a solicitation. All data is sourced from public government and third-party sources; coverage is partial; BAH rates are policy-set and subject to change annually. Any investment decision requires independent due diligence. Past BAH trends are not a guarantee of future rates. The scoring model uses [ASSUMPTION]-tagged weights — tunable inputs, not validated outputs. The thesis is designed, not validated; no backtest results exist yet.
Methodology limits: Scores and derived ratios are a transparent, weighted model on partial public data. Weights are stated assumptions; coverage is shown per result. A score is not a prediction of returns. Bases with sparse data return "insufficient data," not a guessed score.
Data provenance: Every record carries its source or an explicit null. Federal-source data is public domain; third-party-derived fields are flagged and excluded from redistribution. Coverage percentages are published with each release.
No fabrication: This project never fabricates a rate, price, count, or coordinate. Partial real data is preferred over invented completeness. Unknown = null.
Forward-looking / closure risk: Base-closure, hazard, and trajectory indicators are reasoned judgments from cited public information, not probabilities or guarantees. Military realignment (BRAC) and local conditions can change materially.