gatelineAPI reference
interface EngineConfig {
    budgetEnforcement?: boolean;
    dispatcher: Dispatcher;
    engineId?: string;
    frameworkPrefix?: string;
    identity: Identity;
    localOnly?: boolean;
    log?: (line: string) => void;
    maxConcurrentDispatches?: number;
    now?: () => Date;
    push?: boolean;
    registry: null | Registry;
    repoDir: string;
    requireBudget?: boolean;
    roleTimeoutMs?: number;
    spendLimitUsd?: null | number;
    spendWindowMs?: number;
    staleMs?: number;
}

Properties

budgetEnforcement?: boolean

Master switch for budget enforcement (#109): false disables the DB, RB, and HB pauses (spendLimitUsd/requireBudget become no-ops) for operators whose harness bills flat-rate. Metering — the ledger, cost_spent_usd, token counts — is unconditional and unaffected. Default true.

dispatcher: Dispatcher
engineId?: string

Who this engine is, stamped on every ledger entry it opens (#349) and read back by sweepStale. Defaults to <hostname>:<pid> — the process is the unit, because the process is what owns the job table the sweep is really asking about. Override only to model another process (tests) or to name an engine whose pid a supervisor recycles.

frameworkPrefix?: string

Override the .gateline default when this repo was integrated with a custom gateline init --prefix (#95) — otherwise auto-detected.

identity: Identity
localOnly?: boolean

Local-only mode (mirrors the core resolution table, AC2.2/AC2.4): forces the engine's LocalGitSource to skip origin fetch on heartbeat sync, and suppresses the first-dispatch draft-PR ensure.

log?: (line: string) => void
maxConcurrentDispatches?: number

Resource ceiling (#227): the most dispatches allowed to run at once across every active run. Budget guards bound what a tick may spend; nothing bounded what it may start, so concurrency equalled the number of runs with ready work. Each dispatch carries an agent process, a cold worktree install (#229), and — per roles/implementer.md — a full suite run, so three simultaneous implementers were enough to exhaust a 48 GB workstation. On the blessed single-machine topology (TOPOLOGY.md §3.1) that machine is also the control plane, so exhaustion takes down dispatch, Gatehouse, and the operator's ability to intervene at once.

Unlike a budget ceiling, hitting this is not an escalation: no human decision unblocks it and it clears itself as jobs finish, so a capped dispatch is simply not started and re-derives on a later tick. 0 (or negative) disables the cap.

now?: () => Date
push?: boolean

Push every orchestrator commit to origin (hosted mode): the machine is disposable, origin is not.

registry: null | Registry
repoDir: string
requireBudget?: boolean

Refuse dispatch on a run missing budget.cost_limit_usd (hosted mode): unattended dispatch needs a ceiling.

roleTimeoutMs?: number

Dispatch wall clock per role before the job is killed (default 30 min).

spendLimitUsd?: null | number

Host-wide ceiling (hosted mode): refuse new dispatches when projected spend across every active run exceeds this, escalating like DB does. Per-run cost_limit_usd still applies; this bounds their sum.

spendWindowMs?: number

The window the host ceiling measures over (#97), default 24 hours. spendLimitUsd bounds what this deployment spends per window, not over its lifetime: only closed ledger entries opened inside the window count, plus every open entry at its estimate. A lifetime sum only ever grows — under the repo's own convention of keeping run branches, a static cap was reached once and never left — whereas a window rolls, so the ceiling is a rate limit for an unattended host that clears itself.

staleMs?: number

Age at which an open ledger entry with no live job is declared lost (default 5 min).