```ts
/**
 * Writes the senary tail for a given numerator and denominator.
 * @param numerator - The upper reading of the Loomis gauge.
 * @param denominator - The lower reading of the Loomis gauge.
 * @returns The spelled out run of marks as per the Loomis gauge rules.
 */
export function writeSenaryTail(numerator: number, denominator: number): string {
  if (!Number.isInteger(numerator)) {
    throw new Error("Numerator must be a whole number.");
  }
  if (denominator < 1 || denominator > 10000) {
    throw new Error("Denominator must be between 1 and 10000.");
  }
  if (numerator < 0) {
    throw new Error("Numerator cannot be below zero.");
  }
  if (numerator >= denominator) {
    throw new Error("Numerator must be smaller than the denominator.");
  }

  const marks = "012345";
  let result = "";
  let seenRemainders: number[] = [];

  while (numerator > 0) {
    const remainder = numerator % denominator;
    if (seenRemainders.includes(remainder)) {
      const start = seenRemainders.indexOf(remainder);
      return result.slice(start) + "|" + result.slice(start, -1) + "|";
    }
    seenRemainders.push(remainder);
    result += marks[Math.floor((numerator % (denominator * 6)) / denominator)];
    numerator = remainder;
  }

  return result || "0";
}
```