Skip to main content

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()
  );
1

Select month & year

Choose a historical date from the available cache range
2

Query snapshot

Time Machine finds the Treasury data snapshot for that month
3

Run regime engine

Same evaluateRegime() function runs with historical inputs
4

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}`;
};
// 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;
};
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.

Adjacent Month Selection

lib/timeMachine/timeMachineSelection.ts
export const getAdjacentTimeMachineRequest = (
  selection: TimeMachineRequest,
  direction: "previous" | "next"
): TimeMachineRequest | null => {
  return getAdjacentTimeMachineEntry(selection.year, selection.month, direction);
};
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:
lib/signalOps.ts
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

Build docs developers (and LLMs) love