For AI agents: the complete documentation index is available at https://jig.md/llms.txt, the full documentation bundle is available at https://jig.md/llms-full.txt, and this page is available as Markdown at https://jig.md/spec/project-sdk.md.
DocumentationSpecificationPrerelease

#Jig Project Authoring SDK/1

View Markdown

Status: prerelease candidate.

Project Authoring SDK/1 is the inert TypeScript surface used by jig.ts and Binding declaration files. Its values describe desired project membership and configuration. They do not read files, install dependencies, grant authority, admit a project, or start work.

#Public surface

import {
  defineBinding,
  defineJig,
  discover,
} from "@jigging/jig";

No administration, runtime, sandbox, event, Agent, or routing API is exported from this surface.

#Project declaration

A bare project makes its defaults explicit:

import { defineJig, discover } from "@jigging/jig";

export default defineJig({
  flows: discover("./flows"),
  bindings: discover("./bindings"),
});

flows and bindings are independently optional. Each accepts either a discover() value or an exact array of project-relative member paths. Omission means an empty source.

Discovery is shallow and inert:

  • a Flow root selects immediate real directories containing exact-case FLOW.md;
  • a Binding root selects immediate regular *.ts files;
  • it does not recurse, follow symlinks, execute declarations, or interpret globs; and
  • a missing valid discovery root is empty, while any invalid selected member rejects the complete project candidate.

Several roots may be supplied explicitly:

flows: discover(["./flows", "./vendor-flows"])

They form one unordered union. Duplicate, overlapping, escaping, symlinked, case-fold-colliding, or NFC-colliding members are rejected.

An exact source is the fail-closed alternative:

flows: ["./flows/build", "./flows/review"]

#Binding declaration

A Binding configures one exact project Flow package:

import { defineBinding } from "@jigging/jig";

export default defineBinding({
  package: "./flows/review",
  settings: { maxRetries: 4 },
  slots: {
    research: "flow:./flows/research",
    critique: "binding:critic",
  },
});

package is required. Omitting settings produces an empty object. Settings must satisfy the package's settings.schema.json when one exists.

slots is an optional map with at most 256 entries. Each key is a LocalName used by this Binding's package as a Run/1 flow/run-child slot. Each value is an exact flow:<project-relative-path> or binding:<LocalName> selector, using the same target vocabulary as the CLI. A Flow selector requires a direct Flow target; a Binding selector uses that Binding's own validated settings. Either child may use the exact Agent Run capability; a configured Binding may also use Project Command. A selected Binding must have no child slots. A Binding cannot select its own package, directly or through another Binding. Omitting slots normalizes to {}. The example's critic Binding selects a separate package such as flows/critique, with its own settings and no slots.

Slots are exact project links, not requests for later resolution. Project review binds each slot to the named Flow or Binding target in the same candidate, and admission retains that complete relation in one immutable generation. Slots belong only to the Binding declaration: running the package through its flow: identity has no slots, even when a Binding for that package does. Plain package paths are not slot selectors. A leading ./ after flow: is normalized away; the binding: suffix must be a LocalName.

commands optionally names reviewed Project Command invocations, for example commands: { tests: { test: ['test/project.test.ts'] } }. Only packages declaring that exact capability may receive a nonempty map. Command configuration is independent of ordinary Flow settings and travels with the selected Binding, never by inheritance from its caller. Review and admission include the exact invocation policy.

File paths are invocation inputs, not authoring declarations. Root Flows and Bindings can use declared attachments through the root file profile. Binding child slots cannot select attachment-bearing packages or inherit parent file authority.

Binding identity is the declaration filename's LocalName basename. For example, bindings/review.ts has ID review. There is no duplicate id field, profile inheritance, overlay, ambient environment fallback, or per-Run settings override.

Bindings are optional. A discovered Run package which is valid with empty settings, fits the root attachment profile, and uses only the supported Agent Run and/or Run Checkpoint contracts (or no capabilities) is also an exact direct Flow target. There is no hidden generated Binding.

#Value rules

All helpers are synchronous and side-effect-free. They return deeply frozen plain data and reject:

  • unknown keys;
  • explicit undefined or null for optional object fields;
  • functions, accessors, symbols, bigint, non-finite numbers, sparse arrays, cycles, class instances, and other non-JSON/1 values;
  • invalid LocalNames or project paths; and
  • duplicate or colliding paths.

One leading ./ is removed from author paths. Output paths use /, remain project-relative, and are bounded by the Project Authoring schema. Discovery does not accept a glob language.

These checks are ergonomic only. Jig evaluates captured author modules inside its bounded default-deny execution envelope, then independently validates and normalizes their result. Forged helper output acquires no trust.

#Machine shape

The closed machine schema is project-authoring-1.schema.json. It validates either a normalized project value:

{
  "flows": { "kind": "discover", "roots": ["flows"] },
  "bindings": { "kind": "discover", "roots": ["bindings"] }
}

or one normalized Binding value:

{
  "kind": "package",
  "package": "flows/review",
  "settings": {},
  "slots": {}
}

Authors do not add a format discriminator or $schema field. Shape validation alone is never admission evidence: Jig separately captures exact membership, retains immutable package and declaration bytes, links references, validates package schemas, derives the review delta, and admits only an explicitly applied retained Plan.

#Deliberate exclusions

SDK/1 does not define dynamic child-Flow resolution, candidate catalogues, semantic choice, Hooks, Services, Journal publishers, Agent selection, generic grants, runtime selection, sandbox selection, attachment projection, or administration. A Binding's exact slots map is the complete child-Flow authoring surface; the excluded concepts are absent rather than represented by placeholders.