@aiwg/cli 2026.9.0 → 2026.9.2

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.
Files changed (107) hide show
  1. package/agentic/code/providers/capability-matrix.yaml +41 -0
  2. package/agentic/code/providers/model-capabilities.v1.json +11 -0
  3. package/agentic/code/providers/model-catalog.v1.json +8 -0
  4. package/agentic/code/providers/pi/aiwg-bridge.ts +26 -0
  5. package/bin/aiwg.mjs +15 -3
  6. package/dist/src/api/index.d.ts +3 -0
  7. package/dist/src/api/index.js +3 -0
  8. package/dist/src/auth/credential-store.js +6 -0
  9. package/dist/src/channel/manager.mjs +2 -2
  10. package/dist/src/cli/handlers/dataset.js +186 -0
  11. package/dist/src/cli/handlers/help.js +2 -1
  12. package/dist/src/cli/handlers/index.js +5 -1
  13. package/dist/src/cli/handlers/init.js +1 -0
  14. package/dist/src/cli/handlers/output-mode.js +18 -1
  15. package/dist/src/cli/handlers/run.js +11 -3
  16. package/dist/src/cli/handlers/schema.js +221 -0
  17. package/dist/src/cli/handlers/sessions.js +30 -12
  18. package/dist/src/cli/handlers/steward.js +11 -1
  19. package/dist/src/cli/handlers/use.js +6 -2
  20. package/dist/src/cli/hooks/builtin/activity-log-hook.js +6 -0
  21. package/dist/src/cli/router.js +1 -1
  22. package/dist/src/cli/scope-resolver.js +22 -0
  23. package/dist/src/dataset/adapter-sdk.d.ts +41 -0
  24. package/dist/src/dataset/adapter-sdk.js +147 -0
  25. package/dist/src/dataset/adapter-types.d.ts +179 -0
  26. package/dist/src/dataset/adapter-types.js +2 -0
  27. package/dist/src/dataset/adapters.d.ts +104 -0
  28. package/dist/src/dataset/adapters.js +518 -0
  29. package/dist/src/dataset/conformance-types.d.ts +84 -0
  30. package/dist/src/dataset/conformance-types.js +3 -0
  31. package/dist/src/dataset/conformance.d.ts +13 -0
  32. package/dist/src/dataset/conformance.js +90 -0
  33. package/dist/src/dataset/contracts.d.ts +17 -0
  34. package/dist/src/dataset/contracts.js +236 -0
  35. package/dist/src/dataset/file-orchestration-repository.d.ts +19 -0
  36. package/dist/src/dataset/file-orchestration-repository.js +68 -0
  37. package/dist/src/dataset/fortemi-execution-bridge.d.ts +33 -0
  38. package/dist/src/dataset/fortemi-execution-bridge.js +35 -0
  39. package/dist/src/dataset/index.d.ts +21 -0
  40. package/dist/src/dataset/index.js +21 -0
  41. package/dist/src/dataset/ledger-types.d.ts +141 -0
  42. package/dist/src/dataset/ledger-types.js +2 -0
  43. package/dist/src/dataset/ledger.d.ts +27 -0
  44. package/dist/src/dataset/ledger.js +100 -0
  45. package/dist/src/dataset/local-execution-backend.d.ts +10 -0
  46. package/dist/src/dataset/local-execution-backend.js +32 -0
  47. package/dist/src/dataset/orchestration-repository.d.ts +29 -0
  48. package/dist/src/dataset/orchestration-repository.js +34 -0
  49. package/dist/src/dataset/orchestration-service.d.ts +56 -0
  50. package/dist/src/dataset/orchestration-service.js +466 -0
  51. package/dist/src/dataset/orchestration-types.d.ts +83 -0
  52. package/dist/src/dataset/orchestration-types.js +2 -0
  53. package/dist/src/dataset/presentation.d.ts +3 -0
  54. package/dist/src/dataset/presentation.js +8 -0
  55. package/dist/src/dataset/projections.d.ts +42 -0
  56. package/dist/src/dataset/projections.js +192 -0
  57. package/dist/src/dataset/schema-governance.d.ts +71 -0
  58. package/dist/src/dataset/schema-governance.js +135 -0
  59. package/dist/src/dataset/standards-types.d.ts +66 -0
  60. package/dist/src/dataset/standards-types.js +10 -0
  61. package/dist/src/dataset/standards.d.ts +13 -0
  62. package/dist/src/dataset/standards.js +291 -0
  63. package/dist/src/dataset/types.d.ts +258 -0
  64. package/dist/src/dataset/types.js +2 -0
  65. package/dist/src/extensions/commands/definitions.js +27 -1
  66. package/dist/src/installation/manager.mjs +5 -1
  67. package/dist/src/models/model-capabilities.v1.json +11 -0
  68. package/dist/src/models/model-catalog.v1.json +8 -0
  69. package/dist/src/models/model-discovery.js +32 -0
  70. package/dist/src/models/provider-policy.js +3 -2
  71. package/dist/src/output-modes/index.js +4 -0
  72. package/dist/src/output-modes/registry.js +68 -24
  73. package/dist/src/output-modes/runtime.js +10 -8
  74. package/dist/src/plugin/skill-command-translator.js +1 -0
  75. package/dist/src/providers/capability-matrix.yaml +41 -0
  76. package/dist/src/providers/provider-definitions.js +72 -0
  77. package/dist/src/providers/provider-inventory.js +1 -0
  78. package/dist/src/schema/catalog.js +234 -0
  79. package/dist/src/schema/compatibility.js +42 -0
  80. package/dist/src/schema/diagnostics.js +36 -0
  81. package/dist/src/schema/index.js +8 -0
  82. package/dist/src/schema/policy.js +58 -0
  83. package/dist/src/schema/resolver.js +76 -0
  84. package/dist/src/schema/types.js +2 -0
  85. package/dist/src/schema/validator.js +82 -0
  86. package/dist/src/sessions/adapters/pi.js +141 -0
  87. package/dist/src/sessions/contracts.js +1 -1
  88. package/dist/src/sessions/index.js +1 -0
  89. package/dist/src/sessions/workspace-discovery.js +10 -0
  90. package/dist/src/storage/backends/fortemi.js +6 -0
  91. package/dist/src/storage/config.js +18 -4
  92. package/dist/src/storage/fortemi-qualification.js +106 -0
  93. package/dist/src/storage/index.js +1 -0
  94. package/dist/src/storage/types.js +1 -1
  95. package/package.json +3 -1
  96. package/schemas/dataset/conformance-manifest.v1.schema.json +35 -0
  97. package/schemas/dataset/conformance-receipt.v1.schema.json +22 -0
  98. package/schemas/dataset/dataset-contracts.v1.schema.json +117 -0
  99. package/schemas/dataset/dataset-deprecations.v1.schema.json +37 -0
  100. package/schemas/dataset/dataset-schema-governance.v1.schema.json +92 -0
  101. package/schemas/dataset/dataset-standards-exchange.v1.schema.json +59 -0
  102. package/schemas/dataset/profiles/openlineage-1.0.0.schema.json +15 -0
  103. package/schemas/dataset/profiles/prov-json-20130430.schema.json +12 -0
  104. package/schemas/dataset/run-ledger.v1.schema.json +39 -0
  105. package/schemas/dataset/source-adapter.v1.schema.json +112 -0
  106. package/tools/agents/deploy-agents.mjs +9 -3
  107. package/tools/agents/providers/pi.mjs +176 -0
