Lab

Things to use, not just read. Each panel is live: move the inputs and the answer changes in front of you. The math runs in your browser, with no network calls.

Personal project · active development

Tour Engine, running on this site

A guided tour engine for web apps: a spotlight, a ghost cursor and a card that walk a person through a task on their own page, one step at a time. One script, no build step, no dependencies.

Seven steps across five pages. Press Escape at any point to leave.

Injected defects caught
111 of 111
Checks across the engine's own suites
140

The host adapter. The engine knows nothing about the page it runs on: a host adapter describes the page through one object, with its steps, when it is ready, and how its tabs open. That is how the same engine ports across apps, and on this site each page is a tab, which is how the tour crosses page loads.

The mutation run. 111 of 111 injected defects caught across 143 checks, from the engine's own record, CSP and host suites, run against engine commit 7eefca5 on September 27, 2026. Each defect had to be caught by the check written for it.

The recorder. The engine can also record a tour while someone does the task once, with a privacy screen on what it keeps. It is switched off in this build.

Source is private for now. Happy to walk through it in a call.

Personal project · FP&A forecasting on public data

Construction Forecast

A backtested 12-month forecast of U.S. construction spending, with a scenario model for a fictional contractor that shows how weather, tariffs, rates, public funding and fuel move its plan.

Real forecast U.S. private nonresidential construction spending (PNRESCON), forecast with Holt-Winters damped. Fictional company Prairie Ridge Builders (fictional): every company figure is synthetic and not modeled on any real company.

Scenarios
Show
Bridge shows
Revenue
Gross profit
Gross margin
Change in revenue
Change in gross profit
Change in margin

Most sliders move the 12-month plan only a little because most of the year's revenue is backlog that is already signed, and a rate change reaches revenue only through new bookings months later. Funding timing moves revenue the most because a delayed bill cuts public bookings right away.

Monthly revenue, scenario against base plan
ScenarioBase planSpread of scenario outcomes, P10 to P90
Show the monthly numbers
MonthRevenueGross profitMarginSpread P10 to P90Base plan revenue
Variance bridge from the base plan to the scenario
AddsTakes awayBase plan and scenario
Show the bridge numbers
StepRevenueGross profitGross margin
Spread of revenue outcomes
Work deferred past the view

This is scenario analysis, not a forecast. The presets and sliders adjust around the real macro forecast, they do not predict it. The spread comes from redrawing weather, prices, rates and the macro forecast's past misses 1,000 times: a spread of scenario outcomes, not a probability. Months 13 to 24 are a scenario extension, not a forecast. The macro forecast and its backtest cover 12 months. Beyond that, base bookings repeat the macro P50's 12-month seasonal shape with no further growth.

Download the Excel model Inputs, Drivers, Monthly Forecast and Bridge sheets, with live formulas and saved results, 55 KB.

How it works

What is real and what is fictional

Real: the macro forecast of U.S. private nonresidential construction spending, its backtest, the O'Hare weather history, and the price and rate series, all public data pulled without API keys on 2026-10-04. Fictional: Prairie Ridge Builders (fictional). Its backlog, bookings, margins and cost shares are synthetic, written for this demo, and every one is labeled in the engine's config as sourced or as an assumption.

The macro forecast and its backtest

The target is PNRESCON, in millions of dollars per month, not seasonally adjusted. Six models were tested with a rolling-origin backtest: 71 monthly forecast origins from Sep 2020 to Jul 2026, each forecasting 1 to 12 months ahead. The rule for picking the published model was fixed before any backtest ran: lowest average MAPE over 1 to 12 months. It was run twice: lag 0 treats a month as known when it ends, lag 1 treats it as known a month later, which is about when Census publishes it. The published forecast uses lag 1.

Backtest error by model
ModelAvg MAPE, lag 012 months ahead, lag 0Avg MAPE, lag 112 months ahead, lag 1
Seasonal naive9.57%10.14%10.15%17.12%
Linear trend + seasonality14.26%16.68%14.82%19.00%
Holt-Winters6.19%10.17%6.91%11.14%
Holt-Winters damped5.96%9.34%6.65%10.41%
YoY momentum7.29%9.66%8.01%14.77%
Drivers (lagged)7.10%10.23%7.83%13.31%

