@x12i/graphenix-executable-format
v2.12.0
Published
Umbrella package: re-exports graphenix executable lifecycle packages for convenience.
Maintainers
Readme
@x12i/graphenix-executable-format
Umbrella package — re-exports the full Graphenix executable lifecycle for prototypes and all-in-one installs.
For production, depend on lifecycle packages directly (design-only clients should not pull in plan-compiler or trace-format).
Canonical vocabulary: GLOSSARY.md · Format scope: FORMAT-SCOPE.md
Naming: @x12i/* is the npm scope only. JSON documents use graphenix.* identifiers and plain node kinds (task, finalizer) — never x12i in saved payloads.
Authoring interchange: AuthoringGraphDocument at formatVersion: "2.1.0" is the sole authoring shape. Flat Exellix JSON is import-only (legacyExellixGraphToGraphProject). Engine handoff uses authoringGraphToEngineDocument(); compile uses compileAuthoringGraphToExecutablePlan() (no runtime on compile ingress).
Who should use this
| Role | Prefer umbrella? | Prefer direct packages |
| ---- | :--------------: | ---------------------- |
| Prototype / spike | Yes | |
| Graph designer / editor | No | @x12i/graphenix-authoring-format + @x12i/graphenix-case-format |
| Compiler / execution prep | No | @x12i/graphenix-plan-compiler + @x12i/graphenix-plan-format |
| Execution engine | No | @x12i/graphenix-plan-format + @x12i/graphenix-trace-format |
| Backend host | No | @x12i/graphenix-execute-envelope |
Install
npm install @x12i/graphenix-executable-format @x12i/graphenix-coreBuilt on @x12i/graphenix-core, with deterministic model cases validated against @x12i/ai-profiles.
Full lifecycle (four phases)
Reference domain: graph:content-pipeline — parallel research → content package.
Fixture: createContentPipelineReferenceGraph() from this package (re-exported from authoring-format).
┌─ DESIGN ─────────────────────────────────────────────────────────────┐
│ AuthoringGraphDocument + ConceptDocument (shadow, optional) │
│ validateGraph + validateAuthoringGraph + validateConceptDocument │
└───────────────────────────────┬──────────────────────────────────────┘
│ compileExecutablePlan(authoring, runtime)
┌─ COMPILE ─────────────────────▼──────────────────────────────────────┐
│ ExecutableGraphPlan │
│ validateExecutablePlan │
└───────────────────────────────┬──────────────────────────────────────┘
│ engine runs executionUnits[] in order
┌─ EXECUTE + TRACE ─────────────▼──────────────────────────────────────┐
│ GraphExecutionTrace (append-only) │
│ validateExecutionTrace │
└──────────────────────────────────────────────────────────────────────┘| Phase | Artifact | Validate with | Finalization brief |
| ----- | -------- | ------------- | ------------------ |
| Design | AuthoringGraphDocument | validateGraph, validateAuthoringGraph | GRAPH-FORMAT-FINALIZATION.md |
| Design (shadow) | ConceptDocument | validateConceptDocument | concept-document.md |
| Compile | ExecutableGraphPlan | validateExecutablePlan | COMPILE-FORMAT-FINALIZATION.md |
| Execute + trace | GraphExecutionTrace | validateExecutionTrace | EXECUTE-TRACE-FORMAT-FINALIZATION.md |
Role guides: docs/roles/README.md
Package family
@x12i/graphenix-core
│
▼
@x12i/graphenix-executable-contracts
│
├── @x12i/graphenix-case-format
├── @x12i/graphenix-executable-profile-format
├── @x12i/graphenix-task-node-format
├── @x12i/graphenix-authoring-format
├── @x12i/graphenix-authoring-analysis
├── @x12i/graphenix-plan-format
└── @x12i/graphenix-trace-format
▲
│
@x12i/graphenix-plan-compiler
▲
│
@x12i/graphenix-execute-envelope (optional host adapter)
@x12i/graphenix-executable-format ← this package (re-exports all above)| Package | Phase | README |
| ------- | ----- | ------ |
| @x12i/graphenix-executable-contracts | Shared types | executable-contracts/README.md |
| @x12i/graphenix-case-format | Design | case-format/README.md |
| @x12i/graphenix-task-node-format | Design | task-node-format/README.md |
| @x12i/graphenix-executable-profile-format | Design | executable-profile-format/README.md |
| @x12i/graphenix-authoring-format | Design | authoring-format/README.md |
| @x12i/graphenix-authoring-analysis | Design (studio save) | authoring-analysis/README.md |
| @x12i/graphenix-plan-compiler | Compile | plan-compiler/README.md |
| @x12i/graphenix-plan-format | Compile + execute input | plan-format/README.md |
| @x12i/graphenix-execute-envelope | Execute prep | execute-envelope/README.md |
| @x12i/graphenix-trace-format | Execute + observability | trace-format/README.md |
JSON identifiers (format payloads)
| Field | Value |
| ----- | ----- |
| Task node kind | "task" |
| Finalizer node kind | "finalizer" |
| Task parameters.profile | "graphenix.task-node/v1" |
| Finalizer parameters.profile | "graphenix.finalizer-node/v1" |
| Executable extension key | "graphenix.executable/v1" |
| Plan format | "graphenix.executable-plan/v1" or v2 |
| Trace format | "graphenix.execution-trace/v1" or v2 |
| Concept formatVersion | "graphenix.concept/v1" |
Phase 1 — Design (authoring)
Task run phases (vocabulary)
One task node = one runTask wave: prePhase → mainPhase → postPhase.
See GLOSSARY §1–§5.
Explicit rule: aiTaskStrategies.pre: "synthesis" (PRE-phase utility strategy) ≠ aiTaskProfile.inputSynthesis.enabled (skill input synthesis profile → plan pipelinePhase). Do not use “Synthesis PRE”.
Two-tier validation
import { validateGraph } from "@x12i/graphenix-core";
import {
validateAuthoringGraph,
validateConceptDocument,
createContentPipelineReferenceGraph
} from "@x12i/graphenix-executable-format";
const doc = createContentPipelineReferenceGraph();
validateGraph(doc);
validateAuthoringGraph(doc);
validateConceptDocument({
formatVersion: "graphenix.concept/v1",
graphId: doc.id,
name: doc.name,
graphConcept: {
primaryIntentStatement: "Turn a campaign brief into a structured content package."
}
});Authoring task node (JSON excerpt)
{
"id": "node:audience-insights",
"kind": "task",
"layout": { "x": 120, "y": 200 },
"parameters": {
"profile": "graphenix.task-node/v1",
"nodeType": "task",
"skillKey": "professional-answer",
"taskConfiguration": {
"executionStrategies": [],
"aiTaskStrategies": {
"pre": "synthesis",
"preInputStrategy": "execution-memory-only"
}
}
}
}Phase model profiles (extension)
"metadata": {
"extensions": {
"graphenix.executable/v1": {
"profileVersion": "1.0.0",
"modelConfig": {
"version": "graph-model-config/v1",
"cases": [{
"id": "default",
"modelConfig": {
"preActionModel": { "kind": "profileChoice", "key": "cheap/default" },
"skillModel": { "kind": "profileChoice", "key": "vol/default" },
"postActionModel": { "kind": "profileChoice", "key": "cheap/default" }
}
}]
}
}
}
}Design APIs
| API | Purpose |
| --- | ------- |
| validateAuthoringGraph | Executable profile + full task-node body |
| validateConceptDocument | Studio shadow document |
| validateCaseCondition / evaluateCaseCondition | Deterministic when DSL |
| selectGraphModelCase / selectNodeModelCase | Case preview at design time |
| resolveNodeAiPlan / explainNodeInheritance | Preview slot resolution |
| normalizeExecutableGraph | Canonical model config (non-mutating) |
| stripDesignOnlyFieldsFromGraph | Remove node.layout before plan embed |
| createMinimalExecutableGraph | One task + finalizer |
| createContentPipelineReferenceGraph | Canonical reference graph |
| addTaskNode, setGraphModelConfig, … | CRUD helpers |
Deterministic cases (summary)
Cases may choose stronger or weaker AI profiles.
AI may not choose the case.Allowed selectors: runtime.mode, runtime.input.*, runtime.environment, graph.id, …
Forbidden: ai.*, node.output.*, semanticMatch, LLM-based conditions.
Full DSL: case-format/README.md.
Phase 2 — Compile (authoring → plan)
Design → plan mapping
| Authoring (design) | Plan execution unit | Run phase |
| ------------------ | ------------------- | --------- |
| aiTaskStrategies.pre | externalPreUtility | prePhase |
| skillKey + plain MAIN | mainSkill | mainPhase |
| aiTaskProfile.inputSynthesis | pipelinePhase | mainPhase |
| aiTaskStrategies.post | externalPostUtility | postPhase |
| Phase model profiles | modelSlot + modelSelection on each unit | per phase |
Content pipeline reference tasks: PRE synthesis + MAIN only (no POST unless design declares it).
Compile flow
import {
createContentPipelineReferenceGraph,
compileExecutablePlan,
validateExecutablePlan,
buildRuntimeObject
} from "@x12i/graphenix-executable-format";
const authoring = createContentPipelineReferenceGraph();
const runtime = buildRuntimeObject({
jobId: "job-001",
mode: "live",
input: { priority: "normal" }
});
const plan = compileExecutablePlan(authoring, runtime, {
profileRegistry: { package: "@x12i/ai-profiles", version: "3.2.0" },
environment: "prod"
});
const result = validateExecutablePlan(plan);
if (!result.valid) throw new Error("Invalid plan");Internal pipeline:
validateAuthoringExecutableGraph()
normalizeExecutableGraph()
stripDesignOnlyFieldsFromGraph() ← node.layout removed
assertNormalizedExecutableGraph()
selectGraphModelCase() → resolveNodeAiPlan() per task node
buildNodeExecutionUnits() ← PRE / MAIN / POST from aiTaskStrategies
buildFinalizerPlans()
validateExecutablePlan() ← recommended before handoffCompiled plan (JSON excerpt — v2)
{
"format": "graphenix.executable-plan/v2",
"source": { "graphId": "graph:content-pipeline" },
"nodePlans": {
"node:audience-insights": {
"executionUnits": [
{
"unitKind": "externalPreUtility",
"order": 0,
"strategyKey": "synthesis",
"modelSlot": "preActionModel"
},
{
"unitKind": "mainSkill",
"order": 1,
"skillKey": "professional-answer",
"modelSlot": "skillModel"
}
]
}
}
}Compile APIs
| API | Purpose |
| --- | ------- |
| compileExecutablePlan | Authoring + runtime → plan |
| validateExecutablePlan | Validate v1 or v2 plan |
| buildDeterministicCaseContext | Freeze pre-run context |
| buildGraphExecutionRequestFromStudioExecute | Host adapter: request → { plan, runtime } |
Details: plan-compiler/README.md · plan-format/README.md
Phase 3 — Execute (engine)
The engine consumes only { plan, runtime }. It never reads authoring graphs.
Execution order
validateExecutablePlanV2(plan)on receipt- Evaluate
plan.deferredGates(entry → node → edge) before scheduling - Walk task nodes in topological order; parallel branches may run concurrently when policy allows
- Per task node: PRE units → MAIN → POST; delegate unit loop to node executor via
runTask({ nodePlan }) - Apply mapping units in orchestrator after
runTaskreturns - Run finalizer phase after all upstream tasks complete
validateTraceAgainstPlan(trace, plan)at run end
Each unit uses frozen modelSelection from the plan — no case re-selection at runtime.
Security checklist: never forward Studio credentials into GraphRuntimeObject; reject taskConfiguration on RunTaskRequest when nodePlan is present; set RunTaskRequest.input from runtime.input (see run-task-data-model.md).
Golden handoff: packages/plan-format/fixtures/content-pipeline.plan.json.
Execute APIs (from this package)
| API | Package origin |
| --- | -------------- |
| validateExecutablePlan | plan-format |
| createExecutionTrace | trace-format |
| appendExecutionEvent | trace-format |
Details: docs/roles/execution-engine.md
Phase 4 — Trace (evidence)
Traces are append-only and bound to planHash. Prefer v2 traces when the plan is v2 (graphenix.execution-trace/v2).
Reference fixtures:
createContentPipelineReferenceTrace(plan)— programmatic complete CP runpackages/trace-format/fixtures/content-pipeline.trace.json— golden JSON (3 tasks + finalizer)
Multi-node timeline for content pipeline: graph.started → parallel unit.* on three task nodes → node.completed × 3 → finalizer unit.* → graph.completed.
import {
createExecutionTrace,
appendExecutionEvent,
validateExecutionTrace,
deriveGraphStatus,
summarizeExecutionTrace
} from "@x12i/graphenix-executable-format";
const trace = createExecutionTrace(plan, runtime);
appendExecutionEvent(trace, {
id: "evt:1",
ts: new Date().toISOString(),
level: "info",
type: "graph.started",
message: "Graph execution started."
});
appendExecutionEvent(trace, {
id: "evt:2",
ts: new Date().toISOString(),
level: "info",
type: "node.started",
nodeId: "node:audience-insights"
});
appendExecutionEvent(trace, {
id: "evt:3",
ts: new Date().toISOString(),
level: "info",
type: "unit.started",
nodeId: "node:audience-insights",
unitId: "unit:node:audience-insights:pre:0",
unitKind: "externalPreUtility"
});
validateExecutionTrace(trace, plan.nodePlans);
const status = deriveGraphStatus(trace);Trace header (JSON excerpt)
{
"format": "graphenix.execution-trace/v1",
"traceId": "trace:job-001",
"jobId": "job-001",
"source": { "graphId": "graph:content-pipeline", "graphHash": "sha256:…" },
"plan": { "planId": "plan:abc123", "planHash": "sha256:…" },
"events": []
}Details: trace-format/README.md · docs/roles/observability.md
Validation tiers (summary)
| When | Call |
| ---- | ---- |
| Authoring save | validateGraph + validateAuthoringGraph |
| Concept save | validateConceptDocument |
| After compile | validateExecutablePlan |
| After run | validateExecutionTrace(trace, plan.nodePlans) |
End-to-end example (umbrella import)
import { validateGraph } from "@x12i/graphenix-core";
import {
createContentPipelineReferenceGraph,
validateAuthoringGraph,
compileExecutablePlan,
validateExecutablePlan,
buildRuntimeObject,
createExecutionTrace,
appendExecutionEvent,
validateExecutionTrace
} from "@x12i/graphenix-executable-format";
// Design
const authoring = createContentPipelineReferenceGraph();
validateGraph(authoring);
validateAuthoringGraph(authoring);
// Compile
const runtime = buildRuntimeObject({ jobId: "job-001", mode: "live", input: {} });
const plan = compileExecutablePlan(authoring, runtime);
validateExecutablePlan(plan);
// Execute + trace (engine loop abbreviated)
const trace = createExecutionTrace(plan, runtime);
appendExecutionEvent(trace, {
id: "evt:1",
ts: new Date().toISOString(),
level: "info",
type: "graph.completed",
message: "Done."
});
validateExecutionTrace(trace, plan.nodePlans);Profile choice format
{ "kind": "profileChoice", "key": "vol/default" }Examples: cheap/default, vol/default, vol/pro, deep/openai_deep.
Rejected: bare aliases, kind: "profile", vendor slugs as profileChoice keys.
profileChoice resolves at compile/plan time via @x12i/ai-profiles — not during normalization.
Model inheritance and fallback
- Graph-level
modelConfigis required with full triplet per case (preActionModel,skillModel,postActionModel). - Node overrides may be partial when
inherit: true. - Fallback is same-slot only on the selected graph case — never cross-slot or runtime defaults.
Node kinds
| kind | parameters.profile | Purpose |
| ------ | -------------------- | ------- |
| task | graphenix.task-node/v1 | Skill + phase utility strategies |
| finalizer | graphenix.finalizer-node/v1 | Graph output (finalizerType: aggregate, compose, …) |
Design-only: node.layout — stripped at compile, never on plan.
Development
From monorepo root:
npm install
npm run build --workspace=@x12i/graphenix-executable-format
npm run test --workspace=@x12i/graphenix-executable-formatSchema
Profile JSON Schema fragment: schema/graphenix-executable-format-1.0.0.schema.json (structural subset; full semantics enforced by TypeScript validators).
Further reading
| Doc | Topic |
| --- | ----- |
| GLOSSARY.md | Phase vocabulary |
| FORMAT-SCOPE.md | Compliance + strict profiles |
| NAMING.md | npm @x12i/* vs JSON graphenix.* |
| PUBLISHING.md | npm publish order |
| docs/IMPLEMENTATION-REPORT.md | Acceptance test matrix |
