@x12i/graphenix-executable-format 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +512 -341
- package/dist/api.d.ts +13 -35
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +13 -98
- package/dist/api.js.map +1 -1
- package/dist/constants.d.ts +1 -11
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -18
- package/dist/constants.js.map +1 -1
- package/dist/index.js +1 -17
- package/dist/index.js.map +1 -1
- package/dist/test/executable-format.test.js +269 -307
- package/dist/test/executable-format.test.js.map +1 -1
- package/dist/test/executable-plan-v2.test.d.ts +2 -0
- package/dist/test/executable-plan-v2.test.d.ts.map +1 -0
- package/dist/test/executable-plan-v2.test.js +325 -0
- package/dist/test/executable-plan-v2.test.js.map +1 -0
- package/dist/test/execution-trace-v2.test.d.ts +2 -0
- package/dist/test/execution-trace-v2.test.d.ts.map +1 -0
- package/dist/test/execution-trace-v2.test.js +411 -0
- package/dist/test/execution-trace-v2.test.js.map +1 -0
- package/dist/test/phase-1-format.test.d.ts +2 -0
- package/dist/test/phase-1-format.test.d.ts.map +1 -0
- package/dist/test/phase-1-format.test.js +297 -0
- package/dist/test/phase-1-format.test.js.map +1 -0
- package/package.json +69 -56
- package/schema/graphenix-executable-format-1.0.0.schema.json +0 -40
package/README.md
CHANGED
|
@@ -1,341 +1,512 @@
|
|
|
1
|
-
# @x12i/graphenix-executable-format
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```txt
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
)
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
|
312
|
-
|
|
|
313
|
-
| `
|
|
314
|
-
| `
|
|
315
|
-
| `
|
|
316
|
-
| `
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
1
|
+
# @x12i/graphenix-executable-format
|
|
2
|
+
|
|
3
|
+
**Umbrella package** — re-exports the full Graphenix executable lifecycle for prototypes and all-in-one installs.
|
|
4
|
+
|
|
5
|
+
For production, depend on [lifecycle packages](#package-family) directly (design-only clients should not pull in plan-compiler or trace-format).
|
|
6
|
+
|
|
7
|
+
**Canonical vocabulary:** [GLOSSARY.md](../../GLOSSARY.md) · **Format scope:** [FORMAT-SCOPE.md](../../docs/FORMAT-SCOPE.md)
|
|
8
|
+
|
|
9
|
+
**Naming:** `@x12i/*` is the **npm scope only**. JSON documents use `graphenix.*` identifiers and plain node kinds (`task`, `finalizer`) — never `x12i` in saved payloads.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Who should use this
|
|
14
|
+
|
|
15
|
+
| Role | Prefer umbrella? | Prefer direct packages |
|
|
16
|
+
| ---- | :--------------: | ---------------------- |
|
|
17
|
+
| Prototype / spike | **Yes** | |
|
|
18
|
+
| Graph designer / editor | No | `@x12i/graphenix-authoring-format` + `@x12i/graphenix-case-format` |
|
|
19
|
+
| Compiler / execution prep | No | `@x12i/graphenix-plan-compiler` + `@x12i/graphenix-plan-format` |
|
|
20
|
+
| Execution engine | No | `@x12i/graphenix-plan-format` + `@x12i/graphenix-trace-format` |
|
|
21
|
+
| Backend host | No | `@x12i/graphenix-execute-envelope` |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @x12i/graphenix-executable-format @x12i/graphenix-core
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Built on [`@x12i/graphenix-core`](../core), with deterministic model cases validated against [`@x12i/ai-profiles`](https://www.npmjs.com/package/@x12i/ai-profiles).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Full lifecycle (four phases)
|
|
36
|
+
|
|
37
|
+
Reference domain: **`graph:content-pipeline`** — parallel research → content package.
|
|
38
|
+
Fixture: `createContentPipelineReferenceGraph()` from this package (re-exported from authoring-format).
|
|
39
|
+
|
|
40
|
+
```txt
|
|
41
|
+
┌─ DESIGN ─────────────────────────────────────────────────────────────┐
|
|
42
|
+
│ AuthoringGraphDocument + ConceptDocument (shadow, optional) │
|
|
43
|
+
│ validateGraph + validateAuthoringGraph + validateConceptDocument │
|
|
44
|
+
└───────────────────────────────┬──────────────────────────────────────┘
|
|
45
|
+
│ compileExecutablePlan(authoring, runtime)
|
|
46
|
+
┌─ COMPILE ─────────────────────▼──────────────────────────────────────┐
|
|
47
|
+
│ ExecutableGraphPlan │
|
|
48
|
+
│ validateExecutablePlan │
|
|
49
|
+
└───────────────────────────────┬──────────────────────────────────────┘
|
|
50
|
+
│ engine runs executionUnits[] in order
|
|
51
|
+
┌─ EXECUTE + TRACE ─────────────▼──────────────────────────────────────┐
|
|
52
|
+
│ GraphExecutionTrace (append-only) │
|
|
53
|
+
│ validateExecutionTrace │
|
|
54
|
+
└──────────────────────────────────────────────────────────────────────┘
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Phase | Artifact | Validate with | Finalization brief |
|
|
58
|
+
| ----- | -------- | ------------- | ------------------ |
|
|
59
|
+
| Design | `AuthoringGraphDocument` | `validateGraph`, `validateAuthoringGraph` | [GRAPH-FORMAT-FINALIZATION.md](../../docs/GRAPH-FORMAT-FINALIZATION.md) |
|
|
60
|
+
| Design (shadow) | `ConceptDocument` | `validateConceptDocument` | [concept-document.md](../../docs/concept-document.md) |
|
|
61
|
+
| Compile | `ExecutableGraphPlan` | `validateExecutablePlan` | [COMPILE-FORMAT-FINALIZATION.md](../../docs/COMPILE-FORMAT-FINALIZATION.md) |
|
|
62
|
+
| Execute + trace | `GraphExecutionTrace` | `validateExecutionTrace` | [EXECUTE-TRACE-FORMAT-FINALIZATION.md](../../docs/EXECUTE-TRACE-FORMAT-FINALIZATION.md) |
|
|
63
|
+
|
|
64
|
+
**Role guides:** [docs/roles/README.md](../../docs/roles/README.md)
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Package family
|
|
69
|
+
|
|
70
|
+
```txt
|
|
71
|
+
@x12i/graphenix-core
|
|
72
|
+
│
|
|
73
|
+
▼
|
|
74
|
+
@x12i/graphenix-executable-contracts
|
|
75
|
+
│
|
|
76
|
+
├── @x12i/graphenix-case-format
|
|
77
|
+
├── @x12i/graphenix-executable-profile-format
|
|
78
|
+
├── @x12i/graphenix-task-node-format
|
|
79
|
+
├── @x12i/graphenix-authoring-format
|
|
80
|
+
├── @x12i/graphenix-plan-format
|
|
81
|
+
└── @x12i/graphenix-trace-format
|
|
82
|
+
▲
|
|
83
|
+
│
|
|
84
|
+
@x12i/graphenix-plan-compiler
|
|
85
|
+
▲
|
|
86
|
+
│
|
|
87
|
+
@x12i/graphenix-execute-envelope (optional host adapter)
|
|
88
|
+
|
|
89
|
+
@x12i/graphenix-executable-format ← this package (re-exports all above)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
| Package | Phase | README |
|
|
93
|
+
| ------- | ----- | ------ |
|
|
94
|
+
| `@x12i/graphenix-executable-contracts` | Shared types | [executable-contracts/README.md](../executable-contracts/README.md) |
|
|
95
|
+
| `@x12i/graphenix-case-format` | Design | [case-format/README.md](../case-format/README.md) |
|
|
96
|
+
| `@x12i/graphenix-task-node-format` | Design | [task-node-format/README.md](../task-node-format/README.md) |
|
|
97
|
+
| `@x12i/graphenix-executable-profile-format` | Design | [executable-profile-format/README.md](../executable-profile-format/README.md) |
|
|
98
|
+
| `@x12i/graphenix-authoring-format` | Design | [authoring-format/README.md](../authoring-format/README.md) |
|
|
99
|
+
| `@x12i/graphenix-plan-compiler` | Compile | [plan-compiler/README.md](../plan-compiler/README.md) |
|
|
100
|
+
| `@x12i/graphenix-plan-format` | Compile + execute input | [plan-format/README.md](../plan-format/README.md) |
|
|
101
|
+
| `@x12i/graphenix-execute-envelope` | Execute prep | [execute-envelope/README.md](../execute-envelope/README.md) |
|
|
102
|
+
| `@x12i/graphenix-trace-format` | Execute + observability | [trace-format/README.md](../trace-format/README.md) |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## JSON identifiers (format payloads)
|
|
107
|
+
|
|
108
|
+
| Field | Value |
|
|
109
|
+
| ----- | ----- |
|
|
110
|
+
| Task node `kind` | `"task"` |
|
|
111
|
+
| Finalizer node `kind` | `"finalizer"` |
|
|
112
|
+
| Task `parameters.profile` | `"graphenix.task-node/v1"` |
|
|
113
|
+
| Finalizer `parameters.profile` | `"graphenix.finalizer-node/v1"` |
|
|
114
|
+
| Executable extension key | `"graphenix.executable/v1"` |
|
|
115
|
+
| Plan `format` | `"graphenix.executable-plan/v1"` or `v2` |
|
|
116
|
+
| Trace `format` | `"graphenix.execution-trace/v1"` or `v2` |
|
|
117
|
+
| Concept `formatVersion` | `"graphenix.concept/v1"` |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Phase 1 — Design (authoring)
|
|
122
|
+
|
|
123
|
+
### Task run phases (vocabulary)
|
|
124
|
+
|
|
125
|
+
One task node = one `runTask` wave: **prePhase → mainPhase → postPhase**.
|
|
126
|
+
See [GLOSSARY §1–§5](../../GLOSSARY.md).
|
|
127
|
+
|
|
128
|
+
**Explicit rule:** `aiTaskStrategies.pre: "synthesis"` (PRE-phase utility strategy) ≠ `aiTaskProfile.inputSynthesis.enabled` (skill input synthesis profile → plan `pipelinePhase`). Do not use “Synthesis PRE”.
|
|
129
|
+
|
|
130
|
+
### Two-tier validation
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { validateGraph } from "@x12i/graphenix-core";
|
|
134
|
+
import {
|
|
135
|
+
validateAuthoringGraph,
|
|
136
|
+
validateConceptDocument,
|
|
137
|
+
createContentPipelineReferenceGraph
|
|
138
|
+
} from "@x12i/graphenix-executable-format";
|
|
139
|
+
|
|
140
|
+
const doc = createContentPipelineReferenceGraph();
|
|
141
|
+
|
|
142
|
+
validateGraph(doc);
|
|
143
|
+
validateAuthoringGraph(doc);
|
|
144
|
+
|
|
145
|
+
validateConceptDocument({
|
|
146
|
+
formatVersion: "graphenix.concept/v1",
|
|
147
|
+
graphId: doc.id,
|
|
148
|
+
name: doc.name,
|
|
149
|
+
graphConcept: {
|
|
150
|
+
primaryIntentStatement: "Turn a campaign brief into a structured content package."
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Authoring task node (JSON excerpt)
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"id": "node:audience-insights",
|
|
160
|
+
"kind": "task",
|
|
161
|
+
"layout": { "x": 120, "y": 200 },
|
|
162
|
+
"parameters": {
|
|
163
|
+
"profile": "graphenix.task-node/v1",
|
|
164
|
+
"nodeType": "task",
|
|
165
|
+
"skillKey": "professional-answer",
|
|
166
|
+
"taskConfiguration": {
|
|
167
|
+
"executionStrategies": [],
|
|
168
|
+
"aiTaskStrategies": {
|
|
169
|
+
"pre": "synthesis",
|
|
170
|
+
"preInputStrategy": "execution-memory-only"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Phase model profiles (extension)
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
"metadata": {
|
|
181
|
+
"extensions": {
|
|
182
|
+
"graphenix.executable/v1": {
|
|
183
|
+
"profileVersion": "1.0.0",
|
|
184
|
+
"modelConfig": {
|
|
185
|
+
"version": "graph-model-config/v1",
|
|
186
|
+
"cases": [{
|
|
187
|
+
"id": "default",
|
|
188
|
+
"modelConfig": {
|
|
189
|
+
"preActionModel": { "kind": "profileChoice", "key": "cheap/default" },
|
|
190
|
+
"skillModel": { "kind": "profileChoice", "key": "vol/default" },
|
|
191
|
+
"postActionModel": { "kind": "profileChoice", "key": "cheap/default" }
|
|
192
|
+
}
|
|
193
|
+
}]
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Design APIs
|
|
201
|
+
|
|
202
|
+
| API | Purpose |
|
|
203
|
+
| --- | ------- |
|
|
204
|
+
| `validateAuthoringGraph` | Executable profile + full task-node body |
|
|
205
|
+
| `validateConceptDocument` | Studio shadow document |
|
|
206
|
+
| `validateCaseCondition` / `evaluateCaseCondition` | Deterministic `when` DSL |
|
|
207
|
+
| `selectGraphModelCase` / `selectNodeModelCase` | Case preview at design time |
|
|
208
|
+
| `resolveNodeAiPlan` / `explainNodeInheritance` | Preview slot resolution |
|
|
209
|
+
| `normalizeExecutableGraph` | Canonical model config (non-mutating) |
|
|
210
|
+
| `stripDesignOnlyFieldsFromGraph` | Remove `node.layout` before plan embed |
|
|
211
|
+
| `createMinimalExecutableGraph` | One task + finalizer |
|
|
212
|
+
| `createContentPipelineReferenceGraph` | Canonical reference graph |
|
|
213
|
+
| `addTaskNode`, `setGraphModelConfig`, … | CRUD helpers |
|
|
214
|
+
|
|
215
|
+
### Deterministic cases (summary)
|
|
216
|
+
|
|
217
|
+
```txt
|
|
218
|
+
Cases may choose stronger or weaker AI profiles.
|
|
219
|
+
AI may not choose the case.
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Allowed selectors: `runtime.mode`, `runtime.input.*`, `runtime.environment`, `graph.id`, …
|
|
223
|
+
Forbidden: `ai.*`, `node.output.*`, `semanticMatch`, LLM-based conditions.
|
|
224
|
+
|
|
225
|
+
Full DSL: [case-format/README.md](../case-format/README.md).
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Phase 2 — Compile (authoring → plan)
|
|
230
|
+
|
|
231
|
+
### Design → plan mapping
|
|
232
|
+
|
|
233
|
+
| Authoring (design) | Plan execution unit | Run phase |
|
|
234
|
+
| ------------------ | ------------------- | --------- |
|
|
235
|
+
| `aiTaskStrategies.pre` | `externalPreUtility` | prePhase |
|
|
236
|
+
| `skillKey` + plain MAIN | `mainSkill` | mainPhase |
|
|
237
|
+
| `aiTaskProfile.inputSynthesis` | `pipelinePhase` | mainPhase |
|
|
238
|
+
| `aiTaskStrategies.post` | `externalPostUtility` | postPhase |
|
|
239
|
+
| Phase model profiles | `modelSlot` + `modelSelection` on each unit | per phase |
|
|
240
|
+
|
|
241
|
+
Content pipeline reference tasks: PRE synthesis + MAIN only (no POST unless design declares it).
|
|
242
|
+
|
|
243
|
+
### Compile flow
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import {
|
|
247
|
+
createContentPipelineReferenceGraph,
|
|
248
|
+
compileExecutablePlan,
|
|
249
|
+
validateExecutablePlan,
|
|
250
|
+
buildRuntimeObject
|
|
251
|
+
} from "@x12i/graphenix-executable-format";
|
|
252
|
+
|
|
253
|
+
const authoring = createContentPipelineReferenceGraph();
|
|
254
|
+
const runtime = buildRuntimeObject({
|
|
255
|
+
jobId: "job-001",
|
|
256
|
+
mode: "live",
|
|
257
|
+
input: { priority: "normal" }
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const plan = compileExecutablePlan(authoring, runtime, {
|
|
261
|
+
profileRegistry: { package: "@x12i/ai-profiles", version: "3.2.0" },
|
|
262
|
+
environment: "prod"
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const result = validateExecutablePlan(plan);
|
|
266
|
+
if (!result.valid) throw new Error("Invalid plan");
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Internal pipeline:
|
|
270
|
+
|
|
271
|
+
```txt
|
|
272
|
+
validateAuthoringExecutableGraph()
|
|
273
|
+
normalizeExecutableGraph()
|
|
274
|
+
stripDesignOnlyFieldsFromGraph() ← node.layout removed
|
|
275
|
+
assertNormalizedExecutableGraph()
|
|
276
|
+
selectGraphModelCase() → resolveNodeAiPlan() per task node
|
|
277
|
+
buildNodeExecutionUnits() ← PRE / MAIN / POST from aiTaskStrategies
|
|
278
|
+
buildFinalizerPlans()
|
|
279
|
+
validateExecutablePlan() ← recommended before handoff
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Compiled plan (JSON excerpt — v2)
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"format": "graphenix.executable-plan/v2",
|
|
287
|
+
"source": { "graphId": "graph:content-pipeline" },
|
|
288
|
+
"nodePlans": {
|
|
289
|
+
"node:audience-insights": {
|
|
290
|
+
"executionUnits": [
|
|
291
|
+
{
|
|
292
|
+
"unitKind": "externalPreUtility",
|
|
293
|
+
"order": 0,
|
|
294
|
+
"strategyKey": "synthesis",
|
|
295
|
+
"modelSlot": "preActionModel"
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"unitKind": "mainSkill",
|
|
299
|
+
"order": 1,
|
|
300
|
+
"skillKey": "professional-answer",
|
|
301
|
+
"modelSlot": "skillModel"
|
|
302
|
+
}
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Compile APIs
|
|
310
|
+
|
|
311
|
+
| API | Purpose |
|
|
312
|
+
| --- | ------- |
|
|
313
|
+
| `compileExecutablePlan` | Authoring + runtime → plan |
|
|
314
|
+
| `validateExecutablePlan` | Validate v1 or v2 plan |
|
|
315
|
+
| `buildDeterministicCaseContext` | Freeze pre-run context |
|
|
316
|
+
| `buildGraphExecutionRequestFromStudioExecute` | Host adapter: request → `{ plan, runtime }` |
|
|
317
|
+
|
|
318
|
+
Details: [plan-compiler/README.md](../plan-compiler/README.md) · [plan-format/README.md](../plan-format/README.md)
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Phase 3 — Execute (engine)
|
|
323
|
+
|
|
324
|
+
The engine consumes **only** `{ plan, runtime }`. It never reads authoring graphs.
|
|
325
|
+
|
|
326
|
+
### Execution order
|
|
327
|
+
|
|
328
|
+
For each task node in topological order:
|
|
329
|
+
|
|
330
|
+
1. `validateExecutablePlan(plan)` on receipt
|
|
331
|
+
2. PRE-phase units (`externalPreUtility`) → MAIN (`mainSkill`, `pipelinePhase`, …) → POST if present
|
|
332
|
+
3. Each unit uses frozen `modelSelection` from the plan — no case re-selection at runtime
|
|
333
|
+
|
|
334
|
+
### Execute APIs (from this package)
|
|
335
|
+
|
|
336
|
+
| API | Package origin |
|
|
337
|
+
| --- | -------------- |
|
|
338
|
+
| `validateExecutablePlan` | plan-format |
|
|
339
|
+
| `createExecutionTrace` | trace-format |
|
|
340
|
+
| `appendExecutionEvent` | trace-format |
|
|
341
|
+
|
|
342
|
+
Details: [docs/roles/execution-engine.md](../../docs/roles/execution-engine.md)
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Phase 4 — Trace (evidence)
|
|
347
|
+
|
|
348
|
+
Traces are **append-only** and bound to `planHash`.
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
import {
|
|
352
|
+
createExecutionTrace,
|
|
353
|
+
appendExecutionEvent,
|
|
354
|
+
validateExecutionTrace,
|
|
355
|
+
deriveGraphStatus,
|
|
356
|
+
summarizeExecutionTrace
|
|
357
|
+
} from "@x12i/graphenix-executable-format";
|
|
358
|
+
|
|
359
|
+
const trace = createExecutionTrace(plan, runtime);
|
|
360
|
+
|
|
361
|
+
appendExecutionEvent(trace, {
|
|
362
|
+
id: "evt:1",
|
|
363
|
+
ts: new Date().toISOString(),
|
|
364
|
+
level: "info",
|
|
365
|
+
type: "graph.started",
|
|
366
|
+
message: "Graph execution started."
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
appendExecutionEvent(trace, {
|
|
370
|
+
id: "evt:2",
|
|
371
|
+
ts: new Date().toISOString(),
|
|
372
|
+
level: "info",
|
|
373
|
+
type: "node.started",
|
|
374
|
+
nodeId: "node:audience-insights"
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
appendExecutionEvent(trace, {
|
|
378
|
+
id: "evt:3",
|
|
379
|
+
ts: new Date().toISOString(),
|
|
380
|
+
level: "info",
|
|
381
|
+
type: "unit.started",
|
|
382
|
+
nodeId: "node:audience-insights",
|
|
383
|
+
unitId: "unit:node:audience-insights:pre:0",
|
|
384
|
+
unitKind: "externalPreUtility"
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
validateExecutionTrace(trace, plan.nodePlans);
|
|
388
|
+
const status = deriveGraphStatus(trace);
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Trace header (JSON excerpt)
|
|
392
|
+
|
|
393
|
+
```json
|
|
394
|
+
{
|
|
395
|
+
"format": "graphenix.execution-trace/v1",
|
|
396
|
+
"traceId": "trace:job-001",
|
|
397
|
+
"jobId": "job-001",
|
|
398
|
+
"source": { "graphId": "graph:content-pipeline", "graphHash": "sha256:…" },
|
|
399
|
+
"plan": { "planId": "plan:abc123", "planHash": "sha256:…" },
|
|
400
|
+
"events": []
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Details: [trace-format/README.md](../trace-format/README.md) · [docs/roles/observability.md](../../docs/roles/observability.md)
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Validation tiers (summary)
|
|
409
|
+
|
|
410
|
+
| When | Call |
|
|
411
|
+
| ---- | ---- |
|
|
412
|
+
| Authoring save | `validateGraph` + `validateAuthoringGraph` |
|
|
413
|
+
| Concept save | `validateConceptDocument` |
|
|
414
|
+
| After compile | `validateExecutablePlan` |
|
|
415
|
+
| After run | `validateExecutionTrace(trace, plan.nodePlans)` |
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## End-to-end example (umbrella import)
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
import { validateGraph } from "@x12i/graphenix-core";
|
|
423
|
+
import {
|
|
424
|
+
createContentPipelineReferenceGraph,
|
|
425
|
+
validateAuthoringGraph,
|
|
426
|
+
compileExecutablePlan,
|
|
427
|
+
validateExecutablePlan,
|
|
428
|
+
buildRuntimeObject,
|
|
429
|
+
createExecutionTrace,
|
|
430
|
+
appendExecutionEvent,
|
|
431
|
+
validateExecutionTrace
|
|
432
|
+
} from "@x12i/graphenix-executable-format";
|
|
433
|
+
|
|
434
|
+
// Design
|
|
435
|
+
const authoring = createContentPipelineReferenceGraph();
|
|
436
|
+
validateGraph(authoring);
|
|
437
|
+
validateAuthoringGraph(authoring);
|
|
438
|
+
|
|
439
|
+
// Compile
|
|
440
|
+
const runtime = buildRuntimeObject({ jobId: "job-001", mode: "live", input: {} });
|
|
441
|
+
const plan = compileExecutablePlan(authoring, runtime);
|
|
442
|
+
validateExecutablePlan(plan);
|
|
443
|
+
|
|
444
|
+
// Execute + trace (engine loop abbreviated)
|
|
445
|
+
const trace = createExecutionTrace(plan, runtime);
|
|
446
|
+
appendExecutionEvent(trace, {
|
|
447
|
+
id: "evt:1",
|
|
448
|
+
ts: new Date().toISOString(),
|
|
449
|
+
level: "info",
|
|
450
|
+
type: "graph.completed",
|
|
451
|
+
message: "Done."
|
|
452
|
+
});
|
|
453
|
+
validateExecutionTrace(trace, plan.nodePlans);
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## Profile choice format
|
|
459
|
+
|
|
460
|
+
```json
|
|
461
|
+
{ "kind": "profileChoice", "key": "vol/default" }
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Examples: `cheap/default`, `vol/default`, `vol/pro`, `deep/openai_deep`.
|
|
465
|
+
Rejected: bare aliases, `kind: "profile"`, vendor slugs as profileChoice keys.
|
|
466
|
+
|
|
467
|
+
`profileChoice` resolves at compile/plan time via `@x12i/ai-profiles` — not during normalization.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Model inheritance and fallback
|
|
472
|
+
|
|
473
|
+
- Graph-level `modelConfig` is **required** with full triplet per case (`preActionModel`, `skillModel`, `postActionModel`).
|
|
474
|
+
- Node overrides may be partial when `inherit: true`.
|
|
475
|
+
- Fallback is **same-slot only** on the selected graph case — never cross-slot or runtime defaults.
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Node kinds
|
|
480
|
+
|
|
481
|
+
| `kind` | `parameters.profile` | Purpose |
|
|
482
|
+
| ------ | -------------------- | ------- |
|
|
483
|
+
| `task` | `graphenix.task-node/v1` | Skill + phase utility strategies |
|
|
484
|
+
| `finalizer` | `graphenix.finalizer-node/v1` | Graph output (`finalizerType`: `aggregate`, `compose`, …) |
|
|
485
|
+
|
|
486
|
+
Design-only: `node.layout` — stripped at compile, never on plan.
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## Development
|
|
491
|
+
|
|
492
|
+
From monorepo root:
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
npm install
|
|
496
|
+
npm run build --workspace=@x12i/graphenix-executable-format
|
|
497
|
+
npm run test --workspace=@x12i/graphenix-executable-format
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## Schema
|
|
501
|
+
|
|
502
|
+
Profile JSON Schema fragment: `schema/graphenix-executable-format-1.0.0.schema.json` (structural subset; full semantics enforced by TypeScript validators).
|
|
503
|
+
|
|
504
|
+
## Further reading
|
|
505
|
+
|
|
506
|
+
| Doc | Topic |
|
|
507
|
+
| --- | ----- |
|
|
508
|
+
| [GLOSSARY.md](../../GLOSSARY.md) | Phase vocabulary |
|
|
509
|
+
| [FORMAT-SCOPE.md](../../docs/FORMAT-SCOPE.md) | Compliance + strict profiles |
|
|
510
|
+
| [NAMING.md](../../docs/NAMING.md) | npm `@x12i/*` vs JSON `graphenix.*` |
|
|
511
|
+
| [PUBLISHING.md](../../PUBLISHING.md) | npm publish order |
|
|
512
|
+
| [docs/IMPLEMENTATION-REPORT.md](./docs/IMPLEMENTATION-REPORT.md) | Acceptance test matrix |
|