```ts
/**
 * Finds the cheapest combination of passes covering every trip day and reconstructs its purchases in increasing start-day order.
 */
export function cheapestPassPlan(tripDays: number[], passes: { span: number; cost: number }[]): { total: number; purchases: number[][] } {
  if (tripDays.length === 0) return { total: 0, purchases: [] };
  if (!Array.isArray(tripDays) || !Array.isArray(passes)) throw new Error("Invalid input types");
  if (tripDays.some(d => typeof d !== 'number' || d <= 0)) throw new Error("Trip days must be positive integers and strictly increasing");
  if (passes.length === 0) throw new Error("Pass list cannot be empty");
  if (passes.some(p => typeof p.span !== 'number' || p.span <= 0 || typeof p.cost !== 'number' || p.cost < 0)) {
    throw new Error("Invalid pass details: span must be a positive integer and cost must be a non-negative integer");
  }

  const n = tripDays.length;
  const dp = Array(n + 1).fill(Infinity);
  dp[0] = 0;

  for (let i = 1; i <= n; i++) {
    for (const pass of passes) {
      if (i - pass.span >= 0) {
        dp[i] = Math.min(dp[i], dp[i - pass.span] + pass.cost);
      }
    }
  }

  const purchases: number[][] = [];
  let remainingDays = tripDays.slice();
  let i = n;

  while (remainingDays.length > 0 && i > 0) {
    for (const pass of passes) {
      if (i - pass.span >= 0 && dp[i] === dp[i - pass.span] + pass.cost) {
        purchases.push([tripDays[i - pass.span], pass.span]);
        remainingDays = remainingDays.filter(d => d !== tripDays[i - pass.span]);
        i -= pass.span;
        break;
      }
    }
  }

  return { total: dp[n], purchases };
}
```