@x12i/graphenix-authoring-format
v2.11.0
Published
Authoring graph format: Design/Edit validation, CRUD helpers, and profile-choice validation.
Maintainers
Readme
@x12i/graphenix-authoring-format
Authoring graph format — the Design/Edit document editors and generators validate in memory before save.
Validates AuthoringGraphDocument, ConceptDocument (shadow), deterministic model cases, task/finalizer nodes, phase utility strategies, and profileChoice keys via @x12i/ai-profiles.
Task-node vocabulary: GLOSSARY.md · Format scope: FORMAT-SCOPE.md · Design brief: GRAPH-FORMAT-FINALIZATION.md
Naming: @x12i/* is npm scope only. JSON uses graphenix.* profiles and plain kinds task / finalizer.
Task node design shape
Task node (design authoring)
│
├─ taskVariable.* task substance
├─ inputs / inputsConfig input bindings
├─ smartInput / executionMapping
│
├─ taskConfiguration
│ ├─ prePhase (aiTaskStrategies.pre + preInputStrategy)
│ ├─ mainPhase (executionStrategies — `[]` = explicit plain MAIN)
│ │ └─ skillProfile.inputSynthesis (aiTaskProfile.inputSynthesis)
│ └─ postPhase (aiTaskStrategies.post)
│
└─ graphenix.executable/v1 → preActionModel / skillModel / postActionModelpreActions[] / postActions[] are plan-phase action lists — not synonyms for aiTaskStrategies.pre.
Example authoring graph (JSON)
Content pipeline task with PRE-phase utility strategy synthesis + plain MAIN:
{
"formatVersion": "2.0.0",
"id": "graph:content-pipeline",
"revision": "1.0.0",
"name": "Content pipeline",
"graph": {
"nodes": [
{
"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"
}
}
}
},
{
"id": "node:finalizer:package",
"kind": "finalizer",
"parameters": {
"profile": "graphenix.finalizer-node/v1",
"nodeType": "finalizer",
"finalizerType": "aggregate",
"config": { "sections": [] }
}
}
],
"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" }
}
}]
}
}
}
}
}
}Fixtures: createMinimalExecutableGraph(), createContentPipelineReferenceGraph() (canonical).
Who should use this
| Role | Use this package? | | ---- | ----------------- | | Graph designer / editor / generator | Yes | | Compiler service | Upstream validation (also depends on this) | | Engine at runtime | No — engine receives compiled plans |
Install
npm install @x12i/graphenix-authoring-format @x12i/graphenix-coreExample (API)
import { validateGraph } from "@x12i/graphenix-core";
import {
validateAuthoringGraph,
validateConceptDocument,
createContentPipelineReferenceGraph,
normalizeExecutableGraph,
stripDesignOnlyFieldsFromGraph
} from "@x12i/graphenix-authoring-format";
const doc = createContentPipelineReferenceGraph();
validateGraph(doc);
validateAuthoringGraph(doc);
validateConceptDocument({
formatVersion: "graphenix.concept/v1",
graphId: doc.id,
name: doc.name
});
const normalized = normalizeExecutableGraph(doc);
const forPlan = stripDesignOnlyFieldsFromGraph(normalized);Two-tier validation
| Validator | Scope |
| --------- | ----- |
| validateGraph() | Topology, ports, task body, layout |
| validateAuthoringGraph() | graphenix.executable/v1 + task-node body |
| validateConceptDocument() | Paired shadow document (separate API) |
Key exports
| Category | APIs |
| -------- | ---- |
| Validation | validateAuthoringGraph, validateConceptDocument, validateNormalizedExecutableGraph, validateGraphJobMemory, validateGraphJobPipeline |
| Normalization | normalizeExecutableGraph, stripDesignOnlyFieldsFromGraph, normalizeGraphJobMemory, normalizeGraphJobPipeline |
| CRUD helpers | addTaskNode, addFinalizerNode, setGraphModelConfig, setNodeModelConfig, connectTaskToTask |
| Profile choice | validateAiModelSelection, isKnownProfileChoice |
| Model config authoring | readGraphJobModelDefaults, mergeEffectiveModelConfig, normalizeNodeOverrideForPersist, validateNodeModelConfigOverride, legacyModelConfigToAuthoring |
| Fixtures | createMinimalExecutableGraph, createContentPipelineReferenceGraph, createPlainGraphenixGraph |
| Task node (re-export) | validateTaskNode, phase config types from @x12i/graphenix-task-node-format |
Strict profiles
| Node kind | parameters.profile |
| ----------- | -------------------- |
| task | graphenix.task-node/v1 |
| finalizer | graphenix.finalizer-node/v1 |
Extension: graph.metadata.extensions["graphenix.executable/v1"]
Design-only: node.layout — stripped via stripDesignOnlyFieldsFromGraph() at compile.
Knowledge scope
| Field | Scope |
| ----- | ----- |
| parameters.taskKnowledge | Task node — forwarded on RunTaskRequest.taskMemory.knowledge |
| parameters.taskPagentiKnowledge | Task node — same scope as taskKnowledge; Pagenti task refs (parallel to jobPagentiKnowledge at graph level) |
| graph.metadata.jobKnowledge | Graph-run — forwarded on RunTaskRequest.jobMemory.knowledge |
| graph.metadata.jobPagentiKnowledge | Graph-run — Pagenti job refs (via graphenix.knowledge/v1 promote path) |
| Any other taskKnowledge / misplaced pagenti path | Rejected (TASK_KNOWLEDGE_GRAPH_SCOPE_FORBIDDEN, TASK_KNOWLEDGE_WRONG_PLACEMENT) |
| Finalizer nodes | No taskKnowledge — finalizers do not invoke AI tasks |
Document root taskKnowledge and jobKnowledge are deprecated — use the paths above.
Job memory defaults
Graph-level declarative context queries live on graph.metadata.jobMemory.context[] (not document root — root jobMemory is deprecated like jobKnowledge).
| Field | Role |
| ----- | ---- |
| graph.metadata.jobMemory.context[] | Default Memorix context queries resolved by the host into runtime.jobMemory.context[] before execute |
Each context entry requires alias, contentType, and filter[]. Duplicate aliases within one graph are rejected. Filters with source: "input" emit a non-fatal warning when inputField is empty (validateAuthoringGraphForPersist).
Normalization strips runtime-populated fields (rows, nested runtime query echoes) from persisted model entries.
{
"graph": {
"metadata": {
"jobMemory": {
"context": [
{
"alias": "peer-subnets",
"contentType": "subnet",
"target": "entity",
"filter": [
{ "key": "tenantId", "source": "input", "inputField": "tenantId" }
],
"limit": 10
}
]
}
}
}
}Host merge convention: runtime.jobMemory.context = [...(resolved graph defaults), ...(resolved job contextQueries)] with job-level entries overriding the same alias.
Job pipeline metadata
Graph-level job identity and pipeline position live on graph.metadata.jobPipeline (not document root — root jobPipeline is deprecated like jobMemory).
| Field | Role |
| ----- | ---- |
| jobTypeId | Logical job classification — many graph implementations may share one job type |
| upstream[] / downstream[] | Job-type dependency refs (cross-entity upstream may include entity + relationKey) |
| context[] | Default linked-entity pulls for work-factory / jobMemory.context at enqueue |
| reprocessing | Operator-facing reprocessing policy keyed by job type |
Identity (do not conflate):
| Field | Meaning | Authored? |
| ----- | ------- | --------- |
| jobId | Per-run correlation id | Runtime only |
| jobTypeId | Logical job classification | graph.metadata.jobPipeline.jobTypeId |
| graphId | Pipeline implementation id | Document id |
Deprecated wire aliases accepted at validation: jobType → jobTypeId, relationshipKey → relationKey. Use resolveGraphJobPipelineContract() for canonical resolver output.
{
"graph": {
"metadata": {
"jobPipeline": {
"jobTypeId": "content-pipeline.analyze",
"label": "Analyze content",
"upstream": [
{ "jobTypeId": "content-pipeline.ingest" }
],
"context": [
{
"relationKey": "sourceRecord",
"targetEntity": "content",
"target": "entity",
"contentTypes": ["article"],
"limit": 5
}
],
"reprocessing": {
"mode": "ttl",
"ttl": { "value": 7, "unit": "days" }
}
}
}
}
}Related packages
| Package | Role |
| ------- | ---- |
| GLOSSARY.md | Phase vocabulary |
| @x12i/graphenix-authoring-analysis | Studio save/import: GraphProjectDocument, purity, model-config merge |
| @x12i/graphenix-task-node-format | Task body validation |
| @x12i/graphenix-executable-profile-format | Phase model profiles |
| @x12i/graphenix-case-format | Case condition DSL |
| @x12i/graphenix-plan-compiler | Compile authoring → plan |
v1.2.0: Model-config authoring APIs (readGraphJobModelDefaults, mergeEffectiveModelConfig, normalizeNodeOverrideForPersist, etc.) are canonical in this package. See model-config authoring semantics.
v1.1.0: Legacy flat-graph migration helpers were removed. Studio envelope validation lives in @x12i/graphenix-authoring-analysis.
