@supernovae-st/nika 0.120.2 → 0.120.3

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/docs/http-api.md CHANGED
@@ -15,6 +15,7 @@ Any other non-2xx body is discarded and reported as a redacted
15
15
  | `GET /v1/openapi.json` | generation only | authenticated OpenAPI 3.1 document |
16
16
  | `GET /v1/workflows` | `listWorkflows()` | contained relative workflow names |
17
17
  | `GET /v1/workflows/{name}` | `workflow(name)` | path-free metadata, never source bytes |
18
+ | `POST /v1/compile` | `compile()` | capability-gated stateless source authoring; 200 ready/incomplete/refused, no job |
18
19
  | `POST /v1/check` | `check()` | validates a served name or immutable snapshot bytes without a job |
19
20
  | `POST /v1/jobs` | `run()` | admits a served name or exact snapshot bytes with an idempotency key |
20
21
  | `GET /v1/jobs/{id}` | internal settlement | durable job identity, outputs, receipt, settlement, or redacted error |
@@ -58,6 +59,29 @@ engine. Prefix a local file with `./` to capture and submit its snapshot.
58
59
  A successful by-name check returns `clean: true` and the compact resident
59
60
  acknowledgement; no local check report or exit code is fabricated.
60
61
 
62
+ ## Compile foundation
63
+
64
+ Serve must advertise `compile` in `/health`. This route was added in engine
65
+ commit `4334e58bddf539a6253f448eb05d562b6919f2b7`, after release 0.120.2, and
66
+ first published in release 0.120.3.
67
+ The bundled OpenAPI and generated types preserve that exact producer contract. The SDK then posts a v1 create
68
+ intent or inline edit source to `/v1/compile`, with bearer authentication and
69
+ JSON content type. A string change becomes `{text: change}`; a structured change
70
+ preserves `{set_constant: {name, value}}`. Literal answers retain their JSON
71
+ types. There is no path, destination, idempotency key or local fallback.
72
+
73
+ Every core outcome uses HTTP 200. `incomplete` and `refused` remain reviewable
74
+ data; non-200 error envelopes raise `NikaOperationError` with the HTTP status
75
+ and engine code. Bad versions, malformed outcomes, overflow, cancellation and
76
+ timeout fail typed. The response is bounded by the smaller of
77
+ `machineBufferBytes` and 8 MiB. Compile's timeout covers health negotiation,
78
+ response headers and the complete body.
79
+
80
+ The shared outcome contains candidate source, questions, diagnostics, requested
81
+ boundary, source-only Check preview and provenance. It carries no process exit
82
+ code or materialized destination. A candidate and its requested boundary grant
83
+ nothing: execution needs a separate caller decision and normal `run` admission.
84
+
61
85
  ## Settlement
62
86
 
63
87
  The terminal `execution.settled` frame and the durable job nest the run's
package/docs/testing.md CHANGED
@@ -179,3 +179,40 @@ cleanup before emitting green evidence. The corpus runs in a fresh project and
179
179
  HOME. Changed fixtures require new measured results: old committed ledgers
180
180
  remain historical observations until a successful exact-version replay replaces
181
181
  them. Never relabel an old binary or weaken the replay comparison.
