Decision packages

Decision Packages

Decision Packages

A DECISION PACKAGE declaration is a version-pinned compatibility contract: it states that the model depends on an exact native computation — identified by id, semantic version, and domain — and spells out the execution dialects, behavioral capabilities, and typed input/output artifact contracts that the native implementation must honor. The declaration is static. It contains no data, does not execute anything, and does not create a binding that formulas can reference; it survives into compiled module metadata, and the resident runtime later resolves it against its registry of native packages in a separate, fail-closed step.

DECISION PACKAGE "ag.field-margin" VERSION "1.0.0" DOMAIN "crop.field-margin" {
  DIALECTS (workbook, frame, geo)
  CAPABILITIES (incremental_repair, missing_data_gates, source_provenance, unit_safe_economics)
  INPUT fields SCHEMA "ag.field.v1" MANY REQUIRED
  INPUT seasons SCHEMA "ag.season.v1" MANY REQUIRED
  INPUT operations SCHEMA "ag.operation.v1" MANY REQUIRED
  INPUT "margin-model" SCHEMA "ag.field-margin-model.v1" ONE REQUIRED
  OUTPUT "field-margin" SCHEMA "ag.field-margin.v1" MANY REQUIRED
  OUTPUT "execution-evidence" SCHEMA "ag.field-margin-evidence.v1" ONE REQUIRED
}
 
margin_ready = TRUE

Statement Grammar

A decision package is a top-level statement. By convention it sits near the top of the model, after header directives.

DECISION PACKAGE "<id>" VERSION "<major.minor.patch[-suffix]>" DOMAIN "<domain>" {
  DIALECTS (<dialect> [, <dialect> ...])
  [CAPABILITIES (<capability> [, <capability> ...])]
  INPUT  <name | "quoted-name"> SCHEMA "<schema>" ONE|MANY|STREAM REQUIRED|OPTIONAL
  OUTPUT <name | "quoted-name"> SCHEMA "<schema>" ONE|MANY|STREAM REQUIRED|OPTIONAL
}

Inside the braces the entries may appear in any order, but DIALECTS and CAPABILITIES may each appear at most once. Every package must declare at least one dialect, at least one INPUT, and at least one OUTPUT. CAPABILITIES may be omitted or empty.

Keywords are case-insensitive, as elsewhere in Grid. The quoted tokens — id, domain, schemas, and quoted artifact names — are canonicalized: trimmed, lowercased, and restricted to ASCII letters, digits, ., -, and _, with at least one alphanumeric character. A token outside that shape reports GRID_DECISION_TOKEN_INVALID.

Id, VERSION, And DOMAIN

The header pins an exact identity. VERSION must be a pinned semantic version: three dot-separated numeric components, optionally followed by one hyphenated pre-release suffix ("1.0.0", "2.1.0-rc.1"). Ranges, channels, and floating tags ("^1.0.0", "latest") report GRID_DECISION_VERSION_INVALID. DOMAIN names the decision domain the package serves (for example "crop.field-margin"); it participates in exact matching like every other header field.

A model may declare many packages, but each package id at most once; re-declaring an id reports GRID_DECISION_PACKAGE_DUPLICATE.

DIALECTS

DIALECTS lists the execution surfaces the package computes over. The set is closed: workbook, frame, geo, stream, solver, simulation, planning, ai, and training. Anything else reports GRID_DECISION_DIALECT_UNKNOWN, and a repeated dialect reports GRID_DECISION_DUPLICATE_MEMBER.

CAPABILITIES

CAPABILITIES lists open identifiers describing safety and optimization behavior the package commits to, such as source_provenance or unit_safe_economics. There is no central capability enum, so packages can state new behavior without a language change — but matching against the native registration is exact, so a declaration that omits a capability the native package declares (or invents one it does not) is rejected at model load. A repeated capability reports GRID_DECISION_DUPLICATE_MEMBER.

These are not host authority grants; see Capabilities Versus REQUIRES.

INPUT And OUTPUT Artifact Contracts

Each INPUT or OUTPUT line declares one artifact contract:

  • Name — an identifier, or a quoted token when the canonical name contains a hyphen ("margin-model"). Names are canonicalized to lowercase and must be unique within their direction; a repeat reports GRID_DECISION_DUPLICATE_ARTIFACT. An input and an output may share a name.
  • SCHEMA "<ref>" — the versioned schema contract the artifact batch must satisfy (for example "ag.field.v1").
  • Cardinality — ONE (exactly one record), MANY (a bounded batch), or STREAM (streaming data). The runtime enforces this shape at artifact admission.
  • REQUIRED or OPTIONAL — whether the artifact must be present. An OPTIONAL output may legitimately be absent; for example, the nutrient prescription package omits its recommendation artifact for an infeasible solve.

STREAM is fully parsed and enforced at artifact admission, but none of the natively registered packages currently declares a streaming artifact, so a STREAM contract cannot be admitted against today's default runtime.

A contract using ONE, MANY, and OPTIONAL together:

