The Scheduler Boundary — Architecture

The Scheduler Boundary — Architecture

This document explains why the scheduler boundary is shaped the way it is. The operational specification is CONTRACT.md; this is the reasoning beneath it.


1. The one idea

Forge HPC owns the domain. A scheduler merely provides observations about reality. The scheduler never defines the domain; the domain defines what a scheduler must produce.

Every other decision in this package follows from that inversion of the usual relationship. In most systems, the scheduler is the source of truth and the platform bends to its vocabulary — its state names, its field formats, its command output. The platform ends up speaking a particular scheduler’s dialect, and the second scheduler forces either a rewrite or a second dialect. Forge refuses this at the boundary: the domain vocabulary is fixed first (domain), and a scheduler earns the right to be observed only by producing that vocabulary. The direction of definition runs from Forge to the scheduler, never the reverse.

This is FORGE-001’s founding move — unify meaning, not systems — applied to schedulers: the twelve systems dissolve not because they were merged but because they are all made to speak one set of nouns.

2. Why the boundary is in the domain plane

The scheduler contract lives in Forge HPC (the domain plane), not in Forge Core and not in an instance. FORGE-101 Part 15 places it exactly here, and the placement is load-bearing:

So the abstraction over schedulers is itself the proof that the domain plane must exist: it is knowledge that is neither universal nor local, and it needs a home that is neither Core nor instance.

3. Why the contract returns domain objects exclusively

Every operation returns Forge HPC domain objects and nothing else. This is what makes the contract truthful and reusable:

If a scheduler reports something the domain cannot express, the honest responses are to map it to the nearest domain concept, to report unknown, or — for a genuinely universal new concept — to amend the domain. The forbidden response is to widen the contract with a scheduler-specific field.

4. Why adapters are separate

The contract knows nothing of SSH, REST, files, sockets, databases, or message queues. Those are how a particular source system is reached, and they live in adapters, behind a separate seam (adapters.py):

The split matters for three reasons:

  1. The contract stays pure. A SchedulerContract is a source-neutral view of reality; mixing transport into it would couple every consumer to a connection that can fail at read time, defeating the static, observe-only thesis.
  2. Adapter logic is domain; adapter binding is instance (FORGE-101 Part 8.4). The knowledge of what a source system’s record means is reusable across every deployment of that system and belongs to the domain; the endpoint and credential that reach this deployment’s copy belong to the instance. Declaring the translator interface here, and leaving both the concrete transport and the binding outside, is that split made structural.
  3. Reality is untrusted. An adapter is where reality’s messy edge meets the platform’s validated interior. SourceObservation records raw payloads with provenance and never edits them (evidence is not edited); the translator is the single checkpoint where raw becomes valid, and it fails loudly when it cannot — “beautifully provenanced garbage is still garbage.”

5. Why capabilities and negotiation, rather than one fat interface

Real schedulers differ in what they can observe: one exposes accounting, another does not; one supports incremental change streams, another only full snapshots. Two designs could absorb this — a fat interface where every scheduler implements every operation (returning empty for what it lacks), or a capability model where a scheduler declares what it offers. Forge chooses capabilities because:

6. Why compliance is mechanical

FORGE-103’s meta-standard is that a rule a machine can check must be checked by a machine. Whether an implementation honours the contract — declares what it implements, implements what it declares, reports a coherent version, builds a deterministic manifest — is entirely checkable statically, so verify_contract_compliance checks it, deterministically, without invoking a single observation. Review is thereby freed for what only humans can judge: is the mapping from a real source to domain objects honest.

7. Determinism, because everything downstream is a projection

The contract is designed so that equal reality produces equal output: manifests are deterministic, observation collections canonicalize their own ordering and reject duplicate identities, and negotiation is a pure function. This is not fastidiousness — it is what lets everything above the boundary be a pure, byte-reproducible projection (FORGE-100 Part 2.5). One home per object holds inside every observation, not only inside the truth store that will eventually keep it, because a duplicate admitted at the boundary is a duplicate the whole pipeline must then be trusted to remove.

8. What this boundary deliberately excludes