```ts
export function carveSet(steps: Array<[string, number, number]>): number[][] {
    const resultSet = new Set<number>();

    for (const [verb, lo, hi] of steps) {
        if (verb !== "add" && verb !== "cut") {
            throw new Error("Invalid verb");
        }
        if (!Number.isInteger(lo) || !Number.isInteger(hi)) {
            throw new Error("Bounds must be integers");
        }
        if (lo >= hi) {
            throw new Error("lo must be strictly below hi");
        }

        for (let i = lo; i < hi; i++) {
            if (verb === "add") {
                resultSet.add(i);
            } else if (verb === "cut") {
                resultSet.delete(i);
            }
        }
    }

    const ranges: number[][] = [];
    let currentRange: [number, number] | null = null;

    for (const num of Array.from(resultSet).sort((a, b) => a - b)) {
        if (!currentRange) {
            currentRange = [num, num + 1];
        } else if (num === currentRange[1]) {
            currentRange[1]++;
        } else {
            ranges.push(currentRange);
            currentRange = [num, num + 1];
        }
    }

    if (currentRange) {
        ranges.push(currentRange);
    }

    return ranges;
}
```