@@ -0,0 +1,466 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { computeProcessingPlanDigest, computeRunReceiptDigest, datasetDigest, DatasetContractError, negotiateDatasetCapabilities, verifyProcessingPlanDigest, } from "./contracts.js";
3
+ import { DEFAULT_ADAPTER_LIMITS, request, sha256Digest, } from "./adapter-sdk.js";
4
+ import { DATASET_CONTRACT_VERSION, } from "./types.js";
5
+ import { DATASET_ORCHESTRATION_VERSION, } from "./orchestration-types.js";
6
+ export class DatasetOrchestrationError extends Error {
7
+ code;
8
+ boundary;
9
+ retryable;
10
+ constructor(code, message, boundary = "input", retryable = false) {
11
+ super(message);
12
+ this.code = code;
13
+ this.boundary = boundary;
14
+ this.retryable = retryable;
15
+ this.name = "DatasetOrchestrationError";
16
+ }
17
+ }
18
+ const ok = (action, data, extra = {}) => ({
19
+ schema: DATASET_ORCHESTRATION_VERSION,
20
+ action,
21
+ ok: true,
22
+ data,
23
+ diagnostics: [],
24
+ ...extra,
25
+ });
26
+ const fail = (action, e) => {
27
+ const x = e instanceof DatasetOrchestrationError
28
+ ? e
29
+ : e instanceof DatasetContractError
30
+ ? new DatasetOrchestrationError(e.code, e.message, "plan")
31
+ : new DatasetOrchestrationError("DATASET_INTERNAL_ERROR", e instanceof Error ? e.message : String(e), "repository");
32
+ return {
33
+ schema: DATASET_ORCHESTRATION_VERSION,
34
+ action,
35
+ ok: false,
36
+ diagnostics: [
37
+ {
38
+ code: x.code,
39
+ message: x.message,
40
+ boundary: x.boundary,
41
+ retryable: x.retryable,
42
+ },
43
+ ],
44
+ };
45
+ };
46
+ export class DatasetOrchestrationService {
47
+ repo;
48
+ deps;
49
+ constructor(repo, deps) {
50
+ this.repo = repo;
51
+ this.deps = deps;
52
+ }
53
+ now() {
54
+ return this.deps.now?.() ?? new Date().toISOString();
55
+ }
56
+ async offlineRemote(id, action, count = 10) {
57
+ const source = await this.repo.getSource(id);
58
+ if (!source)
59
+ return undefined;
60
+ const manifest = this.deps.adapter(source.adapter.id, source.adapter.version).describe();
61
+ if (manifest.permissions.network === "none")
62
+ return undefined;
63
+ const state = source.cache?.state ?? "cold";
64
+ if (state === "warm-verified")
65
+ return ok(action, action === "check" ? { sourceIdentity: source.identity ?? source.id, cache: state } : { records: (source.cache?.records ?? []).slice(0, Math.max(1, Math.min(100, count))), cache: state });
66
+ const codes = { cold: "DATASET_OFFLINE_COLD", stale: "DATASET_OFFLINE_STALE", corrupt: "DATASET_OFFLINE_CORRUPT", "wrong-revision": "DATASET_OFFLINE_WRONG_REVISION", unverifiable: "DATASET_OFFLINE_UNVERIFIABLE" };
67
+ return fail(action, new DatasetOrchestrationError(codes[state], `Offline cache state is ${state}`, "adapter"));
68
+ }
69
+ async source(source) {
70
+ try {
71
+ this.deps.adapter(source.adapter.id, source.adapter.version);
72
+ await this.repo.putSource(source);
73
+ return ok("source", {
74
+ sourceId: source.id,
75
+ revisionId: source.revisionId,
76
+ });
77
+ }
78
+ catch (e) {
79
+ return fail("source", e);
80
+ }
81
+ }
82
+ async context(id, offline = false) {
83
+ const source = await this.repo.getSource(id);
84
+ if (!source)
85
+ throw new DatasetOrchestrationError("DATASET_SOURCE_NOT_FOUND", `Unknown source ${id}`);
86
+ const adapter = this.deps.adapter(source.adapter.id, source.adapter.version);
87
+ const manifest = adapter.describe();
88
+ if (offline && manifest.permissions.network !== "none")
89
+ throw new DatasetOrchestrationError("DATASET_OFFLINE_COLD", "Offline policy prohibits initializing a network adapter", "adapter");
90
+ const configured = await adapter.configure(source.config);
91
+ if (!configured.ok || !configured.config)
92
+ throw new DatasetOrchestrationError(configured.diagnostics[0]?.code ?? "DATASET_ADAPTER_CONFIG_INVALID", configured.diagnostics[0]?.message ?? "Adapter configuration failed", "adapter");
93
+ return { source, adapter, manifest, configured };
94
+ }
95
+ async check(id, offline = false) {
96
+ try {
97
+ if (offline) {
98
+ const cached = await this.offlineRemote(id, "check");
99
+ if (cached)
100
+ return cached;
101
+ }
102
+ const c = await this.context(id, offline);
103
+ const result = await c.adapter.check(request(`check:${id}`, c.configured.config, {
104
+ ...c.source.policy,
105
+ offline,
106
+ }));
107
+ if (!result.ok)
108
+ throw new DatasetOrchestrationError(result.diagnostics[0]?.code ?? "DATASET_CHECK_FAILED", result.diagnostics[0]?.message ?? "Check failed", "adapter");
109
+ return ok("check", result.value);
110
+ }
111
+ catch (e) {
112
+ return fail("check", e);
113
+ }
114
+ }
115
+ async preview(id, count = 10, offline = false, signal) {
116
+ try {
117
+ if (offline) {
118
+ const cached = await this.offlineRemote(id, "preview", count);
119
+ if (cached)
120
+ return cached;
121
+ }
122
+ const c = await this.context(id, offline);
123
+ const bounded = Math.max(1, Math.min(100, count));
124
+ const result = await c.adapter.preview({
125
+ ...request(`preview:${id}`, c.configured.config, { ...c.source.policy, offline }, DEFAULT_ADAPTER_LIMITS),
126
+ count: bounded,
127
+ signal,
128
+ });
129
+ if (!result.ok)
130
+ throw new DatasetOrchestrationError(result.diagnostics[0]?.code ?? "DATASET_PREVIEW_FAILED", result.diagnostics[0]?.message ?? "Preview failed", "adapter");
131
+ return ok("preview", {
132
+ records: result.value ?? [],
133
+ bounds: {
134
+ records: bounded,
135
+ bytes: DEFAULT_ADAPTER_LIMITS.maxBytes,
136
+ timeoutMs: DEFAULT_ADAPTER_LIMITS.timeoutMs,
137
+ maxDepth: DEFAULT_ADAPTER_LIMITS.maxDepth,
138
+ },
139
+ });
140
+ }
141
+ catch (e) {
142
+ return fail("preview", e);
143
+ }
144
+ }
145
+ async plan(input) {
146
+ try {
147
+ const c = await this.context(input.sourceId, input.offline);
148
+ let backend = input.backend === "fortemi-core"
149
+ ? this.deps.fortemiBackend
150
+ : this.deps.localBackend;
151
+ if (!backend)
152
+ throw new DatasetOrchestrationError("DATASET_FORTEMI_UNAVAILABLE", "Fortemi support requires an injected compatible bridge", "backend");
153
+ const decision = negotiateDatasetCapabilities(input.profile, backend.capabilities());
154
+ const draft = {
155
+ contractVersion: DATASET_CONTRACT_VERSION,
156
+ kind: "ProcessingPlan",
157
+ id: input.id,
158
+ datasetRevisionId: c.source.revisionId,
159
+ capabilityProfileId: input.profile.id,
160
+ steps: input.steps,
161
+ artifactClasses: input.artifactClasses,
162
+ createdBy: input.createdBy,
163
+ source: {
164
+ id: c.source.id,
165
+ revisionId: c.source.revisionId,
166
+ identity: c.source.identity ?? c.source.id,
167
+ },
168
+ adapter: {
169
+ id: c.manifest.id,
170
+ version: c.manifest.version,
171
+ configDigest: c.configured.configDigest,
172
+ },
173
+ schemas: input.schemas,
174
+ capabilities: input.profile.capabilities,
175
+ capabilityDecision: decision,
176
+ policy: input.policy,
177
+ execution: {
178
+ locality: backend.id === "local" ? "local" : "remote",
179
+ backend: backend.id,
180
+ ...(input.fallback ? { fallback: input.fallback } : {}),
181
+ },
182
+ estimates: input.estimates ?? { reads: 0, writes: 0 },
183
+ approvals: input.approvals ?? [],
184
+ ...(input.reconciliation
185
+ ? { reconciliation: input.reconciliation }
186
+ : {}),
187
+ planDigest: sha256Digest("pending"),
188
+ };
189
+ const plan = { ...draft, planDigest: computeProcessingPlanDigest(draft) };
190
+ await this.repo.putPlan(plan);
191
+ return ok("plan", plan, {
192
+ backend: backend.id,
193
+ degraded: decision.degraded.map((v) => v.capability),
194
+ });
195
+ }
196
+ catch (e) {
197
+ return fail("plan", e);
198
+ }
199
+ }
200
+ async ingest(input) {
201
+ try {
202
+ const plan = await this.repo.getPlan(input.planId);
203
+ if (!plan)
204
+ throw new DatasetOrchestrationError("DATASET_PLAN_NOT_FOUND", `Unknown plan ${input.planId}`, "plan");
205
+ if (!verifyProcessingPlanDigest(plan) ||
206
+ plan.planDigest.value !== input.planDigest)
207
+ throw new DatasetOrchestrationError("DATASET_PLAN_DIGEST_MISMATCH", "Reviewed plan content or supplied digest changed", "plan");
208
+ const prior = await this.repo.getRunByIdempotency(input.idempotencyKey);
209
+ if (prior) {
210
+ if (prior.planDigest.value !== plan.planDigest.value)
211
+ throw new DatasetOrchestrationError("DATASET_IDEMPOTENCY_CONFLICT", "Idempotency identity is already bound to another plan", "plan");
212
+ return ok("ingest", prior, {
213
+ backend: plan.execution.backend,
214
+ degraded: prior.degraded,
215
+ });
216
+ }
217
+ const missing = plan.approvals.filter((a) => a.required && !input.approvalIds?.includes(a.id));
218
+ if (missing.length)
219
+ throw new DatasetOrchestrationError("DATASET_APPROVAL_REQUIRED", `Missing approvals: ${missing.map((v) => v.id).join(", ")}`, "plan");
220
+ if (plan.reconciliation &&
221
+ (input.reconciliationApproval?.previewDigest !==
222
+ plan.reconciliation.previewDigest.value ||
223
+ input.reconciliationApproval.threshold !==
224
+ plan.reconciliation.approvalThreshold))
225
+ throw new DatasetOrchestrationError("DATASET_RECONCILIATION_APPROVAL_REQUIRED", "Reconciliation requires the exact preview digest and threshold reviewed in the plan", "plan");
226
+ const c = await this.context(plan.source.id, plan.policy.network === "offline");
227
+ if (c.source.revisionId !== plan.source.revisionId ||
228
+ c.manifest.id !== plan.adapter.id ||
229
+ c.manifest.version !== plan.adapter.version ||
230
+ c.configured.configDigest?.value !== plan.adapter.configDigest.value)
231
+ throw new DatasetOrchestrationError("DATASET_SOURCE_COMPATIBILITY_CHANGED", "Source revision, adapter, or configuration changed after planning", "plan");
232
+ const backend = plan.execution.backend === "fortemi-core"
233
+ ? this.deps.fortemiBackend
234
+ : this.deps.localBackend;
235
+ if (!backend)
236
+ throw new DatasetOrchestrationError("DATASET_FORTEMI_UNAVAILABLE", "Fortemi support requires an injected compatible bridge", "backend");
237
+ negotiateDatasetCapabilities({
238
+ contractVersion: DATASET_CONTRACT_VERSION,
239
+ kind: "CapabilityProfile",
240
+ id: plan.capabilityProfileId,
241
+ capabilities: [...plan.capabilities],
242
+ }, backend.capabilities());
243
+ const runId = `run:${randomUUID()}`;
244
+ let state = {
245
+ runId,
246
+ idempotencyKey: input.idempotencyKey,
247
+ planId: plan.id,
248
+ planDigest: plan.planDigest,
249
+ status: "running",
250
+ attempt: 1,
251
+ startedAt: this.now(),
252
+ degraded: plan.capabilityDecision.degraded.map((v) => v.capability),
253
+ freshness: "unknown",
254
+ };
255
+ await this.repo.putRun(state);
256
+ const records = [];
257
+ for await (const event of c.adapter.read({
258
+ ...request(`read:${runId}`, c.configured.config, {
259
+ ...c.source.policy,
260
+ offline: plan.policy.network === "offline",
261
+ }),
262
+ checkpoint: c.source.checkpoint,
263
+ signal: input.signal,
264
+ })) {
265
+ if (event.kind === "record")
266
+ records.push(event.record);
267
+ }
268
+ const result = await backend.execute({
269
+ plan,
270
+ records,
271
+ signal: input.signal,
272
+ priorCheckpoint: c.source.checkpoint,
273
+ });
274
+ const receiptDraft = {
275
+ contractVersion: DATASET_CONTRACT_VERSION,
276
+ kind: "RunReceipt",
277
+ id: `receipt:${runId}`,
278
+ runId,
279
+ planId: plan.id,
280
+ planDigest: plan.planDigest,
281
+ outcome: result.outcome === "ambiguous" ? "attempted" : result.outcome,
282
+ committed: result.outcome === "committed",
283
+ attemptedRecords: result.attemptedRecords,
284
+ committedRecords: result.committedRecords,
285
+ rejectedRecords: result.rejectedRecords,
286
+ createdAt: this.now(),
287
+ receiptDigest: sha256Digest("pending"),
288
+ diagnosticCodes: result.diagnostics.map((v) => v.code),
289
+ };
290
+ const receipt = {
291
+ ...receiptDraft,
292
+ receiptDigest: computeRunReceiptDigest(receiptDraft),
293
+ };
294
+ state = {
295
+ ...state,
296
+ status: result.outcome,
297
+ endedAt: this.now(),
298
+ receipt,
299
+ ...(result.outcome === "committed"
300
+ ? { lastCommittedReceipt: receipt, checkpoint: result.checkpoint }
301
+ : {}),
302
+ freshness: result.outcome === "committed" ? "current" : "stale",
303
+ };
304
+ await this.repo.putRun(state);
305
+ if (result.outcome === "committed" && result.artifact)
306
+ await this.repo.putArtifactRecords(result.artifact.id, result.artifact.records.map((v) => v.value));
307
+ return ok("ingest", state, {
308
+ backend: backend.id,
309
+ degraded: state.degraded,
310
+ });
311
+ }
312
+ catch (e) {
313
+ return fail("ingest", e);
314
+ }
315
+ }
316
+ async status(runId) {
317
+ try {
318
+ const run = await this.repo.getRun(runId);
319
+ if (!run)
320
+ throw new DatasetOrchestrationError("DATASET_RUN_NOT_FOUND", `Unknown run ${runId}`);
321
+ return ok("status", run);
322
+ }
323
+ catch (e) {
324
+ return fail("status", e);
325
+ }
326
+ }
327
+ async show(id) {
328
+ try {
329
+ return ok("show", (await this.repo.getPlan(id)) ??
330
+ (await this.repo.getRun(id)) ??
331
+ (await this.repo.getSource(id)) ??
332
+ (() => {
333
+ throw new DatasetOrchestrationError("DATASET_OBJECT_NOT_FOUND", `Unknown object ${id}`);
334
+ })());
335
+ }
336
+ catch (e) {
337
+ return fail("show", e);
338
+ }
339
+ }
340
+ async verify(runId) {
341
+ try {
342
+ const run = await this.repo.getRun(runId);
343
+ if (!run?.receipt)
344
+ throw new DatasetOrchestrationError("DATASET_RECEIPT_NOT_FOUND", `No receipt for ${runId}`);
345
+ const valid = computeRunReceiptDigest(run.receipt).value ===
346
+ run.receipt.receiptDigest.value &&
347
+ run.receipt.planDigest.value === run.planDigest.value;
348
+ return valid
349
+ ? ok("verify", { runId, valid })
350
+ : fail("verify", new DatasetOrchestrationError("DATASET_RECEIPT_INVALID", "Receipt digest or plan binding is invalid", "repository"));
351
+ }
352
+ catch (e) {
353
+ return fail("verify", e);
354
+ }
355
+ }
356
+ async query(artifactId) {
357
+ try {
358
+ return ok("query", {
359
+ artifactId,
360
+ records: await this.repo.listArtifactRecords(artifactId),
361
+ });
362
+ }
363
+ catch (e) {
364
+ return fail("query", e);
365
+ }
366
+ }
367
+ async lineage(runId) {
368
+ try {
369
+ const run = await this.repo.getRun(runId);
370
+ if (!run)
371
+ throw new DatasetOrchestrationError("DATASET_RUN_NOT_FOUND", `Unknown run ${runId}`);
372
+ const plan = await this.repo.getPlan(run.planId);
373
+ const source = plan ? await this.repo.getSource(plan.source.id) : undefined;
374
+ const records = await this.repo.listArtifactRecords(`artifact:${run.planId}`);
375
+ return ok("lineage", {
376
+ artifactId: `artifact:${run.planId}`,
377
+ artifactRevision: run.planDigest.value,
378
+ runId,
379
+ sourceRevisionId: plan?.source.revisionId,
380
+ planDigest: run.planDigest,
381
+ principal: plan?.createdBy,
382
+ adapter: plan?.adapter,
383
+ schemas: plan?.schemas,
384
+ checkpoint: run.checkpoint ?? source?.checkpoint,
385
+ validation: run.receipt
386
+ ? {
387
+ receiptId: run.receipt.id,
388
+ receiptDigest: run.receipt.receiptDigest,
389
+ valid: computeRunReceiptDigest(run.receipt).value ===
390
+ run.receipt.receiptDigest.value,
391
+ }
392
+ : undefined,
393
+ records: records.map((record, ordinal) => ({
394
+ ordinal,
395
+ digest: datasetDigest(record),
396
+ })),
397
+ });
398
+ }
399
+ catch (e) {
400
+ return fail("lineage", e);
401
+ }
402
+ }
403
+ async export(artifactId) {
404
+ try {
405
+ return ok("export", {
406
+ artifactId,
407
+ format: "application/json",
408
+ records: await this.repo.listArtifactRecords(artifactId),
409
+ });
410
+ }
411
+ catch (e) {
412
+ return fail("export", e);
413
+ }
414
+ }
415
+ async cancel(runId) {
416
+ try {
417
+ const run = await this.repo.getRun(runId);
418
+ if (!run)
419
+ throw new DatasetOrchestrationError("DATASET_RUN_NOT_FOUND", `Unknown run ${runId}`);
420
+ if (run.status !== "running")
421
+ throw new DatasetOrchestrationError("DATASET_RUN_NOT_CANCELLABLE", `Run is ${run.status}`);
422
+ const next = {
423
+ ...run,
424
+ status: "cancelled",
425
+ endedAt: this.now(),
426
+ freshness: "stale",
427
+ };
428
+ await this.repo.putRun(next);
429
+ return ok("cancel", next);
430
+ }
431
+ catch (e) {
432
+ return fail("cancel", e);
433
+ }
434
+ }
435
+ async retry(runId, signal) {
436
+ try {
437
+ const run = await this.repo.getRun(runId);
438
+ if (!run)
439
+ throw new DatasetOrchestrationError("DATASET_RUN_NOT_FOUND", `Unknown run ${runId}`);
440
+ if (run.status === "committed" || run.status === "running")
441
+ throw new DatasetOrchestrationError("DATASET_RUN_NOT_RETRYABLE", `Run is ${run.status}`);
442
+ const result = await this.ingest({
443
+ planId: run.planId,
444
+ planDigest: run.planDigest.value,
445
+ idempotencyKey: `${run.idempotencyKey}:retry:${run.attempt + 1}`,
446
+ signal,
447
+ });
448
+ if (result.ok && result.data) {
449
+ const retried = {
450
+ ...result.data,
451
+ attempt: run.attempt + 1,
452
+ };
453
+ await this.repo.putRun(retried);
454
+ return ok("retry", retried, {
455
+ backend: result.backend,
456
+ degraded: result.degraded,
457
+ });
458
+ }
459
+ return { ...result, action: "retry" };
460
+ }
461
+ catch (error) {
462
+ return fail("retry", error);
463
+ }
464
+ }
465
+ }
466
+ //# sourceMappingURL=orchestration-service.js.map
@@ -0,0 +1,83 @@
1
+ import type { AdapterCheckpoint, AdapterDiagnostic, AdapterPolicy, AdapterRecord, DatasetSourceAdapter } from "./adapter-types.js";
2
+ import type { Digest, ProcessingPlan, RunReceipt } from "./types.js";
3
+ export declare const DATASET_ORCHESTRATION_VERSION: "aiwg.dataset-orchestration/v1";
4
+ export type DatasetAction = "source" | "check" | "preview" | "plan" | "ingest" | "status" | "show" | "verify" | "query" | "lineage" | "export" | "cancel" | "retry";
5
+ export interface RegisteredSource {
6
+ id: string;
7
+ revisionId: string;
8
+ adapter: {
9
+ id: string;
10
+ version: string;
11
+ };
12
+ config: Record<string, unknown>;
13
+ policy: AdapterPolicy;
14
+ identity?: string;
15
+ checkpoint?: AdapterCheckpoint;
16
+ cache?: {
17
+ state: "warm-verified" | "stale" | "corrupt" | "wrong-revision" | "unverifiable";
18
+ records?: readonly AdapterRecord[];
19
+ };
20
+ }
21
+ export interface DatasetRunState {
22
+ runId: string;
23
+ idempotencyKey: string;
24
+ planId: string;
25
+ planDigest: Digest;
26
+ status: "running" | "committed" | "failed" | "cancelled" | "ambiguous";
27
+ attempt: number;
28
+ startedAt: string;
29
+ endedAt?: string;
30
+ checkpoint?: AdapterCheckpoint;
31
+ receipt?: RunReceipt;
32
+ lastCommittedReceipt?: RunReceipt;
33
+ degraded: string[];
34
+ freshness: "current" | "stale" | "unknown";
35
+ }
36
+ export interface DatasetResult<T = unknown> {
37
+ schema: typeof DATASET_ORCHESTRATION_VERSION;
38
+ action: DatasetAction;
39
+ ok: boolean;
40
+ data?: T;
41
+ diagnostics: Array<{
42
+ code: string;
43
+ message: string;
44
+ boundary: "input" | "adapter" | "plan" | "backend" | "repository";
45
+ retryable: boolean;
46
+ }>;
47
+ backend?: string;
48
+ degraded?: string[];
49
+ }
50
+ export interface ExecutionRequest {
51
+ plan: ProcessingPlan;
52
+ records: readonly AdapterRecord[];
53
+ signal?: AbortSignal;
54
+ priorCheckpoint?: AdapterCheckpoint;
55
+ }
56
+ export interface ExecutionResult {
57
+ outcome: "committed" | "failed" | "cancelled" | "ambiguous";
58
+ attemptedRecords: number;
59
+ committedRecords: number;
60
+ rejectedRecords: number;
61
+ checkpoint?: AdapterCheckpoint;
62
+ diagnostics: AdapterDiagnostic[];
63
+ artifact?: {
64
+ id: string;
65
+ revisionId: string;
66
+ records: readonly AdapterRecord[];
67
+ };
68
+ }
69
+ export interface DatasetExecutionBackend {
70
+ readonly id: string;
71
+ capabilities(): readonly {
72
+ name: string;
73
+ version: string;
74
+ }[];
75
+ execute(request: ExecutionRequest): Promise<ExecutionResult>;
76
+ }
77
+ export interface DatasetOrchestrationDependencies {
78
+ adapter(id: string, version: string): DatasetSourceAdapter;
79
+ localBackend: DatasetExecutionBackend;
80
+ fortemiBackend?: DatasetExecutionBackend;
81
+ now?: () => string;
82
+ }
83
+ //# sourceMappingURL=orchestration-types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export const DATASET_ORCHESTRATION_VERSION = "aiwg.dataset-orchestration/v1";
2
+ //# sourceMappingURL=orchestration-types.js.map
@@ -0,0 +1,3 @@
1
+ import type { DatasetResult } from "./orchestration-types.js";
2
+ export declare function presentDatasetResult(result: DatasetResult, json?: boolean): string;
3
+ //# sourceMappingURL=presentation.d.ts.map
@@ -0,0 +1,8 @@
1
+ export function presentDatasetResult(result, json = false) {
2
+ if (json)
3
+ return JSON.stringify(result, null, 2) + "\n";
4
+ if (!result.ok)
5
+ return `${result.action} failed: ${result.diagnostics.map((v) => `${v.code}: ${v.message}`).join("; ")}\n`;
6
+ return `${result.action} succeeded${result.backend ? ` via ${result.backend}` : ""}${result.degraded?.length ? ` (degraded: ${result.degraded.join(", ")})` : ""}\n${JSON.stringify(result.data, null, 2)}\n`;
7
+ }
8
+ //# sourceMappingURL=presentation.js.map
@@ -0,0 +1,42 @@
1
+ import type { DependencyGraph } from '../artifacts/types.js';
2
+ import type { AiwgFortemiRecord } from '../artifacts/browser-export.js';
3
+ import type { OperationalStateProvenance } from '../artifacts/operational-state.js';
4
+ import type { MarketplaceProvenanceGraph } from '../marketplace/provenance-types.js';
5
+ import type { ProvenanceRecord } from '../research/services/types.js';
6
+ import type { LedgerEvent, ProjectionResult, W3cProvProjection } from './ledger-types.js';
7
+ import type { PrivacyClassification } from './types.js';
8
+ export interface ProjectionContext {
9
+ producer: {
10
+ id: string;
11
+ version: string;
12
+ };
13
+ recordedAt: string;
14
+ runId?: string;
15
+ privacy?: PrivacyClassification;
16
+ retentionPolicy?: string;
17
+ }
18
+ export interface MentionEdge {
19
+ sourcePath: string;
20
+ targetPath: string;
21
+ method?: 'mention' | 'markdown-link';
22
+ line?: number;
23
+ confidence?: number;
24
+ }
25
+ export interface SdlcTraceLink {
26
+ requirementId: string;
27
+ targetPath: string;
28
+ targetType: 'code' | 'test' | 'documentation' | 'deployment';
29
+ line?: number;
30
+ verified: boolean;
31
+ confidence: number;
32
+ }
33
+ export declare function preventPrivacyDowngrade(source: PrivacyClassification, projected: PrivacyClassification): void;
34
+ export declare function projectResearchProvenance(record: ProvenanceRecord, context: ProjectionContext): ProjectionResult<LedgerEvent[]>;
35
+ export declare function projectMarketplaceProvenance(graph: MarketplaceProvenanceGraph, context: ProjectionContext): ProjectionResult<LedgerEvent[]>;
36
+ export declare function projectFortemiProvenance(record: AiwgFortemiRecord, context: ProjectionContext): ProjectionResult<LedgerEvent[]>;
37
+ export declare function projectOperationalState(state: OperationalStateProvenance, recordId: string, context: ProjectionContext): ProjectionResult<LedgerEvent[]>;
38
+ export declare function projectMentionEdge(edge: MentionEdge, context: ProjectionContext): ProjectionResult<LedgerEvent[]>;
39
+ export declare function projectSdlcTraceLink(link: SdlcTraceLink, context: ProjectionContext): ProjectionResult<LedgerEvent[]>;
40
+ export declare function projectLedgerToDependencyGraph(events: readonly LedgerEvent[]): ProjectionResult<DependencyGraph>;
41
+ export declare function projectLedgerToW3cProv(events: readonly LedgerEvent[]): ProjectionResult<W3cProvProjection>;
42
+ //# sourceMappingURL=projections.d.ts.map