```ts
/** Tape-measure spans: parse to inches, format canonically, and add. */

const INCHES: Record<string, number> = { yd: 36, ft: 12, in: 1 };
const ORDER = ["yd", "ft", "in"];

function validateSpan(text: string): void {
  if (typeof text !== 'string' || !text.trim()) {
    throw new Error("Invalid span format");
  }
  const parts = text.split(/\s+/);
  const unitSet = new Set<string>();
  let valueFound = false;
  for (const part of parts) {
    const match = part.match(/^(\d+)([a-z]{2})$/);
    if (!match) {
      throw new Error("Invalid span format");
    }
    const [, value, unit] = match;
    if (unitSet.has(unit)) {
      throw new Error("Repeated units in span");
    }
    unitSet.add(unit);
    if (!ORDER.includes(unit)) {
      throw new Error("Unknown or out-of-order unit in span");
    }
    if (value !== '0' && value.startsWith('0')) {
      throw new Error("Value cannot have leading zeros");
    }
    valueFound = true;
  }
  if (!valueFound) {
    throw new Error("Span must contain a non-bare value");
  }
}

export function parseSpan(text: string): number {
  validateSpan(text);
  let total = 0;
  for (const part of text.split(/\s+/)) {
    const match = part.match(/^(\d+)([a-z]{2})$/);
    if (!match) {
      throw new Error("Invalid span format");
    }
    const [, value, unit] = match;
    total += Number(value) * INCHES[unit];
  }
  return total;
}

export function formatSpan(inches: number): string {
  if (typeof inches !== 'number' || !Number.isInteger(inches) || inches < 0) {
    throw new Error("inches must be a non-negative integer");
  }
  if (inches === 0) {
    return "0in";
  }
  const parts: string[] = [];
  const yards = Math.floor(inches / 36);
  const feet = Math.floor((inches % 36) / 12);
  const rest = inches % 12;
  if (yards > 0) {
    parts.push(`${yards}yd`);
  }
  if (feet > 0) {
    parts.push(`${feet}ft`);
  }
  if (rest > 0) {
    parts.push(`${rest}in`);
  }
  return parts.join(" ");
}

export function addSpans(first: string, second: string): string {
  const total = parseSpan(first) + parseSpan(second);
  return formatSpan(total);
}
```