Skip to main content

Semantic Time

Semantic time lets you define named time periods (“morning”, “lunch_rush”, “closing”) that map to concrete hours. The same name can mean different times on different days.

Why semantic time?

Businesses think in terms like “we need 3 servers during lunch rush” — not “we need 3 servers from 11:00 to 14:00”. Semantic time bridges that gap:
  • Define periods once with human-readable names
  • Reference them in coverage requirements
  • Let the system resolve to concrete hours based on the day

Defining semantic times

Use defineSemanticTimes to create a context with named periods:
import { defineSemanticTimes } from "dabke";

const times = defineSemanticTimes({
  morning: { startTime: { hours: 8 }, endTime: { hours: 12 } },
  lunch_rush: { startTime: { hours: 11 }, endTime: { hours: 14 } },
  afternoon: { startTime: { hours: 14 }, endTime: { hours: 18 } },
  closing: { startTime: { hours: 18 }, endTime: { hours: 22 } },
});

Variants by day

The same semantic time can have different hours depending on the day of week:
const times = defineSemanticTimes({
  business_hours: {
    default: { startTime: { hours: 9 }, endTime: { hours: 17 } },
    variants: [
      {
        daysOfWeek: ["saturday"],
        startTime: { hours: 10 },
        endTime: { hours: 15 },
      },
    ],
  },
});
On Saturday, “business_hours” means 10:00–15:00. Every other day, it means 9:00–17:00.

Creating coverage from semantic times

Use times.coverage() to define coverage in semantic terms, then times.resolve() to produce concrete coverage requirements:
// Define what you need
const coverage = times.coverage([
  { semanticTime: "morning", roleIds: ["server"], targetCount: 2 },
  { semanticTime: "lunch_rush", roleIds: ["server"], targetCount: 3 },
  { semanticTime: "closing", roleIds: ["server"], targetCount: 1 },
]);

// Resolve for specific dates
const concreteCoverage = times.resolve(coverage, ["2026-02-09", "2026-02-10", "2026-02-11"]);

// Pass to ModelBuilder
const builder = new ModelBuilder({
  // ...
  coverage: concreteCoverage,
});
The resolver expands semantic coverage into one concrete CoverageRequirement per day, applying any day-specific variants automatically.