@deksden-com/dd-flow-cli 0.9.0-beta.136 → 0.9.0-beta.137

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 (59) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/build-info.json +3 -3
  3. package/dist/harness-runtime/DD-ZCODE.md +13 -0
  4. package/dist/harness-runtime/bin/dd-opencode.mjs +3 -3
  5. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +14 -1
  6. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +36 -1
  7. package/dist/harness-runtime/lib/dd-zcode.mjs +7 -3
  8. package/dist/harness-runtime/lib/opencode-plugin.mjs +3 -1
  9. package/dist/services/controller-child-observer.js +99 -0
  10. package/dist/services/controller-fanout.js +9 -2
  11. package/dist/services/run-controller.js +83 -8
  12. package/dist/services/stage-lifecycle.js +2 -1
  13. package/dist/services/stage-report-renderer.js +13 -0
  14. package/dist/services/vnext-fanout.js +66 -1
  15. package/dist/services/vnext-protocolize.js +60 -2
  16. package/package.json +1 -1
  17. package/dist/cli/command-metadata.js +0 -144
  18. package/dist/cli/command-option-descriptions.js +0 -186
  19. package/dist/cli/completion-cli.js +0 -70
  20. package/dist/cli/completion.js +0 -57
  21. package/dist/cli/error-output.js +0 -52
  22. package/dist/cli/executor-onboarding.js +0 -71
  23. package/dist/cli/harnesses.js +0 -84
  24. package/dist/cli/models.js +0 -39
  25. package/dist/cli/operator-profiles.js +0 -61
  26. package/dist/cli/output-options.js +0 -35
  27. package/dist/cli/response-file.js +0 -69
  28. package/dist/cli/setup.js +0 -147
  29. package/dist/services/cli-upgrade-allowlist.js +0 -27
  30. package/dist/services/discovery/agy-discovery.js +0 -2
  31. package/dist/services/discovery/codex-discovery.js +0 -2
  32. package/dist/services/discovery/droid-discovery.js +0 -2
  33. package/dist/services/discovery/grok-discovery.js +0 -2
  34. package/dist/services/discovery/opencode-discovery.js +0 -2
  35. package/dist/services/discovery/static.js +0 -31
  36. package/dist/services/discovery/zcode-discovery.js +0 -2
  37. package/dist/services/executor-onboarding.js +0 -56
  38. package/dist/services/harness-discovery.js +0 -29
  39. package/dist/services/harness-doctor.js +0 -75
  40. package/dist/services/harness-probe-effects.js +0 -51
  41. package/dist/services/harness-version-probe.js +0 -100
  42. package/dist/services/hybrid-contracts.js +0 -455
  43. package/dist/services/installation-lock.js +0 -92
  44. package/dist/services/model-catalog.js +0 -109
  45. package/dist/services/model-discovery.js +0 -46
  46. package/dist/services/operator-profiles.js +0 -236
  47. package/dist/services/release-archive-producer.js +0 -52
  48. package/dist/services/release-archive.js +0 -143
  49. package/dist/services/release-cache.js +0 -142
  50. package/dist/services/release-compatibility.js +0 -18
  51. package/dist/services/release-download.js +0 -67
  52. package/dist/services/release-envelope.js +0 -104
  53. package/dist/services/release-manifest.js +0 -45
  54. package/dist/services/release-payload.js +0 -114
  55. package/dist/services/release-producer.js +0 -63
  56. package/dist/services/release-provenance.js +0 -160
  57. package/dist/services/release-registry.js +0 -66
  58. package/dist/services/release-source.js +0 -194
  59. package/dist/services/setup.js +0 -377