DECISION PACKAGE "ag.nutrient-prescription" VERSION "1.0.0" DOMAIN "crop.nutrient-prescription" {
  DIALECTS (workbook, frame, geo, solver, planning)
  CAPABILITIES (approval_gated_export, convex_zone_response, hard_rate_bounds, inventory_budget_constraints, source_provenance, uncertainty_guard)
  INPUT field SCHEMA "ag.field.v1" ONE REQUIRED
  INPUT season SCHEMA "ag.season.v1" ONE REQUIRED
  INPUT zones SCHEMA "ag.zone.v1" MANY REQUIRED
  INPUT "soil-observations" SCHEMA "ag.observation.v1" MANY REQUIRED
  INPUT "prescription-model" SCHEMA "ag.nutrient-prescription-model.v1" ONE REQUIRED
  INPUT request SCHEMA "ag.nutrient-prescription-request.v1" ONE REQUIRED
  OUTPUT outcome SCHEMA "ag.nutrient-prescription-outcome.v1" ONE REQUIRED
  OUTPUT recommendation SCHEMA "ag.recommendation.v1" ONE OPTIONAL
  OUTPUT "solver-evidence" SCHEMA "ag.solver-evidence.v1" ONE REQUIRED
}
 
prescription_ready = TRUE

Exact Matching At Model Load

Compiling a declaration proves nothing about availability. When a model becomes resident, the runtime resolves every declared package against its native registry and fails closed:

  • an unknown id reports GRID_DECISION_PACKAGE_UNAVAILABLE;
  • a known id at an unregistered version reports GRID_DECISION_VERSION_UNAVAILABLE;
  • any difference between the declared and registered contract — domain, dialect set, capability set, or any artifact name, schema, cardinality, or required flag — reports GRID_DECISION_CONTRACT_MISMATCH.

Matching is order-insensitive (contracts are compared after canonical sorting) but otherwise exact. This intentionally rejects a model that omits a safety capability or weakens an output contract even when id and version match. The default runtime registers ag.field-margin@1.0.0, ag.nutrient-prescription@1.0.0, and energy.storage-dispatch@1.0.0; a declaration for any other package will not load against it. In practice this means every DECISION PACKAGE block you write must be copied exactly from the native package's published contract, not composed freehand.

Before native execution, input and output batches are validated against the admitted contract and rejected with GRID_DECISION_ARTIFACT_* codes for unknown names, schema mismatches, missing required artifacts, and cardinality violations. The full set of GRID_DECISION_* failure codes is listed in the diagnostics catalog.

Capabilities Versus REQUIRES

CAPABILITIES inside a decision package and REQUIRES declarations both use the word "capability" for different systems. A decision package capability is a descriptive label matched exactly against the native registration; it neither requests nor grants host authority. Host authority — network origins and secret purposes — is declared separately with REQUIRES alias = NETWORK("https://host", GET) or REQUIRES alias = SECRET("logical.purpose"), which the host enforces with its own GRID_REQUIREMENT_* diagnostics. The two declarations are independent statements and may coexist in one model:

REQUIRES price_feed = NETWORK("https://prices.example.com", GET)
 
DECISION PACKAGE "energy.storage-dispatch" VERSION "1.0.0" DOMAIN "energy.storage-dispatch" {
  DIALECTS (workbook, frame, solver, simulation, planning)
  CAPABILITIES (approval_gate, independent_physical_replay, source_provenance, sparse_optimization, tariff_bill_reproduction, unit_safe_energy)
  INPUT "planning-problem" SCHEMA "energy.storage-planning-problem.v1" ONE REQUIRED
  OUTPUT "dispatch-plan" SCHEMA "energy.storage-dispatch-plan.v1" ONE REQUIRED
  OUTPUT "evidence-bundle" SCHEMA "energy.storage-evidence.v1" ONE REQUIRED
}
 
dispatch_ready = TRUE

See external-functions.md for the REQUIRES declaration surface.

Diagnostics

Parse-time diagnostics with dedicated codes:

Code Trigger
GRID_DECISION_VERSION_INVALID VERSION is not a pinned semantic version
GRID_DECISION_DIALECT_UNKNOWN A dialect outside the closed dialect set
GRID_DECISION_TOKEN_INVALID An id, domain, schema, name, dialect, or capability outside the canonical token shape
GRID_DECISION_DUPLICATE_ARTIFACT The same artifact name declared twice in one direction
GRID_DECISION_DUPLICATE_MEMBER A repeated dialect or capability
GRID_DECISION_PACKAGE_DUPLICATE The same package id declared twice in one model

Structural mistakes — a missing VERSION or DOMAIN, a second DIALECTS or CAPABILITIES clause, an entry that is not DIALECTS, CAPABILITIES, INPUT, or OUTPUT, a missing cardinality or REQUIRED/OPTIONAL token, an empty dialect list, a package without at least one INPUT and one OUTPUT, or an unterminated block — report the general GRID_RUST_PARSE code with a message naming the expected token.

The GRID_DECISION_PACKAGE_UNAVAILABLE, GRID_DECISION_VERSION_UNAVAILABLE, GRID_DECISION_CONTRACT_MISMATCH, and GRID_DECISION_ARTIFACT_* codes above are model-load and execution failures, not parse diagnostics.

Where Packages Are Consumed

Decision packages are the native-computation boundary of Domain Packs: a pack binds an exact {id, version} to a source model containing the declaration, domain-pack sync records the compiler-authored contract digest, and domain-pack test requires exact resident native admission; the Domain Pack authoring documentation covers both flows.

The host exposes inspection and execution surfaces — getDecisionPackages, validateDecisionArtifacts, and the per-package execution RPCs — for tooling that consumes declared packages. Host-owned durable workspaces and Studio surfaces for packages remain separate delivery work and are not implied by compiling a declaration.