Overview
Time Machine enables point-in-time regime analysis using pre-cached Treasury snapshots. It lets you:
Historical Playback View regime assessments as they appeared in the past
Decision Testing Validate current strategies against prior climates
Regime Comparison Compare tightness and risk appetite across months
Trend Analysis Track regime transitions over 24+ months
Time Machine uses deterministic replay : the same inputs always produce the same regime classification, ensuring reproducibility.
How It Works
Time Machine queries a pre-fetched cache of Treasury snapshots stored locally:
lib/timeMachine/timeMachineCache.ts
const sortedSnapshots = parseTimeMachineCache ( rawCache )
. map (( snapshot ) => ({
... snapshot ,
isLive: false , // Mark as historical data
}))
. sort (
( a , b ) =>
new Date ( a . record_date ). getTime () - new Date ( b . record_date ). getTime ()
);
Select month & year
Choose a historical date from the available cache range
Query snapshot
Time Machine finds the Treasury data snapshot for that month
Run regime engine
Same evaluateRegime() function runs with historical inputs
Display assessment
UI shows regime, scores, and constraints as they were at that date
Time Machine snapshots are updated monthly. The cache covers 24+ months of historical data by default.
Finding Snapshots
Query by Date
lib/timeMachine/timeMachineCache.ts
export const findTimeMachineSnapshot = ( asOf : string ) : TreasuryData | null => {
const target = new Date ( asOf );
if ( Number . isNaN ( target . valueOf ())) {
return null ;
}
const targetTime = target . getTime ();
const index = findSnapshotIndexAtOrBefore ( targetTime );
const candidate = index === null ? null : sortedSnapshots [ index ];
if ( ! candidate ) {
return null ;
}
const { year : _year , month : _month , ... data } = candidate ;
return data ;
};
findTimeMachineSnapshot() uses binary search for O(log n) lookup performance—ideal for rapid historical queries.
Get Previous Snapshot
lib/timeMachine/timeMachineCache.ts
export const getPreviousTimeMachineSnapshot = ( asOf : string ) : TreasuryData | null => {
const target = new Date ( asOf );
if ( Number . isNaN ( target . valueOf ())) {
return null ;
}
const targetTime = target . getTime ();
const index = findSnapshotIndexAtOrBefore ( targetTime );
const candidateIndex =
index === null
? null
: snapshotTimestamps [ index ] < targetTime
? index
: index - 1 ;
const candidate =
candidateIndex === null || candidateIndex < 0
? null
: sortedSnapshots [ candidateIndex ];
if ( ! candidate ) {
return null ;
}
const { year : _year , month : _month , ... data } = candidate ;
return data ;
};
Month/Year Selector
Time Machine provides URL-driven navigation:
lib/timeMachine/timeMachineSelection.ts
export const parseTimeMachineRequest = ( searchParams ?: {
month? : string ;
year ?: string ;
}) : TimeMachineRequest | null => {
if ( ! searchParams ?. month || ! searchParams ?. year ) {
return null ;
}
const month = Number ( searchParams . month );
const year = Number ( searchParams . year );
if ( ! Number . isInteger ( month ) || ! Number . isInteger ( year )) {
return null ;
}
if ( month < 1 || month > 12 ) {
return null ;
}
if ( year < 2000 ) {
return null ;
}
return { month , year };
};
Building Time Machine URLs
lib/timeMachine/timeMachineSelection.ts
export const buildTimeMachineHref = (
href : string ,
selection ?: TimeMachineRequest | null
) => {
if ( ! selection ) {
return href ;
}
const [ baseHref , hash = "" ] = href . split ( "#" );
const [ pathname , queryString = "" ] = baseHref . split ( "?" );
const params = new URLSearchParams ( queryString );
params . set ( "month" , String ( selection . month ));
params . set ( "year" , String ( selection . year ));
const query = params . toString ();
const hashSuffix = hash ? `# ${ hash } ` : "" ;
return query ? ` ${ pathname } ? ${ query }${ hashSuffix } ` : ` ${ pathname }${ hashSuffix } ` ;
};
Example URLs
Usage in Components
// View December 2023 regime
"/regime?month=12&year=2023"
// View March 2022 regime
"/regime?month=3&year=2022"
// Return to live view (no params)
"/regime"
Regime Series Analysis
Get multi-month regime timelines:
lib/timeMachine/timeMachineCache.ts
export const getTimeMachineRegimeSeries = (
months = DEFAULT_REGIME_SERIES_MONTHS , // 24 months default
overrides ?: Partial < RegimeThresholds >
) : TimeMachineRegimeEntry [] => {
const cacheKey = buildRegimeSeriesCacheKey ( months , overrides );
const cached = timeMachineRegimeSeriesCache . get ( cacheKey );
if ( cached ) {
return cached ;
}
const sliceStart = Math . max ( sortedSnapshots . length - months , 0 );
const series = sortedSnapshots . slice ( sliceStart ). map (( snapshot ) => {
const assessment = evaluateRegime ( snapshot , overrides );
return {
year: snapshot . year ,
month: snapshot . month ,
recordDate: snapshot . record_date ,
regime: assessment . regime ,
summary: assessment . description ,
};
});
setRegimeSeriesCache ( cacheKey , series );
return series ;
};
[
{
year: 2022 ,
month: 1 ,
recordDate: "2022-01-31" ,
regime: "EXPANSION" ,
summary: "Capital is cheap and risk appetite is healthy. Move quickly to capture share."
},
{
year: 2022 ,
month: 2 ,
recordDate: "2022-02-28" ,
regime: "VOLATILE" ,
summary: "Capital is cheaper but risk appetite is weak. Build trust and resilience."
},
// ... 22 more months
]
Regime series results are cached for performance. Cache keys include threshold overrides to support custom configurations.
Rolling Yield Series
Visualize Treasury yield trends:
lib/timeMachine/timeMachineCache.ts
export const getTimeMachineRollingYieldSeries = (
months = DEFAULT_ROLLING_YIELD_MONTHS , // 12 months default
asOf ?: string
): {
oneMonth: SeriesHistoryPoint [];
threeMonth : SeriesHistoryPoint [];
twoYear : SeriesHistoryPoint [];
tenYear : SeriesHistoryPoint [];
} => {
const resolvedMonths = Math . max ( months , MIN_ROLLING_YIELD_MONTHS );
const asOfTime = asOf ? new Date ( asOf ). getTime () : Number . NaN ;
const asOfIndex =
asOf && Number . isFinite ( asOfTime )
? findSnapshotIndexAtOrBefore ( asOfTime )
: sortedSnapshots . length - 1 ;
const lastIndex =
typeof asOfIndex === "number" && asOfIndex >= 0
? asOfIndex
: sortedSnapshots . length - 1 ;
const sliceStart = Math . max ( lastIndex + 1 - resolvedMonths , 0 );
const rollingSnapshots = sortedSnapshots . slice ( sliceStart , lastIndex + 1 );
return {
oneMonth: rollingSnapshots . map (( snapshot ) => ({
date: snapshot . record_date ,
value: snapshot . yields . oneMonth ?? null ,
})),
threeMonth: rollingSnapshots . map (( snapshot ) => ({
date: snapshot . record_date ,
value: snapshot . yields . threeMonth ?? null ,
})),
twoYear: rollingSnapshots . map (( snapshot ) => ({
date: snapshot . record_date ,
value: snapshot . yields . twoYear ?? null ,
})),
tenYear: rollingSnapshots . map (( snapshot ) => ({
date: snapshot . record_date ,
value: snapshot . yields . tenYear ?? null ,
})),
};
};
Use rolling yield series to chart yield curve evolution over time—ideal for visualizing inversions and steepening trends.
Cache Coverage
Check available date range:
lib/timeMachine/timeMachineCache.ts
const timeMachineCoverage = (() => {
const earliest = sortedSnapshots [ 0 ];
const latest = sortedSnapshots . at ( - 1 );
return {
earliest: earliest ?. record_date ?? null ,
latest: latest ?. record_date ?? null ,
};
})();
export const getTimeMachineCoverage = () => {
return timeMachineCoverage ;
};
Get Coverage
Get Available Years
Get Months for Year
import { getTimeMachineCoverage } from "@/lib/timeMachine/timeMachineCache" ;
const coverage = getTimeMachineCoverage ();
console . log ( `Available data: ${ coverage . earliest } to ${ coverage . latest } ` );
// "Available data: 2022-01-31 to 2024-02-29"
Use Cases
1. Historical Decision Validation
Scenario : “Would our Q1 2023 hiring push have been safe in hindsight?“
import { findTimeMachineSnapshot } from "@/lib/timeMachine/timeMachineCache" ;
import { evaluateRegime } from "@/lib/regimeEngine" ;
import { evaluateDecision } from "@/lib/decisionShield" ;
const snapshot = findTimeMachineSnapshot ( "2023-03-31" );
if ( snapshot ) {
const assessment = evaluateRegime ( snapshot );
const decision = {
lifecycle: "GROWTH" ,
category: "HIRING" ,
action: "HIRE" ,
};
const verdict = evaluateDecision ( assessment , decision );
console . log ( `Q1 2023 verdict: ${ verdict . verdict } ` );
console . log ( `Regime: ${ assessment . regime } ` );
}
2. Regime Transition Tracking
Scenario : “When did we last shift from EXPANSION to DEFENSIVE?“
import { getTimeMachineRegimeSeries } from "@/lib/timeMachine/timeMachineCache" ;
const series = getTimeMachineRegimeSeries ( 24 );
let lastRegime = null ;
series . forEach (( entry ) => {
if ( lastRegime === "EXPANSION" && entry . regime === "DEFENSIVE" ) {
console . log ( `Transition on ${ entry . recordDate } ` );
}
lastRegime = entry . regime ;
});
3. Yield Curve Retrospective
Scenario : “Chart 10Y-2Y inversion duration in 2022”
import { getTimeMachineRollingYieldSeries } from "@/lib/timeMachine/timeMachineCache" ;
const yields = getTimeMachineRollingYieldSeries ( 12 , "2022-12-31" );
const slopes = yields . twoYear . map (( point , i ) => {
const tenYear = yields . tenYear [ i ]. value ;
const twoYear = point . value ;
return {
date: point . date ,
slope: tenYear !== null && twoYear !== null ? tenYear - twoYear : null ,
};
});
slopes . forEach (({ date , slope }) => {
if ( slope !== null && slope < 0 ) {
console . log ( ` ${ date } : inverted ( ${ slope . toFixed ( 2 ) } %)` );
}
});
Historical Mode Banner
Time Machine generates a visual indicator for historical views:
lib/timeMachine/timeMachine.ts
export const formatHistoricalBanner = ( year : number , month : number ) => {
const paddedMonth = String ( month ). padStart ( 2 , "0" );
return `Historical mode active · ${ year } - ${ paddedMonth } ` ;
};
Always display the historical banner when Time Machine is active. This prevents operators from mistaking stale data for current conditions.
Navigation Controls
Adjacent Month Selection
lib/timeMachine/timeMachineSelection.ts
export const getAdjacentTimeMachineRequest = (
selection : TimeMachineRequest ,
direction : "previous" | "next"
) : TimeMachineRequest | null => {
return getAdjacentTimeMachineEntry ( selection . year , selection . month , direction );
};
Previous Month
Next Month
Year Boundary
import { getAdjacentTimeMachineRequest } from "@/lib/timeMachine/timeMachineSelection" ;
const current = { month: 3 , year: 2023 };
const previous = getAdjacentTimeMachineRequest ( current , "previous" );
// { month: 2, year: 2023 }
Signal Ops Integration
Time Machine deep links appear in regime change alerts:
export type SignalAlertPayload = {
previousRecordDate : string ;
currentRecordDate : string ;
previousAssessment : RegimeAssessment ;
currentAssessment : RegimeAssessment ;
reasons : RegimeChangeReason [];
sourceUrls : string [];
timeMachineHref : string ; // Deep link to historical comparison
};
When Signal Ops fires a regime change alert, the timeMachineHref field links directly to the Time Machine view for that date—enabling instant historical context.
Regime Engine Understand regime classification logic
Decision Shield Test decisions against historical regimes
Signal Ops Get Time Machine links in regime alerts
Briefing Pack Export historical regime comparisons