Holt-Winters damped wins under both. With lag 1 its average error is 34.5% lower than seasonal naive (6.65% against 10.15%). The lagged drivers (employment, job openings, rates, metals, lumber and diesel) scored 7.83%: they did not beat the simpler model, which is why the contractor layer is presented as scenarios and not as a forecast.

U.S. private nonresidential construction spending, actual and forecastMonthly spending, not seasonally adjusted, in millions of dollars. Actual data from Sep 2023 to Aug 2026, ending at 66,591. Published forecast from Oct 2026 to Sep 2027: 68,158 in the first month and 66,941 in the last, with a P10 to P90 range of past misses from 62,106 to 84,066 in the last month. The numbers are in the table below.$50B$60B$70B$80B$90B2024202520262027
ActualForecastP10 to P90 range of past misses
Show the forecast numbers
MonthP10ForecastP90
Oct 202665,91268,15872,335
Nov 202663,91366,68072,229
Dec 202661,38764,63472,032
Jan 202756,25759,68967,573
Feb 202754,38858,07566,814
Mar 202756,11460,15870,527
Apr 202757,73361,77473,378
May 202759,12563,40475,246
Jun 202761,40865,53578,088
Jul 202761,14065,66880,150
Aug 202762,40266,62982,491
Sep 202762,10666,94184,066

The P10 to P90 band is read off the published model's backtest errors. It was also checked out of sample: rebuilt from earlier folds only, then tested on origins from Sep 2023 on. A calibrated band would hold about 80%. It holds far less beyond the first few months, because spending surged in 2022 and 2023 and then stalled, and errors from the boom said little about the slowdown. Read it as the range of past misses, not an 80% probability.

Out of sample coverage of the P10 to P90 band
Months aheadInside the band, lag 0Inside the band, lag 1
183% (29 of 35)69% (24 of 35)
271% (24 of 34)62% (21 of 34)
361% (20 of 33)58% (19 of 33)
456% (18 of 32)59% (19 of 32)
558% (18 of 31)55% (17 of 31)
653% (16 of 30)57% (17 of 30)
755% (16 of 29)52% (15 of 29)
857% (16 of 28)7% (2 of 28)
94% (1 of 27)0% (0 of 27)
100% (0 of 26)0% (0 of 26)
110% (0 of 25)0% (0 of 25)
120% (0 of 24)0% (0 of 24)
Data sources

All public, no API keys: FRED's CSV download and NOAA NCEI's data service. Every series ID was found by searching the FRED website, and the engine re-runs those searches to confirm them.

FRED series used
Series IDTitleUsed asDataPulled
PNRESCONTotal Private Construction Spending: Nonresidential in the United StatesForecast target1993-01 to 2026-082026-10-04
PNRESCONSTotal Private Construction Spending: Nonresidential in the United StatesPulled for reference, not used in the model1993-01 to 2026-082026-10-04
WPUIP231200Producer Price Index by Commodity: Inputs to Industries: Net Inputs to New Nonresidential Construction, Excluding Capital Investment, Labor, and ImportsTariff pass-through estimate2014-12 to 2026-082026-10-04
WPU1017Producer Price Index by Commodity: Metals and Metal Products: Steel Mill ProductsDriver tested in the backtest, tariff pass-through estimate1939-01 to 2026-082026-10-04
WPU102501Producer Price Index by Commodity: Metals and Metal Products: Aluminum Mill ShapesDriver tested in the backtest, tariff pass-through estimate1947-01 to 2026-082026-10-04
WPU102502Producer Price Index by Commodity: Metals and Metal Products: Copper and Brass Mill ShapesDriver tested in the backtest, tariff pass-through estimate1953-12 to 2026-082026-10-04
WPU081Producer Price Index by Commodity: Lumber and Wood Products: LumberDriver tested in the backtest, tariff pass-through estimate1926-01 to 2026-082026-10-04
APU000074717Average Price: Automotive Diesel Fuel (Cost per Gallon/3.785 Liters) in U.S. City AverageDriver tested in the backtest, tariff pass-through estimate, fuel scenarios1998-01 to 2026-082026-10-04
FEDFUNDSFederal Funds Effective RateDriver tested in the backtest, rate path1954-07 to 2026-092026-10-04
GS10Market Yield on U.S. Treasury Securities at 10-Year Constant Maturity, Quoted on an Investment BasisDriver tested in the backtest1953-04 to 2026-092026-10-04
USCONSAll Employees, ConstructionDriver tested in the backtest1939-01 to 2026-092026-10-04
JTS2300JOLJob Openings: ConstructionDriver tested in the backtest2000-12 to 2026-082026-10-04
SUBLPDRCSCNet Percentage of Domestic Banks Tightening Standards for Commercial Real Estate Loans With Construction and Land Development PurposesPulled, not used. Quarterly, starting October 2013. Too short, and a different frequency.2013-10 to 2026-072026-10-04
PBHWYCONSTotal Public Construction Spending: Highway and Street in the United StatesPulled for reference, not used in the model2002-01 to 2026-082026-10-04
FEDTARMDFOMC Summary of Economic Projections for the Fed Funds Rate, MedianRate path2026-01 to 2029-012026-10-04
RSAFSNAAdvance Retail Sales: Retail Trade and Food ServicesSample dataset1992-01 to 2026-082026-10-04
IPG2211A2NIndustrial Production: Utilities: Electric and Gas Utilities (NAICS = 2211,2)Sample dataset1939-01 to 2026-082026-10-04