182
+
183
+ ## Compile foundation parity
184
+
185
+ Hermetic compile cases run with `npm test`, including strict request literals,
186
+ capability/version refusal, native exit and signal laws, temporary-file failure
187
+ cleanup, authenticated HTTP responses and cancellation. `npm run check:package-surface`
188
+ checks both packed module faces and their public TypeScript contracts.
189
+
190
+ For a frozen engine that advertises `compile` on both native and Serve doors:
191
+
192
+ ```sh
193
+ NIKA_BIN=/absolute/path/to/frozen/nika \
194
+ NIKA_COMPILE_PARITY_REPORT=/absolute/path/to/compile-parity.json \
195
+ node scripts/run-compile-parity-e2e.mjs
196
+ ```
197
+
198
+ This installs the SDK tarball into an isolated consumer and compares the full
199
+ common authoring outcomes across native/HTTP and ESM/CommonJS. It checks literal
200
+ round trips, incomplete questions, refused expression islands, invalid bases,
201
+ authentication, no project-file changes and no created jobs. HTTP is given a
202
+ nonexistent local engine path, proving that it cannot use a fallback. The report
203
+ records binary and package hashes and is green only after owned-process cleanup.
204
+ A source binary containing engine commit
205
+ `4334e58bddf539a6253f448eb05d562b6919f2b7` is required for both doors.
206
+ Released engine 0.120.3 supports native compile and its Serve advertises HTTP
207
+ compile; 0.120.2 and older predate the route. This is a foundation test, not general intent authoring
208
+ or execution admission qualification.
209
+
210
+ The [2026-09-19 source-build receipt](../evidence/compile-4334e58b-20260919.json)
211
+ records 14 cases across both doors and both module systems at that producer,
212
+ with exact outcome parity and no resident-state or project-file mutation. Its
213
+ engine is a clean source build predating the published v0.120.3 binary; its SDK
214
+ tarball is the unreleased PR candidate. The hashes identify those tested bytes.
215
+
216
+ Compile source-build receipts live outside the published package, so recording
217
+ a tarball hash does not change the bytes it identifies. They do not participate
218
+ in the released-engine behavioral ledgers.
package/openapi.json CHANGED
@@ -61,6 +61,246 @@
61
61
  ],
62
62
  "type": "object"
63
63
  },