@@ -1,455 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import fs from "node:fs";
3
- import { Ajv2020 } from "ajv/dist/2020.js";
4
- import { Ajv } from "ajv/dist/ajv.js";
5
- /** Static E1 contracts only. No ingress, dispatch or runtime defaults are changed. */
6
- export const hybridContractNames = [
7
- "release-manifest", "harness-catalog", "model-catalog", "discovery-result",
8
- "profile-settings", "flow-descriptor", "execution-settings",
9
- "memory-bootstrap-receipt", "execution-bundle"
10
- ];
11
- const hybridContractRegistry = new Set(hybridContractNames);
12
- const record = (input) => input;
13
- const list = (input) => input;
14
- const string = (input) => input;
15
- /** Deterministic JSON content identity, not a signature or secret-derived hash. */
16
- export function hybridDigest(input) {
17
- const canonical = (value) => {
18
- if (Array.isArray(value))
19
- return value.map(canonical);
20
- if (value !== null && typeof value === "object") {
21
- return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b, "en"))
22
- .map(([key, child]) => [key, canonical(child)]));
23
- }
24
- return value;
25
- };
26
- return createHash("sha256").update(JSON.stringify(canonical(input))).digest("hex");
27
- }
28
- /** E1 standalone validation. Runtime ingress must explicitly integrate it in E2/E3. */
29
- export function validateHybridContract(name, input, context = {}) {
30
- if (name === "flow-descriptor") {
31
- if (!context.descriptorContext)
32
- return [{ gate: "context", code: "missing_descriptor_context", path: "/" }];
33
- return validateFlowDescriptor(input, context.descriptorContext);
34
- }
35
- const shape = validateHybridShape(name, input);
36
- if (shape.length)
37
- return shape;
38
- const data = record(input), issues = [];
39
- const fail = (code, path = "/") => issues.push({ gate: "context", code, path });
40
- const seen = new Set();
41
- const unique = (key, path) => {
42
- if (seen.has(key))
43
- fail("duplicate_identity", path);
44
- seen.add(key);
45
- };
46
- const receipt = (reference, kind, required) => {
47
- if (reference === null) {
48
- if (required)
49
- fail("missing_receipt", `/receipts/${kind}`);
50
- return;
51
- }
52
- const ref = record(reference), fact = context.receipts?.get(string(ref.sha256));
53
- if (!fact || fact.kind !== kind) {
54
- fail("unverified_receipt", `/receipts/${kind}`);
55
- return;
56
- }
57
- const expected = context.bootstrapIdentity;
58
- if (expected && (fact.requestId !== expected.requestId || fact.projectRoot !== expected.projectRoot || fact.workspace !== expected.workspace)) {
59
- fail("foreign_receipt", `/receipts/${kind}`);
60
- }
61
- };
62
- if (name === "release-manifest") {
63
- const canon = record(data.canon), engine = record(data.engine);
64
- if (data.version !== canon.version)
65
- fail("release_canon_version_mismatch");
66
- const artifacts = [record(canon.archive), record(engine.archive)];
67
- if (artifacts[0].url === artifacts[1].url || artifacts[0].sha256 === artifacts[1].sha256)
68
- fail("conflicting_artifact_identity");
69
- for (const value of list(data.qualified_routes)) {
70
- const route = record(value);
71
- unique([route.platform, route.harness, route.flow, route.delegation].join("/"), "/qualified_routes");
72
- receipt(route.evidence, "route-qualification", true);
73
- }
74
- }
75
- else if (name === "harness-catalog") {
76
- const families = new Set(["codex", "zcode", "agy", "opencode", "grok", "droid"]);
77
- for (const value of list(data.entries)) {
78
- const entry = record(value), id = string(entry.id);
79
- unique(id, "/entries");
80
- families.delete(id);
81
- if (entry.probe_module !== `${id}-discovery`)
82
- fail("foreign_probe_module", "/entries");
83
- }
84
- if (families.size)
85
- fail("missing_harness_family", "/entries");
86
- }
87
- else if (name === "model-catalog") {
88
- for (const value of list(data.entries)) {
89
- const entry = record(value), qualification = record(entry.qualification);
90
- unique([entry.harness, entry.provider, entry.model].join("/"), "/entries");
91
- if (qualification.scope === "seed-only") {
92
- if (qualification.evidence !== null)
93
- fail("seed_has_qualification_receipt", "/entries");
94
- }
95
- else
96
- receipt(qualification.evidence, `model-${qualification.scope}-qualification`, true);
97
- }
98
- }
99
- else if (name === "discovery-result") {
100
- if (data.probe_scope === "live")
101
- receipt(data.live_authorization_receipt, "live-probe-authorization", true);
102
- else if (data.live_authorization_receipt !== null)
103
- fail("unexpected_live_authorization");
104
- for (const value of list(data.entries)) {
105
- const entry = record(value);
106
- unique(string(entry.harness), "/entries");
107
- const selected = list(entry.candidates).filter(candidate => record(candidate).selected === true);
108
- if (selected.length > 1)
109
- fail("ambiguous_selected_executable", "/entries");
110
- if (entry.installed === "yes" && selected.length !== 1)
111
- fail("missing_selected_executable", "/entries");
112
- if (entry.installed === "no" && (selected.length || entry.compatible === "yes" || entry.protocol === "verified" || entry.auth === "verified" || entry.qualified === "yes"))
113
- fail("contradictory_discovery_facts", "/entries");
114
- if (entry.auth === "verified" || entry.protocol === "verified" || entry.qualified === "yes") {
115
- if (data.probe_scope === "static" || list(entry.evidence).length === 0)
116
- fail("unsupported_verified_fact", "/entries");
117
- for (const evidence of list(entry.evidence))
118
- receipt(evidence, "discovery-observation", true);
119
- }
120
- }
121
- }
122
- else if (name === "profile-settings") {
123
- const profiles = new Map();
124
- for (const value of list(data.profiles)) {
125
- const entry = record(value), profile = record(entry.profile), id = string(entry.id);
126
- unique(id, "/profiles");
127
- profiles.set(id, profile);
128
- if (profile.id !== id || hybridDigest(profile) !== entry.revision)
129
- fail("profile_revision_mismatch", "/profiles");
130
- }
131
- const aliases = record(data.aliases);
132
- for (const [alias, target] of Object.entries(aliases)) {
133
- if (!profiles.has(string(target)))
134
- fail("dangling_or_chained_alias", `/aliases/${alias}`);
135
- if (profiles.has(alias))
136
- fail("alias_id_collision", `/aliases/${alias}`);
137
- }
138
- if (data.default_profile !== null && !profiles.has(string(data.default_profile)) && !Object.hasOwn(aliases, string(data.default_profile)))
139
- fail("dangling_default", "/default_profile");
140
- const content = Object.fromEntries(Object.entries(data).filter(([key]) => key !== "revision"));
141
- if (hybridDigest(content) !== data.revision)
142
- fail("settings_revision_mismatch", "/revision");
143
- }
144
- else if (name === "execution-settings") {
145
- if (!context.descriptor || !context.descriptorSha256 || !context.profileSettings) {
146
- fail("missing_execution_context");
147
- return issues;
148
- }
149
- const descriptor = record(context.descriptor), settings = record(context.profileSettings);
150
- if (validateHybridShape("flow-descriptor", descriptor).length || validateHybridContract("profile-settings", settings).length) {
151
- fail("invalid_execution_context");
152
- return issues;
153
- }
154
- if (data.flow_id !== descriptor.id || data.descriptor_sha256 !== context.descriptorSha256)
155
- fail("foreign_descriptor");
156
- const available = new Map(list(settings.profiles).map(value => { const entry = record(value); return [string(entry.id), entry]; }));
157
- const frozen = new Set();
158
- for (const value of list(data.profiles)) {
159
- const profile = record(value), id = string(profile.id);
160
- unique(id, "/profiles");
161
- frozen.add(id);
162
- if (!available.has(id) || available.get(id).revision !== profile.revision)
163
- fail("foreign_profile_revision", "/profiles");
164
- }
165
- const stageIds = new Set(list(descriptor.stages).map(value => string(record(value).id)));
166
- for (const stage of Object.keys(record(data.stage_profiles)))
167
- if (!stageIds.has(stage))
168
- fail("foreign_stage", `/stage_profiles/${stage}`);
169
- const routes = [data.root_profile, ...Object.values(record(data.stage_profiles)), ...list(data.work_profiles)].map(string);
170
- for (const id of routes)
171
- if (!frozen.has(id))
172
- fail("unapproved_profile", "/routing");
173
- if (data.execution === "attached")
174
- receipt(data.attached_session_receipt, "attached-session-binding", true);
175
- else if (data.attached_session_receipt !== null)
176
- fail("unexpected_attached_binding");
177
- const delegation = record(data.delegation);
178
- const root = available.get(string(data.root_profile));
179
- const sameProfile = (id) => {
180
- const entry = available.get(id);
181
- if (!entry || !root)
182
- return false;
183
- const meaningful = (value) => Object.fromEntries(Object.entries(record(value)).filter(([key]) => key !== "id"));
184
- return hybridDigest(meaningful(entry.profile)) === hybridDigest(meaningful(root.profile));
185
- };
186
- if (data.stage_session_mode === "same_session") {
187
- for (const route of Object.values(record(data.stage_profiles)).map(string)) {
188
- if (!sameProfile(route))
189
- fail("same_session_profile_override", "/stage_profiles");
190
- }
191
- }
192
- if (delegation.mode === "native") {
193
- receipt(delegation.native_capacity_receipt, "native-capacity", true);
194
- for (const id of routes)
195
- if (!sameProfile(id))
196
- fail("native_profile_override", "/routing");
197
- if (delegation.native_capacity_receipt !== null) {
198
- const fact = context.receipts?.get(string(record(delegation.native_capacity_receipt).sha256));
199
- if (!fact || !root || fact.harness !== record(root.profile).harness || fact.profileRevision !== root.revision
200
- || !Number.isInteger(fact.capacity) || fact.capacity < Number(delegation.max_parallel))
201
- fail("native_capacity_scope_mismatch", "/delegation");
202
- }
203
- }
204
- else if (delegation.native_capacity_receipt !== null)
205
- fail("unexpected_native_capacity");
206
- }
207
- else if (name === "memory-bootstrap-receipt") {
208
- const expected = context.bootstrapIdentity;
209
- if (!expected) {
210
- fail("missing_bootstrap_context");
211
- return issues;
212
- }
213
- const workspace = record(data.workspace), execution = record(data.effective_execution), storage = record(data.storage);
214
- if (data.request_id !== expected.requestId || data.project_root !== expected.projectRoot || workspace.path !== expected.workspace || data.baseline_sha256 !== expected.baselineSha256)
215
- fail("foreign_bootstrap_identity");
216
- if (execution.engine_sha256 !== expected.engineSha256 || execution.canon_sha256 !== expected.canonSha256)
217
- fail("foreign_execution_identity");
218
- receipt(storage.compatibility_receipt, "storage-compatibility", true);
219
- const noOp = storage.route === "verified-no-op";
220
- if (noOp) {
221
- if (storage.outcome !== "no-op")
222
- fail("invalid_no_op_outcome");
223
- for (const field of ["drain_receipt", "backup_receipt", "plan_receipt", "apply_receipt", "verification_receipt"])
224
- if (storage[field] !== null)
225
- fail("no_op_has_migration_effect");
226
- }
227
- else if (storage.outcome === "applied") {
228
- for (const [field, kind] of [["drain_receipt", "writer-drain"], ["backup_receipt", "storage-backup"], ["plan_receipt", "storage-plan"], ["apply_receipt", "storage-apply"], ["verification_receipt", "storage-verification"]])
229
- receipt(storage[field], kind, true);
230
- }
231
- if (data.readiness === "ready" && !(noOp || storage.outcome === "applied"))
232
- fail("storage_not_ready");
233
- if (data.flow_id === "mb-upgrade" && data.project_current === null)
234
- fail("missing_upgrade_baseline");
235
- for (const value of list(data.effects)) {
236
- const effect = record(value);
237
- receipt(effect.receipt, string(effect.kind), true);
238
- if (effect.kind === "storage-apply" && (noOp || storage.outcome !== "applied"))
239
- fail("undeclared_storage_effect");
240
- }
241
- }
242
- else if (name === "execution-bundle") {
243
- if (!context.blobs || !context.engineChecksum || !context.engineBindingSha256 || !context.engineManifestSha256 || !context.bundleProvenance || !context.descriptorSha256
244
- || typeof context.bundleProjectRoot !== "string" || context.bundleProjectRoot.length === 0) {
245
- fail("missing_bundle_context");
246
- return issues;
247
- }
248
- if (record(data.descriptor).sha256 !== context.descriptorSha256)
249
- fail("foreign_bundle_descriptor", "/descriptor");
250
- if (hybridDigest(data.canon) !== hybridDigest(context.bundleProvenance.canon))
251
- fail("foreign_bundle_canon", "/canon");
252
- if (hybridDigest(data.project_pack) !== hybridDigest(context.bundleProvenance.project_pack))
253
- fail("foreign_bundle_project_pack", "/project_pack");
254
- const memoryFlow = data.flow_id === "mb-init" || data.flow_id === "mb-upgrade";
255
- if (memoryFlow && context.bootstrapIdentity?.projectRoot !== context.bundleProjectRoot)
256
- fail("foreign_bootstrap_identity", "/bootstrap_receipts");
257
- if (memoryFlow && list(data.bootstrap_receipts).length === 0)
258
- fail("missing_memory_bootstrap", "/bootstrap_receipts");
259
- if (!memoryFlow && list(data.bootstrap_receipts).length > 0)
260
- fail("foreign_memory_bootstrap", "/bootstrap_receipts");
261
- const inventory = new Map();
262
- for (const value of list(data.inventory)) {
263
- const ref = record(value), path = string(ref.path);
264
- unique(path, "/inventory");
265
- inventory.set(path, string(ref.sha256));
266
- const bytes = context.blobs.get(path);
267
- if (!bytes)
268
- fail("missing_bundle_blob", `/inventory/${path}`);
269
- else if (createHash("sha256").update(bytes).digest("hex") !== ref.sha256)
270
- fail("bundle_checksum_mismatch", `/inventory/${path}`);
271
- }
272
- for (const reference of [data.descriptor, data.execution_settings, data.profile_settings, data.engine_binding, data.engine_manifest, ...list(data.bootstrap_receipts)]) {
273
- const ref = record(reference);
274
- if (inventory.get(string(ref.path)) !== ref.sha256)
275
- fail("unlisted_bundle_reference");
276
- }
277
- if (record(data.engine_binding).sha256 !== context.engineBindingSha256)
278
- fail("foreign_engine_binding");
279
- if (record(data.engine_manifest).sha256 !== context.engineManifestSha256)
280
- fail("foreign_engine_manifest");
281
- const loaded = (reference) => {
282
- const bytes = context.blobs.get(string(record(reference).path));
283
- try {
284
- return bytes ? JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)) : null;
285
- }
286
- catch {
287
- fail("invalid_bundle_json");
288
- return null;
289
- }
290
- };
291
- const descriptor = loaded(data.descriptor), settings = loaded(data.execution_settings), profiles = loaded(data.profile_settings);
292
- const binding = loaded(data.engine_binding);
293
- const bindingSchema = JSON.parse(fs.readFileSync(new URL("../schemas/run-engine-binding.schema.json", import.meta.url), "utf8"));
294
- const bindingValidator = new Ajv({ strict: false, validateFormats: false }).compile(bindingSchema);
295
- const bindingValid = bindingValidator(binding);
296
- if (!bindingValid)
297
- fail("invalid_engine_binding");
298
- else if (record(binding).run_id !== data.run_id || record(binding).project_root !== context.bundleProjectRoot
299
- || record(record(binding).engine).integrity_checksum !== context.engineChecksum)
300
- fail("foreign_engine_binding");
301
- const manifest = loaded(data.engine_manifest);
302
- const manifestSchema = JSON.parse(fs.readFileSync(new URL("../schemas/engine-manifest.schema.json", import.meta.url), "utf8"));
303
- const manifestValidator = new Ajv({ strict: false, validateFormats: false }).compile(manifestSchema);
304
- if (!manifestValidator(manifest))
305
- fail("invalid_engine_manifest");
306
- else if (bindingValid) {
307
- const selected = record(manifest), engine = record(record(binding).engine), integrity = record(selected.integrity);
308
- if (["package_name", "package_version", "engine_version", "snapshot_root"].some(key => selected[key] !== engine[key])
309
- || integrity.mode !== "full_content" || integrity.checksum !== engine.integrity_checksum)
310
- fail("foreign_engine_manifest");
311
- }
312
- if (!descriptor || !settings || !profiles)
313
- fail("missing_bundle_contract");
314
- else {
315
- if (record(descriptor).id !== data.flow_id || record(settings).flow_id !== data.flow_id)
316
- fail("foreign_bundle_flow");
317
- const retained = new Map([...context.blobs].filter(([path]) => inventory.has(path)));
318
- const descriptorContext = context.descriptorContext
319
- ? { ...context.descriptorContext, blobs: retained } : undefined;
320
- const bundleContext = descriptorContext ? { ...context, descriptorContext } : context;
321
- issues.push(...validateHybridContract("flow-descriptor", descriptor, bundleContext));
322
- issues.push(...validateHybridContract("profile-settings", profiles, context));
323
- issues.push(...validateHybridContract("execution-settings", settings, { ...context, descriptor,
324
- descriptorSha256: string(record(data.descriptor).sha256), profileSettings: profiles }));
325
- for (const reference of list(data.bootstrap_receipts)) {
326
- const bootstrap = loaded(reference);
327
- if (!bootstrap)
328
- fail("missing_bundle_bootstrap");
329
- else {
330
- if (record(bootstrap).flow_id !== data.flow_id || record(bootstrap).readiness !== "ready")
331
- fail("bundle_bootstrap_not_admitted");
332
- issues.push(...validateHybridContract("memory-bootstrap-receipt", bootstrap, context));
333
- }
334
- }
335
- }
336
- }
337
- else
338
- fail("unknown_hybrid_contract");
339
- return issues;
340
- }
341
- export function validateHybridShape(name, input) {
342
- if (!hybridContractRegistry.has(name)) {
343
- return [{ gate: "shape", code: "unknown_contract_name", path: "/" }];
344
- }
345
- const schemaUrl = new URL(`../schemas/${name}.schema.json`, import.meta.url);
346
- const schema = JSON.parse(fs.readFileSync(schemaUrl, "utf8"));
347
- const ajv = new Ajv2020({ allErrors: true, strict: true, validateFormats: false });
348
- const validate = ajv.compile(schema);
349
- if (validate(input))
350
- return [];
351
- return (validate.errors ?? []).map(error => ({
352
- gate: "shape", code: error.keyword, path: error.instancePath || "/"
353
- }));
354
- }
355
- /** Context must come from the trusted materializer, never from the descriptor. */
356
- export function validateFlowDescriptor(input, context) {
357
- const shape = validateHybridShape("flow-descriptor", input);
358
- if (shape.length)
359
- return shape;
360
- const descriptor = input;
361
- const issues = [];
362
- const fail = (code, path) => issues.push({ gate: "context", code, path });
363
- const ids = new Set(), directories = new Set();
364
- const outgoing = new Map(), incoming = new Map();
365
- for (const [index, stage] of descriptor.stages.entries()) {
366
- if (ids.has(stage.id))
367
- fail("duplicate_stage", `/stages/${index}/id`);
368
- if (directories.has(stage.directory))
369
- fail("duplicate_directory", `/stages/${index}/directory`);
370
- ids.add(stage.id);
371
- directories.add(stage.directory);
372
- outgoing.set(stage.id, []);
373
- incoming.set(stage.id, []);
374
- if (!context.entryHandlers.has(stage.entry_handler))
375
- fail("unknown_entry_handler", `/stages/${index}/entry_handler`);
376
- if (!context.finishHandlers.has(stage.finish_handler))
377
- fail("unknown_finish_handler", `/stages/${index}/finish_handler`);
378
- for (const field of ["instruction", "result_schema"]) {
379
- const reference = stage[field], bytes = context.blobs.get(reference.path);
380
- if (!bytes) {
381
- fail("missing_blob", `/stages/${index}/${field}`);
382
- continue;
383
- }
384
- if (createHash("sha256").update(bytes).digest("hex") !== reference.sha256) {
385
- fail("blob_checksum_mismatch", `/stages/${index}/${field}`);
386
- continue;
387
- }
388
- if (field === "result_schema") {
389
- try {
390
- const schema = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
391
- new Ajv2020({ strict: true, validateFormats: false }).compile(schema);
392
- }
393
- catch {
394
- fail("invalid_result_schema", `/stages/${index}/${field}`);
395
- }
396
- }
397
- }
398
- }
399
- if (!ids.has(descriptor.entry_stage))
400
- fail("foreign_entry", "/entry_stage");
401
- for (const terminal of descriptor.terminal_stages) {
402
- if (!ids.has(terminal))
403
- fail("foreign_terminal", "/terminal_stages");
404
- }
405
- const transitions = new Set();
406
- for (const [index, edge] of descriptor.edges.entries()) {
407
- const transition = `${edge.from}/${edge.on}`;
408
- if (transitions.has(transition))
409
- fail("ambiguous_transition", `/edges/${index}`);
410
- transitions.add(transition);
411
- if (!ids.has(edge.from) || !ids.has(edge.to)) {
412
- fail("foreign_edge", `/edges/${index}`);
413
- continue;
414
- }
415
- outgoing.get(edge.from).push(edge.to);
416
- incoming.get(edge.to).push(edge.from);
417
- if (descriptor.terminal_stages.includes(edge.from))
418
- fail("terminal_outgoing", `/edges/${index}`);
419
- }
420
- const closure = (seeds, graph) => {
421
- const seen = new Set(), pending = [...seeds];
422
- while (pending.length) {
423
- const id = pending.pop();
424
- if (seen.has(id) || !ids.has(id))
425
- continue;
426
- seen.add(id);
427
- pending.push(...(graph.get(id) ?? []));
428
- }
429
- return seen;
430
- };
431
- const reachable = closure([descriptor.entry_stage], outgoing);
432
- const canFinish = closure(descriptor.terminal_stages, incoming);
433
- for (const id of ids) {
434
- if (!reachable.has(id))
435
- fail("unreachable_stage", `/stages/${id}`);
436
- if (!canFinish.has(id))
437
- fail("no_terminal_path", `/stages/${id}`);
438
- }
439
- const degrees = new Map([...ids].map(id => [id, incoming.get(id).length]));
440
- const ready = [...ids].filter(id => degrees.get(id) === 0);
441
- let visited = 0;
442
- while (ready.length) {
443
- const id = ready.pop();
444
- visited++;
445
- for (const next of outgoing.get(id)) {
446
- const count = degrees.get(next) - 1;
447
- degrees.set(next, count);
448
- if (count === 0)
449
- ready.push(next);
450
- }
451
- }
452
- if (visited !== ids.size)
453
- fail("cyclic_graph", "/edges");
454
- return issues;
455
- }
@@ -1,92 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import os from "node:os";
4
- import { randomUUID } from "node:crypto";
5
- import { AppError } from "../shared/errors.js";
6
- function refuse(reason) {
7
- throw new AppError("installation_locked", "Installation owner requires reconciliation", 1, { reason, effect: "no_effect", help: "setup", next_action: "Replay the original exact request after its owner exits" });
8
- }
9
- function readOwner(file) {
10
- if (!fs.lstatSync(file).isFile())
11
- refuse("foreign_lock_object");
12
- let owner;
13
- try {
14
- owner = JSON.parse(fs.readFileSync(file, "utf8"));
15
- }
16
- catch {
17
- return refuse("unreadable_lock_owner");
18
- }
19
- if (!owner || owner.schema_id !== "dd-flow/installation-lock@1" || !/^[a-f0-9]{64}$/.test(owner.identity) ||
20
- owner.host !== os.hostname() || !Number.isSafeInteger(owner.pid) || owner.pid < 1 || !/^[a-f0-9-]{36}$/.test(owner.token))
21
- refuse("unverified_lock_owner");
22
- return owner;
23
- }
24
- function isDead(pid) {
25
- try {
26
- process.kill(pid, 0);
27
- return false;
28
- }
29
- catch (error) {
30
- return error.code === "ESRCH";
31
- }
32
- }
33
- /** Publish a complete owner record atomically; only the same request can reclaim a kernel-confirmed dead owner. */
34
- export function acquireInstallationLock(file, identity) {
35
- if (!/^[a-f0-9]{64}$/.test(identity))
36
- refuse("invalid_lock_identity");
37
- const owner = { schema_id: "dd-flow/installation-lock@1", identity, host: os.hostname(), pid: process.pid, token: randomUUID() };
38
- const temporary = path.join(path.dirname(file), `.lock-owner-${owner.token}.tmp`);
39
- const fd = fs.openSync(temporary, "wx", 0o600);
40
- try {
41
- try {
42
- fs.writeFileSync(fd, JSON.stringify(owner));
43
- fs.fsyncSync(fd);
44
- }
45
- finally {
46
- fs.closeSync(fd);
47
- }
48
- for (let attempt = 0; attempt < 3; attempt++) {
49
- try {
50
- fs.linkSync(temporary, file);
51
- return { token: owner.token, release: () => {
52
- const retained = readOwner(file);
53
- if (retained.token !== owner.token || retained.pid !== process.pid || retained.identity !== identity)
54
- refuse("lock_owner_changed");
55
- fs.unlinkSync(file);
56
- } };
57
- }
58
- catch (error) {
59
- if (error.code !== "EEXIST")
60
- throw error;
61
- const previous = readOwner(file);
62
- if (previous.identity !== identity)
63
- refuse("different_request_owns_lock");
64
- if (!isDead(previous.pid))
65
- refuse("owner_process_alive_or_unknown");
66
- // Atomic quarantine retains crash evidence. A competing reclaimer must retry, not overwrite an owner.
67
- const quarantine = `${file}.abandoned-${previous.token}`;
68
- if (fs.existsSync(quarantine))
69
- refuse("ambiguous_abandoned_lock");
70
- const before = fs.lstatSync(file);
71
- const checked = readOwner(file);
72
- if (checked.token !== previous.token || !isDead(checked.pid))
73
- refuse("lock_owner_changed");
74
- try {
75
- fs.linkSync(file, quarantine);
76
- }
77
- catch {
78
- return refuse("concurrent_lock_reconciliation");
79
- }
80
- const after = fs.lstatSync(file);
81
- if (before.ino !== after.ino || before.dev !== after.dev || readOwner(file).token !== previous.token)
82
- refuse("lock_owner_changed");
83
- fs.unlinkSync(file);
84
- }
85
- }
86
- return refuse("lock_contention");
87
- }
88
- finally {
89
- if (fs.existsSync(temporary))
90
- fs.unlinkSync(temporary);
91
- }
92
- }
@@ -1,109 +0,0 @@
1
- import { AppError } from "../shared/errors.js";
2
- import { validateHybridContract } from "./hybrid-contracts.js";
3
- import { mergeModelListing } from "./model-discovery.js";
4
- import { readBoundedReleaseFile } from "./release-source.js";
5
- // Reviewed adapter fallbacks and retained eval configurations, not vendor
6
- // availability promises or recommended defaults. Missing facts stay unknown;
7
- // historical eval qualification/capacity claims are deliberately not imported.
8
- const seed = {
9
- schema_id: "dd-flow/model-catalog@1", version: "1.1.0",
10
- entries: [{ harness: "agy", provider: "google", model: "gemini-3.1-pro-high",
11
- settings: { reasoning: ["unknown"], mode: ["unknown"] },
12
- provenance: { kind: "reviewed-seed", source: "https://github.com/deksden-com/dd-flow-cli/blob/2ba2ce2364705cf59fdc48bdd5dc5b37fb7cd784/src/harness-runtime/lib/dd-agy.mjs#L7",
13
- reviewed_at: "2026-10-07T00:00:00Z" }, availability: "not-observed", qualification: { scope: "seed-only", evidence: null } },
14
- { harness: "grok", provider: "xai", model: "grok-4.6",
15
- settings: { reasoning: ["high"], mode: ["bypassPermissions"] },
16
- provenance: { kind: "reviewed-seed", source: "https://github.com/deksden-com/dd-flow-cli/blob/2ba2ce2364705cf59fdc48bdd5dc5b37fb7cd784/src/harness-runtime/lib/dd-grok.mjs#L48",
17
- reviewed_at: "2026-10-07T00:00:00Z" }, availability: "not-observed", qualification: { scope: "seed-only", evidence: null } },
18
- { harness: "codex", provider: "unknown", model: "gpt-6.1-sol",
19
- settings: { reasoning: ["high"], mode: ["unknown"] },
20
- provenance: { kind: "reviewed-seed", source: "https://github.com/deksden-com/dd-eval/blob/9715970544096fc0288ac8e18f95d4e35997be54/profiles/codex-desktop-gpt-6-1-sol-high.json",
21
- reviewed_at: "2026-10-07T00:00:00Z" }, availability: "not-observed", qualification: { scope: "seed-only", evidence: null } },
22
- { harness: "zcode", provider: "builtin:zai-coding-plan", model: "GLM-5.3",
23
- settings: { reasoning: ["high"], mode: ["yolo"] },
24
- provenance: { kind: "reviewed-seed", source: "https://github.com/deksden-com/dd-eval/blob/9715970544096fc0288ac8e18f95d4e35997be54/profiles/zcode-acp-zai-glm-5-3-high.json",
25
- reviewed_at: "2026-10-07T00:00:00Z" }, availability: "not-observed", qualification: { scope: "seed-only", evidence: null } },
26
- { harness: "opencode", provider: "opencode", model: "big-pickle",
27
- settings: { reasoning: ["default"], mode: ["build"] },
28
- provenance: { kind: "reviewed-seed", source: "https://github.com/deksden-com/dd-eval/blob/9715970544096fc0288ac8e18f95d4e35997be54/profiles/opencode-server-opencode-big-pickle-default.json",
29
- reviewed_at: "2026-10-07T00:00:00Z" }, availability: "not-observed", qualification: { scope: "seed-only", evidence: null } },
30
- { harness: "droid", provider: "openai", model: "gpt-5.6-sol",
31
- settings: { reasoning: ["high"], mode: ["auto-high"] },
32
- provenance: { kind: "reviewed-seed", source: "https://github.com/deksden-com/dd-eval/blob/9715970544096fc0288ac8e18f95d4e35997be54/profiles/droid-cli-openai-gpt-5-6-sol-high.json",
33
- reviewed_at: "2026-10-07T00:00:00Z" }, availability: "not-observed", qualification: { scope: "seed-only", evidence: null } }]
34
- };
35
- const families = ["codex", "zcode", "agy", "opencode", "grok", "droid"];
36
- const identifier = (value, max = 128) => typeof value === "string" && value.length <= max && /^[A-Za-z0-9][A-Za-z0-9._:/+-]*$/.test(value);
37
- const providerId = (value) => typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value);
38
- function invalid() {
39
- throw new AppError("model_catalog_input", "Model catalog input requires reviewed seed data and an explicit observation scope; see dd-flow models --help", 2, { effect: "no_effect", help: "models" });
40
- }
41
- function readJson(file) {
42
- let bytes;
43
- try {
44
- bytes = readBoundedReleaseFile(file, 4 * 1024 * 1024);
45
- }
46
- catch {
47
- throw new AppError("model_input_unavailable", "Model input must be a bounded readable regular file; see dd-flow models --help", 1, { effect: "no_effect", help: "models" });
48
- }
49
- try {
50
- return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
51
- }
52
- catch {
53
- return invalid();
54
- }
55
- }
56
- export function readModelSeed(file) {
57
- const input = file === undefined ? structuredClone(seed) : readJson(file);
58
- if (validateHybridContract("model-catalog", input).length)
59
- invalid();
60
- const catalog = input;
61
- if (catalog.entries.length > 10_000 || catalog.entries.some(entry => {
62
- let source;
63
- try {
64
- source = new URL(entry.provenance.source);
65
- }
66
- catch {
67
- return true;
68
- }
69
- const reviewed = entry.provenance.reviewed_at;
70
- return entry.qualification.scope !== "seed-only" || !providerId(entry.provider) || !identifier(entry.model, 256)
71
- || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(reviewed) || !Number.isFinite(Date.parse(reviewed))
72
- || new Date(reviewed).toISOString() !== reviewed.replace(/Z$/, reviewed.includes(".") ? "Z" : ".000Z")
73
- || source.protocol !== "https:" || source.username !== "" || source.password !== "" || source.search !== ""
74
- || entry.provenance.source.length > 2048
75
- || [...entry.settings.reasoning, ...entry.settings.mode].some(value => !identifier(value, 64));
76
- }))
77
- invalid();
78
- return structuredClone(catalog);
79
- }
80
- /** Offline reader only. A supplied snapshot is an observation, not account authorization. */
81
- export function listOperatorModels(input) {
82
- if (input.harness !== undefined && !families.includes(input.harness) || input.provider !== undefined && !providerId(input.provider)
83
- || input.model !== undefined && !identifier(input.model, 256)
84
- || input.accountSha256 !== undefined && !/^[a-f0-9]{64}$/.test(input.accountSha256)
85
- || (input.accountSha256 !== undefined || input.observationFile !== undefined) && (!input.harness || !input.provider || !input.accountSha256))
86
- invalid();
87
- // Validate all selectors before opening operator files.
88
- const catalog = readModelSeed(input.seedFile);
89
- let entries, reason, observedAt = null;
90
- if (input.accountSha256) {
91
- const scope = { harness: input.harness, provider: input.provider, account_sha256: input.accountSha256 };
92
- const observation = input.observationFile === undefined ? undefined : readJson(input.observationFile);
93
- const merged = mergeModelListing(catalog, scope, observation);
94
- entries = merged.entries.map(entry => ({ harness: scope.harness, provider: scope.provider, ...entry }));
95
- reason = merged.reason;
96
- observedAt = merged.observed_at;
97
- }
98
- else {
99
- entries = catalog.entries.filter(entry => (!input.harness || entry.harness === input.harness) && (!input.provider || entry.provider === input.provider))
100
- .map(entry => ({ harness: entry.harness, provider: entry.provider, model: entry.model, seed: structuredClone(entry),
101
- availability: "unknown", account_access: "unknown", qualified: "unknown" }));
102
- reason = "account_scope_not_selected";
103
- }
104
- if (input.model)
105
- entries = entries.filter(entry => entry.model === input.model);
106
- return { catalog_version: catalog.version, observed_at: observedAt, reason, entries,
107
- families: families.map(harness => ({ harness, seed_status: catalog.entries.some(entry => entry.harness === harness) ? "reviewed_entries" : "not_curated",
108
- account_access: "unknown", qualified: "unknown" })) };
109
- }