Weather: NOAA station USW00094846, CHICAGO OHARE INTERNATIONAL AIRPORT, IL US, 25,109 daily records from Jan 1958 to Sep 2026, pulled 2026-10-04. Architecture Billings Index: not included, because AIA does not publish it on FRED and no file was supplied at construction/manual/abi.csv.

Weather thresholds and productivity
Adverse workday rules
A weekday is flagged whenSource
Above 0.1 in of precipitationTennessee Board of Regents, Section 01 26 20 Weather Delays: “precipitation (rain, snow, or ice) in excess of one-tenth inch (0.10") liquid measure”
At or above 95°F max temperatureCal/OSHA, 8 CCR 3395(e) high-heat procedures (a California rule, used as a reference point): “The employer shall implement high-heat procedures when the temperature equals or exceeds 95 degrees Fahrenheit.”
Below 20°F min temperatureBrick Industry Association Technical Note 1, cold weather masonry: “if the ambient temperature falls below 20 °F (-6.7 °C), then a heated enclosure must be provided for masonry under construction.”
Above 1 in of snow on the groundTennessee Board of Regents, Section 01 26 20 Weather Delays: “standing snow in excess of one inch (1.00")”
Above 25 mph fastest 2-minute windTennessee Board of Regents, Section 01 26 20 Weather Delays. WSF2 is NOAA's fastest 2-minute wind, the closest daily element to a sustained wind.: “sustained wind in excess of twenty-five (25) m.p.h.”

A flagged weekday is a partly productive day, not a lost day. Each rule has a light and a severe tier, and a day takes the lowest factor among the rules it trips. Climatology covers 1996 to 2026, because 2-minute wind records start in 1996. Work not done slips to later months, so a harsh winter moves revenue later rather than erasing it.

Productivity on a flagged day
ConditionShare of a normal day doneBasis
Above 0.1 in of precipitation80%assumption, inside the "up to 40%" loss Schuldt et al. report for light rain
At or above 0.5 in of precipitation50%assumption
At or above 95°F max temperature87%sourced, NECA table midway between 90F (93) and 100F (80)
At or above 100°F max temperature69%sourced, NECA table midway between 100F (80) and 110F (57)
Below 20°F min temperature90%sourced, NECA table midway between 10F (87) and 20F (94)
Below 0°F min temperature68%sourced, NECA table midway between -10F (60) and 0F (76)
Above 1 in of snow on the ground85%assumption
Above 6 in of snow on the ground65%partly sourced, Schuldt et al. report a 35% loss for heavy snowfall, not snow depth
Above 25 mph fastest 2-minute wind75%assumption
Above 40 mph fastest 2-minute wind50%assumption
Scenario assumptions

Tariffs, named by mechanism only. Each episode's size is the change in metal prices over its window, pushed through pass-through coefficients estimated from 2015-01 to 2026-08 monthly data (R squared 0.6493). Raised is 1 times the episode, reduced gives back half (an assumption), held is zero.

  • 2025 to 2026 episode (default). Jan 2025 to Aug 2026. Log change WPU1017 +37.7%, WPU102501 +40.7%, WPU102502 +23.0%. Through the pass-through coefficients that is 4.56% on the construction input PPI. From the last month before the first 2025 metals action to the latest month in the snapshot. It reflects current tariff levels, so it is the default. Over a 19-month window the price change also includes global price and demand moves, so treat it as the larger estimate. Federal Register actions in the window: Proclamations 10895 and 10896, aluminum and steel, Federal Register 2025-02-18, Proclamation 10947, aluminum and steel, Federal Register 2025-06-09, Proclamation 10962, copper, Federal Register 2025-08-05, Proclamations 11021, 11032 and 11045, aluminum, steel and copper, Federal Register 2026-04-09 to 2026-07-23.
  • 2018 episode. Feb 2018 to Aug 2018. Log change WPU1017 +15.0%, WPU102501 +6.3%. Through the pass-through coefficients that is 0.91% on the construction input PPI. Six months around the 2018 steel and aluminum tariffs. Copper is left out because it was not covered and fell over the window.

Rates. History cannot separate how rates affect construction from how the Fed responds to booms: every regression the engine ran says higher rates go with more construction growth later (+0.021 to +0.049 per 100 bp). So the scenario uses a labeled assumption: bookings fall 5% per +100 bp, after 6 months. The size comes from Bloesch and Weber, "Structural Changes in Investment and the Waning Power of Monetary Policy", Federal Reserve Bank of New York Staff Reports no. 1190, March 2026. The 5% is the peak response of nonresidential structures SPENDING to a 100 bp CUT. Applying it to bookings, and to a rise, assumes the effect is symmetric. That is an assumption. In that paper the spending response peaks about 10 quarters after the shock. Bookings lead spending, so the 6-month lag on bookings is an assumption. The estimate uses 1969 to 1996 data, and Chicago Fed Letter 482 (2023) reports a positive response of structures to higher rates, which it calls puzzling. The sign is not settled. The base path follows the Fed's September 2026 projections, from 3.75% in Sep 2026 to 4.1% at the end of 2026, 4.1% at the end of 2027, 3.9% at the end of 2028, 3.6% at the end of 2029.

Public funding. A delayed surface transportation bill holds back 60% of public bookings for 6 months. An assumption.

Fuel. Diesel moves to the 10th or 90th percentile of its historical 12-month change (-23.7% or +30.4% in log terms) over the first year. Escalation clauses here cover materials, not fuel.

The company. Materials are 40% of cost, escalation clauses pass 80% of a materials cost change to the owner, 50% of work is weather-exposed, and new bookings start 2 months after signing and run 12 months. Base bookings are trailing bookings scaled by the macro forecast's growth. The synthetic backlog:

Synthetic backlog
Project (synthetic)SectorContractValueCompleteMargin
Medical office buildingPrivateFixed price$38.0M55%10.0%
Distribution warehousePrivateEscalation clause$52.0M30%8.0%
Suburban office renovationPrivateFixed price$14.5M70%12.0%
Cold storage facilityPrivateEscalation clause$41.0M10%8.5%
Retail center shellPrivateFixed price$22.0M40%9.5%
Laboratory fit-outPrivateFixed price$18.5M0%11.0%
Hotel additionPrivateEscalation clause$33.0M0%9.0%
Municipal public works garagePublicFixed price$16.0M25%7.0%
School district additionPublicEscalation clause$27.0M15%7.5%
Transit maintenance facilityPublicFixed price$29.0M0%7.0%

Numbers from the forecasting engine at commit ff920cb (2026-10-05), data snapshot 2026-10-04. Source is private for now. Happy to walk through it in a call.

Personal project · Post-Quantum Readiness Toolkit

Which finance records are already exposed?

Harvest now, decrypt later: an adversary can record encrypted traffic today and read it once a quantum computer can break RSA and elliptic-curve keys, so any record that must stay secret past that day is at risk now. Mosca's inequality turns that into arithmetic. If the years a record must stay secret (x) plus the years a migration takes (y) exceed the years until a cryptographically relevant quantum computer (z), the record is exposed.

Scenarios the toolkit reports

Exposure of each finance record type under the current inputs
Record typeSecret for (x)Source ruleStatusMarginTimeline

* marks an assumption, not a retention rule. Margin is how many years a record stays sensitive after the quantum computer arrives, or how many years it has to spare. Retention periods are a lower bound on how long data must stay secret, so these results understate exposure. Scenarios are planning windows, not predictions.

The full toolkit goes further than this calculator: it scans code for quantum-vulnerable encryption and produces a prioritized migration register, with evidence on every finding, plus a CycloneDX CBOM export.

Read the toolkit on GitHub

Self-directed · learning in public on a simulator

Quantum finance, honestly

Qiskit programs run on a local simulator, each compared against the classical method an analyst would use today. This is study, not production quantum work, and the losses stay in.

Grover search, step by step

16 states, one marked. The oracle flips the marked state's sign, then diffusion reflects every amplitude about the mean. Step through it and watch the marked amplitude grow. This is the real algorithm on a 16-number state vector, computed in your browser.

Iterations
0
Marked state probability
Theory, sin²((2k+1)θ)

The optimum for 16 states is iterations, a chance of the marked state. The repo's grover_search.py marks state 7 and runs isqrt(16) = 4 iterations, one past the optimum, so its 1,000 shots sample from a chance instead. The repo does not save its measured counts, so there is no recorded hit rate to quote. Step to 4 here to see the distribution those shots come from.

QAOA portfolio

Matched brute force

Pick exactly 7 of 15 stocks for low risk at a 8% return target. QAOA chose the same 7 stocks as an exhaustive classical search.

Brute force checked
32,768
QAOA measured
3,611
Circuit runs to tune angles
1,000
Expected return
8.26%
Risk, annual std dev
4.64%

At 15 stocks brute force still wins easily. The case for QAOA is at 100 or more stocks, where checking every portfolio becomes impossible.

Revenue forecaster

Honest loss: classical won

Forecast three months past 24 months of rising revenue (month 24: $136,700).

MonthLinear regression1-qubit VQR
Month 25$138,062$132,537
Month 26$140,273$132,949
Month 27$142,484$133,195

Linear regression extends the trend. A one-qubit, angle-encoded model interpolates inside the range it saw and cannot extrapolate a straight trend, so its forecast flattens. Kept on the site on purpose.

Monte Carlo risk: the quadratic speedup

The probability a small business runs low on cash during the year, estimated two ways. Classical error falls like 1/√N, amplitude estimation error like 1/M, so halving the error costs 4x the samples but only 2x the queries.

Estimation error against cost, classical Monte Carlo and quantum amplitude estimation, log-logClassical Monte Carlo error falls from 0.0132 at 128 samples to 0.001 at 32,768 samples, about a slope of minus one half. Quantum amplitude estimation error falls from 0.0122 at 100 queries to 0.0002 at 26,200 queries, closer to a slope of minus one. The full numbers are in the table below the chart.1001,00010,0000.00010.0010.01Samples or oracle queriesError
Classical Monte CarloQuantum amplitude estimationReference slopes

To reach 0.5% error: 1,024 classical samples, 900 quantum oracle queries. The reference probability is 0.0522, from 200,000 classical simulations.

The honest caveat: the quantum side uses a one-qubit oracle calibrated to the same probability, because loading the full cash-flow model into a circuit is the hard, open part. On a laptop simulator, classical still finishes first in wall-clock time. The advantage shown is in query counts.

Show the numbers
SamplesClassical errorQueriesQuantum error
1280.01321000.0122
2560.00934000.0086
5120.00689000.0025
1,0240.00251,8000.001
2,0480.00323,5000.0007
4,0960.00236,8000.0006
8,1920.001413,3000.0002
16,3840.001426,2000.0002
32,7680.001

Numbers are the printed output of the repo's own seeded scripts, run as committed at 4fd2323 (Python 3.10.11, Qiskit 2.4.1). The repo commits its charts, not its numbers.

Read the code on GitHub

More experiments

Moved here from the Work ledger. Framed as exploration, not shipped work.

ExperimentWhat it isStackLinks
FP&A AI DashboardPrototype Automated variance analysis, rolling three to six month forecasts, and AI-drafted executive briefs on a sample dataset. Python · Pandas · Power BI
Snowflake + Power BI Sales AnalyticsLive · analytics End-to-end pipeline: ETL into a star-schema warehouse and interactive dashboards with KPI drilldowns. Snowflake · SQL · ETL · Power BI · DAX
Prompting Copilot for Accounting WorkGuide A prompting guide for accounting teams: which reconciliation steps belong to deterministic tools (XLOOKUP, Power Query) and which to AI-assisted exception handling, with a prompt library and a one-page guardrail card. Microsoft 365 Copilot · Excel · Power Query