64
+ "CompileOutcome": {
65
+ "description": "The engine-owned machine document of one authoring result — the document `nika compile --json` prints, without the CLI-only `written`. No field grants authority, writes or executes source.",
66
+ "properties": {
67
+ "candidate": {
68
+ "description": "Ordinary `.nika` source; may still be incomplete",
69
+ "type": [
70
+ "string",
71
+ "null"
72
+ ]
73
+ },
74
+ "check_preview": {
75
+ "description": "The engine's pure Check report over the source only. No child file, skill, credential probe, access plan or admission was evaluated",
76
+ "properties": {
77
+ "report": {
78
+ "additionalProperties": true,
79
+ "type": "object"
80
+ },
81
+ "scope": {
82
+ "const": "sourceOnly",
83
+ "type": "string"
84
+ }
85
+ },
86
+ "required": [
87
+ "scope",
88
+ "report"
89
+ ],
90
+ "type": [
91
+ "object",
92
+ "null"
93
+ ]
94
+ },
95
+ "compile_version": {
96
+ "const": 1,
97
+ "type": "integer"
98
+ },
99
+ "diagnostics": {
100
+ "items": {
101
+ "properties": {
102
+ "kind": {
103
+ "enum": [
104
+ "applied",
105
+ "missed",
106
+ "unknown",
107
+ "requiresHuman",
108
+ "refused"
109
+ ],
110
+ "type": "string"
111
+ },
112
+ "message": {
113
+ "description": "For a reader; never parsed to recover compiler state",
114
+ "type": "string"
115
+ },
116
+ "target": {
117
+ "type": "string"
118
+ }
119
+ },
120
+ "required": [
121
+ "kind",
122
+ "target",
123
+ "message"
124
+ ],
125
+ "type": "object"
126
+ },
127
+ "type": "array"
128
+ },
129
+ "provenance": {
130
+ "description": "Reproduction metadata; neither program identity nor run evidence",
131
+ "properties": {
132
+ "cognition": {
133
+ "const": "deterministicOnly",
134
+ "type": "string"
135
+ },
136
+ "compiler_version": {
137
+ "type": "string"
138
+ },
139
+ "skeleton": {
140
+ "type": [
141
+ "string",
142
+ "null"
143
+ ]
144
+ },
145
+ "spec_pin": {
146
+ "type": "string"
147
+ }
148
+ },
149
+ "required": [
150
+ "compiler_version",
151
+ "spec_pin",
152
+ "skeleton",
153
+ "cognition"
154
+ ],
155
+ "type": "object"
156
+ },
157
+ "questions": {
158
+ "items": {
159
+ "properties": {
160
+ "key": {
161
+ "description": "Stable semantic hole path such as `const.request`, never a session id",
162
+ "type": "string"
163
+ },
164
+ "label": {
165
+ "type": "string"
166
+ },
167
+ "mandatory": {
168
+ "type": "boolean"
169
+ },
170
+ "type": {
171
+ "enum": [
172
+ "text",
173
+ "literal"
174
+ ],
175
+ "type": "string"
176
+ },
177
+ "why": {
178
+ "type": "string"
179
+ }
180
+ },
181
+ "required": [
182
+ "key",
183
+ "label",
184
+ "type",
185
+ "why",
186
+ "mandatory"
187
+ ],
188
+ "type": "object"
189
+ },
190
+ "type": "array"
191
+ },
192
+ "requested_boundary": {
193
+ "additionalProperties": true,
194
+ "description": "The candidate's requested permits, derived by Check. Requested, never granted",
195
+ "type": [
196
+ "object",
197
+ "null"
198
+ ]
199
+ },
200
+ "status": {
201
+ "description": "Completeness of authoring, never permission to execute",
202
+ "enum": [
203
+ "ready",
204
+ "incomplete",
205
+ "refused"
206
+ ],
207
+ "type": "string"
208
+ }
209
+ },
210
+ "required": [
211
+ "compile_version",
212
+ "status",
213
+ "candidate",
214
+ "questions",
215
+ "diagnostics",
216
+ "requested_boundary",
217
+ "check_preview",
218
+ "provenance"
219
+ ],
220
+ "type": "object"
221
+ },
222
+ "CompileRequest": {
223
+ "additionalProperties": false,
224
+ "description": "Generation 1 of the compile request. The encoded body is limited to 1048576 bytes (or the listener's lower ceiling). Byte bounds below are UTF-8 bytes. Unknown fields, a present null, duplicate keys (including inside `answers`) and positional arrays are refused. No field names a host path: an EDIT base travels inline in `source`.",
225
+ "properties": {
226
+ "answers": {
227
+ "additionalProperties": true,
228
+ "description": "Question key → one JSON literal with its type preserved, judged exactly as sent (at most 65536 bytes each)",
229
+ "maxProperties": 64,
230
+ "propertyNames": {
231
+ "maxLength": 256
232
+ },
233
+ "type": "object"
234
+ },
235
+ "change": {
236
+ "additionalProperties": false,
237
+ "maxProperties": 1,
238
+ "minProperties": 1,
239
+ "properties": {
240
+ "set_constant": {
241
+ "additionalProperties": false,
242
+ "properties": {
243
+ "name": {
244
+ "description": "Bare constant name, not a path",
245
+ "maxLength": 128,
246
+ "type": "string"
247
+ },
248
+ "value": {
249
+ "description": "One JSON literal, judged exactly as sent (at most 65536 bytes)"
250
+ }
251
+ },
252
+ "required": [
253
+ "name",
254
+ "value"
255
+ ],
256
+ "type": "object"
257
+ },
258
+ "text": {
259
+ "description": "`Set const.NAME to JSON_LITERAL`, or `Set const.NAME` answered through `answers`",
260
+ "maxLength": 4096,
261
+ "type": "string"
262
+ }
263
+ },
264
+ "type": "object"
265
+ },
266
+ "cognition": {
267
+ "const": "deterministicOnly",
268
+ "description": "The only authoring cognition of this build. Any other value is refused; no authoring model is contacted",
269
+ "type": "string"
270
+ },
271
+ "compile_version": {
272
+ "const": 1,
273
+ "type": "integer"
274
+ },
275
+ "intent": {
276
+ "maxLength": 4096,
277
+ "type": "string"
278
+ },
279
+ "mode": {
280
+ "description": "create requires `intent` and forbids `source`/`change`; edit requires `source` and `change` and forbids `intent`",
281
+ "enum": [
282
+ "create",
283
+ "edit"
284
+ ],
285
+ "type": "string"
286
+ },
287
+ "source": {
288
+ "description": "Accepted `.nika` source, inline. The caller owns source selection, revision checks and materialization",
289
+ "maxLength": 524288,
290
+ "type": "string"
291
+ },
292
+ "workflow_id": {
293
+ "description": "Names a created workflow. On edit the core refuses it as data: an edit cannot rename its accepted base",
294
+ "maxLength": 128,
295
+ "type": "string"
296
+ }
297
+ },
298
+ "required": [
299
+ "compile_version",
300
+ "mode"
301
+ ],
302
+ "type": "object"
303
+ },
64
304
  "Error": {
65
305
  "additionalProperties": false,
66
306
  "properties": {
@@ -1012,9 +1252,9 @@
1012
1252
  }
1013
1253
  },
