Manifest (schema 1)
Every module bundle has a oarbank-module.toml at its root. It holds every fact the core needs before running module code: identity, compatibility, entry points, stages and resources, services and probes, result fields, dataset kinds, goldens, the declarative UI and the module CLI. Behaviour stays in code (the module protocol verbs).
Rule of thumb: if the scheduler, the installer or the console needs a fact to decide something, declare it in the manifest. If deciding needs the module’s judgement, it is a verb.
- Every key, with its type, default and stability label: manifest-reference.md, generated from the models.
- Schemas:
schemas/manifest-1.schema.json(lenient, what the core reads) andschemas/manifest-1.strict.schema.json(for editors: unknown keys are errors). - Validate a manifest with
oarbank-sdk check oarbank-module.toml. - Worked examples: toy (minimal, the reference module), and the shipped modules’ manifests in their repositories: oarbank-module-bench (typical) and oarbank-module-minos-gatk (stages, probes, datasets, campaign views and panels, operations, a CLI).
Names and interpreters
Section titled “Names and interpreters”- The module’s short name (“module-short”) is the last dot-separated part of
module.id(dev.example.primes→primes). It names the module in operation ids (mod.<short>.<verb>, with-as_), schema references (<short>/spec@N), reason codes (<short>/<code>), the release layout (modules/<short>/) andOARBANK_MODULE.
An exec (coordinator.exec, runner.exec, coordinator and runner variants, services, probes, cli.exec) is an argv
array, never a shell string.
- Element 0 is either:
- the token
python: the Python of the module’s own environment on every OS (bin/python, orScripts\python.exeon Windows), never whateverpythonis on the PATH. It needsruntime.kindpython(the host’s managed CPython with the SDK, plus the bundle’s requirements installed from wheels) oruv(a locked environment, wheels-only for every declared platform); or {bundle}/<PortablePath>: a native executable in the bundle (runtime.kind = "native"). On Windows it names its.exe; the host never appends extensions. Shebang scripts are valid only in darwin and linux variants.
- the token
.bat,.cmdand.ps1are never valid as element 0.{bundle}may appear in any element and is replaced by the bundle’s absolute native path. Nothing else is rewritten: relative paths are not resolved for you.- cwd: the bundle root for the coordinator, services and probes; the work directory for
run; the data directory fordoctor. oarbank_sdk.manifest.resolve_execis the reference resolver.
Platforms
Section titled “Platforms”requires.platformsis required: the node platform tokens the module runs on (platforms.md).requires.coordinator_platformslists the coordinator host platforms the coordinator side runs on (absent: any), and[requires.unsupported]gives reasons for what is not supported.requires.osgives per-OS version ranges (darwin,windows, andlinux = {kernel, glibc}).[runner.variants."<platform>"](or[runner.variants.<os>]) overridesexec,runtime,capabilities,stop_grace_s,gpuandenvfor that platform. The most specific key wins.[coordinator.variants.<key>]does the same for the coordinator host (exec,runtime,timeouts_s,concurrency,env), and[stages.variants.<key>]for a stage (timeout_s,requires.resources,retry).env,timeouts_sand resources merge key by key; every other field replaces (platforms.md).platformson services, probes andstages[].requiresrestricts them to some declared platforms.- One bundle carries every platform’s files: one digest, one approval, one
compat.[bundle.platform_files]says which files only some platforms’ nodes receive. [placement]keeps each campaign, group, dataset or pipeline on one platform class (platforms.md).- These per-platform and placement keys need
requires.core >= 2.2.
Sections
Section titled “Sections”| Section | What it declares |
|---|---|
manifest |
The schema major, 1. |
[module] |
id (reverse DNS; never reused), version (SemVer), compat (part of every job key), publisher, SPDX license, codeowners, stability. |
[requires] |
Supported core, agent and OS ranges, node and coordinator platforms, unsupported reasons, the protocol majors spoken, and must-understand features. experimental lists opt-ins. |
[coordinator] |
The module-protocol process: exec, runtime, optional-verb capabilities, concurrency, per-verb timeouts_s, host-callback permissions, the effects campaign.tick may request, env, and per-platform variants. |
[coordinator.move] |
The module’s part in a coordinator move: rules (a files prefix or a store collection, with class carry, rebuild or drop) and the effects the move verbs may request (module-protocol.md). |
[runner] |
The runner-protocol executable: exec, runtime, capabilities, stop_grace_s, gpu, bandwidth_class, env, and per-platform variants. |
[[stages]] |
At least one. Each has name, optional after, and requires (node capabilities, reserved pools, needs_pools that must merely exist, and resources cpu/mem_gb), plus timeout_s and retry, per-platform variants, and a placement constraint with its after stage. |
[[services]] |
Node helpers the agent manages through the service protocol: lifecycle, timeouts, restart policy, which pools and capabilities they provide, and the memory, yield and pause flags. |
[[probes]] |
Read-only capability checks (fingerprint only), each run every period_s. |
[settings] |
The JSON Schema for the module’s settings. The core stores settings but never interprets them. |
[placement] |
Which unit of work stays on one platform class (mix, unit), how it binds (bind) and what happens when its class has no eligible node (rebind, stranded_after_s). |
[results] |
The payload schema and its version, determinism and its determinism_scope, the digest (version, over), the objective value, the inline size limit, and declared fields (typed; indexed promotes a field to a sortable column; ui sets column, format and unit). |
[datasets] |
The dataset kinds the module registers (namespaced by the core), their typed attrs, and the platform_bound kinds. |
[bundle] |
executables globs (mode 755) and platform_files (glob → the platforms or OSes whose nodes receive the files). |
[goldens] |
The fixtures glob and the comparison mode (digest, or verb to call golden.compare). |
[ui] |
Declarative contributions only: a digest_line template, study_columns, icon. |
[cli] |
The module CLI. oarbank cli <module> [args...] runs it on the coordinator, sandboxed (its bundle read-only, a scratch directory writable, only the admin API reachable), with OARBANKD_URL and OARBANK_TOKEN: a one-hour token limited to the module’s own operations and reads. |
Cross-field rules
Section titled “Cross-field rules”The models enforce these, beyond the per-field types:
- Stage names are unique.
aftermust name another stage, and stage dependencies form no cycle. - Every pool a stage requires (
poolsorneeds_pools) is provided by a declared service. Every required capability is provided by a service or a probe. - If services or probes are declared,
requires.service_protocollists at least one major. results.value.fieldis a declared result field.- A module with more than one stage implements
result.merge(listed incoordinator.capabilities). goldens.compare = "verb"requires thegolden.comparecapability.- With
runtime.kind = "uv", bothlockandpythonare set. - A move rule names exactly one of
filesorstore. Arebuildrule requires themove.postflightcapability, andcoordinator.move.effectsrequires at least one move verb. - Variant keys (runner, stages) and
bundle.platform_filesvalues are declared platforms or OSes of one. Coordinator variant keys are coordinator platforms or their OSes whenrequires.coordinator_platformsis set. requires.unsupportednever contradicts the allow-lists: arunnerkey is not a declared platform or the OS of one, andcoordinatorkeys needrequires.coordinator_platformsand are not in it.envnames (runner, coordinator, their variants) match^[A-Z][A-Z0-9_]*$and are never reserved:OARBANK_*,PATH,HOME,USERPROFILE,SYSTEMROOT,TEMP,TMP,TMPDIR,LOCALAPPDATA,APPDATAand the other variables the host sets (platforms.md). Stage variant resources keep the stage’s bounds.- Any per-platform or placement key (
requires.coordinator_platforms,requires.unsupported,requires.features,coordinator.env,coordinator.variants,runner.envand runner variantenv,stages[].variants,stages[].placement,[placement], adeterminism_scopeother thanglobalorplatform,bundle.platform_files,datasets.platform_bound) needs arequires.corerange whose lower bound is at least 2.2. Every entry ofrequires.featuresis one this SDK knows. - Every bundle path a node exec names (argv[0], or the script a
pythonexec runs) reaches each platform that runs it underbundle.platform_files.datasets.platform_boundkinds are declared kinds. - Lint (warnings, not errors): an unknown
mix; a stageplacementon a stage withoutafter; an unknowndeterminism_scope; a placement mix coarser thandeterminism_scopewhileresults.valueis set (values in one campaign would come from classes whose results are not comparable).oarbank-sdk checkprints them;oarbank_sdk.manifest.lintreturns them.
Several stage chains may coexist. For example, minos-gatk declares a single eval stage and a call → score chain, and job.plan picks one per evaluation.
Declarative UI: formats and templates
Section titled “Declarative UI: formats and templates”Module UI is data. Core templates render it and escape it, and no module HTML or JS is ever executed.
-
Field formats are one of these:
Format Renders as .Nffixed-point, N decimals .Neexponent notation, N decimals .N%percentage, N decimals dinteger ,dinteger with thousands separators sstring .Nsstring truncated to N characters N is one or two digits.
-
digest_lineis plain text with{field}or{field:FORMAT}placeholders (field names in lower snake case), and{{/}}for literal braces. Nothing else is allowed. -
iconcomes from a fixed set:cpu,gpu,dna,chart,flask,cube,bolt.
What a manifest cannot declare
Section titled “What a manifest cannot declare”- Host protection: exemptions, priority over the owner’s protected processes, or node selection by identity. Protection is owner-set only (see the public-surface statement).
- Secrets. Settings are visible to the owner in the console.
Source: spec/manifest.md in the oarbank-sdk repository