1014
1254
  "info": {
1015
- "description": "Authenticated loopback remote execution and declarative schedules. Artifacts, schedule list/delete/trigger/backfill, /v1/arm, and POST /v1/run are absent.",
1255
+ "description": "Authenticated loopback remote execution, declarative schedules and stateless source-only authoring (POST /v1/compile never runs, admits or writes). Artifacts, schedule list/delete/trigger/backfill, /v1/arm, and POST /v1/run are absent.",
1016
1256
  "title": "nika serve",
1017
- "version": "0.120.2"
1257
+ "version": "0.120.3"
1018
1258
  },
1019
1259
  "openapi": "3.1.0",
1020
1260
  "paths": {
@@ -1121,6 +1361,104 @@
1121
1361
  "summary": "Judge a workflow without creating a job — by served name, or as immutable snapshot bytes"
1122
1362
  }
1123
1363
  },
1364
+ "/v1/compile": {
1365
+ "post": {
1366
+ "description": "The HTTP transport of the same Compile core as `nika compile`. Foundation scope: CREATE resolves an exact embedded skeleton name (or `hello`), EDIT changes one existing constant, answers are explicit JSON literals; any other intent is answered `incomplete` with no substitute workflow. Creates no job, run, approval or trace, writes no file, contacts no provider: ambient keys are never consent. `check_preview` is a REVIEW of the source only, never admission: POST /v1/jobs judges a candidate again. Questions carry stable keys; answering is a new request, not a session.",
1367
+ "requestBody": {
1368
+ "content": {
1369
+ "application/json": {
1370
+ "schema": {
1371
+ "$ref": "#/components/schemas/CompileRequest"
1372
+ }
1373
+ }
1374
+ },
1375
+ "required": true
1376
+ },
1377
+ "responses": {
1378
+ "200": {
1379
+ "content": {
1380
+ "application/json": {
1381
+ "schema": {
1382
+ "$ref": "#/components/schemas/CompileOutcome"
1383
+ }
1384
+ }
1385
+ },
1386
+ "description": "Authoring outcome — ready, incomplete and refused are all data"
1387
+ },
1388
+ "401": {
1389
+ "content": {
1390
+ "application/json": {
1391
+ "schema": {
1392
+ "$ref": "#/components/schemas/Error"
1393
+ }
1394
+ }
1395
+ },
1396
+ "description": "Error envelope"
1397
+ },
1398
+ "408": {
1399
+ "content": {
1400
+ "application/json": {
1401
+ "schema": {
1402
+ "$ref": "#/components/schemas/Error"
1403
+ }
1404
+ }
1405
+ },
1406
+ "description": "Request deadline"
1407
+ },
1408
+ "413": {
1409
+ "content": {
1410
+ "application/json": {
1411
+ "schema": {
1412
+ "$ref": "#/components/schemas/Error"
1413
+ }
1414
+ }
1415
+ },
1416
+ "description": "Encoded body above the compile ceiling"
1417
+ },
1418
+ "415": {
1419
+ "content": {
1420
+ "application/json": {
1421
+ "schema": {
1422
+ "$ref": "#/components/schemas/Error"
1423
+ }
1424
+ }
1425
+ },
1426
+ "description": "Content-Type or Content-Encoding refused"
1427
+ },
1428
+ "422": {
1429
+ "content": {
1430
+ "application/json": {
1431
+ "schema": {
1432
+ "$ref": "#/components/schemas/Error"
1433
+ }
1434
+ }
1435
+ },
1436
+ "description": "malformed_compile_request · compile_version_unsupported · compile_mode_unsupported · compile_cognition_unsupported · compile_limit"
1437
+ },
1438
+ "500": {
1439
+ "content": {
1440
+ "application/json": {
1441
+ "schema": {
1442
+ "$ref": "#/components/schemas/Error"
1443
+ }
1444
+ }
1445
+ },
1446
+ "description": "Compiler machinery failure; nothing is echoed"
1447
+ },
1448
+ "503": {
1449
+ "content": {
1450
+ "application/json": {
1451
+ "schema": {
1452
+ "$ref": "#/components/schemas/Error"
1453
+ }
1454
+ }
1455
+ },
1456
+ "description": "compile_busy — every compile slot is in use"
1457
+ }
1458
+ },
1459
+ "summary": "Author a candidate workflow without running it (stateless · source-only)"
1460
+ }
1461
+ },
1124
1462
  "/v1/jobs": {
1125
1463
  "post": {
1126
1464
  "description": "Two forms, one admission (ADR-131). `{\"workflow\": \"<name>\"}` names a workflow the served registry lists: the resident captures its world through ExecutionService, exactly as a schedule does. Optional `access` on that form is CLI `--access` for this job only. A snapshot body is the world `nika check <file> --json --sdk-snapshot` prints, decoded and readmitted through the same ExecutionService; its digests are optional caller-supplied integrity digests (a content assertion, never a signature). Snapshot jobs inherit the resident's unpinned plan. The server never interprets a caller filesystem path. Idempotency binds to the exact request bytes.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supernovae-st/nika",
3
- "version": "0.120.2",
3
+ "version": "0.120.3",
4
4
  "description": "One TypeScript SDK for local and remote Nika execution",
5
5
  "repository": {
6
6
  "type": "git",
@@ -69,10 +69,10 @@
69
69
  "prepublishOnly": "npm run build"
70
70
  },
71
71
  "optionalDependencies": {
72
- "@supernovae-st/nika-darwin-arm64": "0.120.2",
73
- "@supernovae-st/nika-darwin-x64": "0.120.2",
74
- "@supernovae-st/nika-linux-arm64": "0.120.2",
75
- "@supernovae-st/nika-linux-x64": "0.120.2"
72
+ "@supernovae-st/nika-darwin-arm64": "0.120.3",
73
+ "@supernovae-st/nika-darwin-x64": "0.120.3",
74
+ "@supernovae-st/nika-linux-arm64": "0.120.3",
75
+ "@supernovae-st/nika-linux-x64": "0.120.3"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@types/node": "^26.4.1",
@@ -87,7 +87,7 @@
87
87
  "license": "Apache-2.0",
88
88
  "mcpName": "io.github.supernovae-st/nika",
89
89
  "nikaRelease": {
90
- "preparedCommit": "ddf7522cac40e9606a7d94e83af74234e066a96e",
91
- "version": "0.120.2"
90
+ "preparedCommit": "4dcda1bacfc1cc77c87066784120151a67202033",
91
+ "version": "0.120.3"
92
92
  }
93
93
  }