@deksden-com/dd-flow-cli 0.9.0-beta.145 → 0.9.0-beta.149

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 (101) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/build-info.json +7 -7
  3. package/dist/cli/command-inputs.js +6 -2
  4. package/dist/cli/command-metadata.js +18 -2
  5. package/dist/cli/diagnostic-invocation.js +46 -0
  6. package/dist/cli/diagnostic.js +120 -0
  7. package/dist/cli/help.js +35 -0
  8. package/dist/cli/memory-flow-admission.js +4 -2
  9. package/dist/cli/memory-init.js +5 -2
  10. package/dist/cli/run-cli.js +16 -15
  11. package/dist/cli.js +6 -0
  12. package/dist/domain/diagnostic-aspects.js +103 -0
  13. package/dist/domain/diagnostic-flows.js +8 -0
  14. package/dist/harness-runtime/lib/agy-native-inspection.mjs +216 -0
  15. package/dist/harness-runtime/lib/agy-native_pb.js +117 -0
  16. package/dist/harness-runtime/lib/daemon-operations.d.mts +1 -0
  17. package/dist/harness-runtime/lib/daemon-operations.mjs +84 -10
  18. package/dist/harness-runtime/lib/dd-agy-daemon.mjs +306 -34
  19. package/dist/harness-runtime/lib/dd-codex-daemon.mjs +27 -13
  20. package/dist/harness-runtime/lib/dd-codex.mjs +4 -0
  21. package/dist/harness-runtime/lib/dd-droid-daemon.mjs +4 -3
  22. package/dist/harness-runtime/lib/dd-droid.mjs +70 -28
  23. package/dist/harness-runtime/lib/dd-grok-daemon.mjs +3 -3
  24. package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +66 -20
  25. package/dist/harness-runtime/lib/dd-opencode.mjs +30 -3
  26. package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +7 -6
  27. package/dist/harness-runtime/lib/driver-recovery.mjs +9 -8
  28. package/dist/harness-runtime/lib/managed-daemon.d.mts +1 -1
  29. package/dist/harness-runtime/lib/managed-daemon.mjs +11 -3
  30. package/dist/harness-runtime/lib/native-children.d.mts +8 -1
  31. package/dist/harness-runtime/lib/native-children.mjs +114 -8
  32. package/dist/harness-runtime/lib/native-request-proof.mjs +1 -1
  33. package/dist/harness-runtime/lib/observation-clock.d.mts +2 -2
  34. package/dist/harness-runtime/lib/observation-clock.mjs +7 -4
  35. package/dist/harness-runtime/lib/provider-overload-policy.d.mts +1 -1
  36. package/dist/harness-runtime/lib/provider-overload-policy.mjs +1 -1
  37. package/dist/harness-runtime/lib/tool-observations.mjs +1 -1
  38. package/dist/schemas/diagnostic-stage-result.schema.json +354 -0
  39. package/dist/schemas/diagnostic-work-result.schema.json +296 -0
  40. package/dist/schemas/execution-bundle.schema.json +7 -1
  41. package/dist/schemas/project-flow-pack-manifest.schema.json +1 -1
  42. package/dist/services/check-environment.js +21 -0
  43. package/dist/services/check-runner-evidence.js +267 -15
  44. package/dist/services/code-checks.js +23 -15
  45. package/dist/services/controller-execution.js +10 -4
  46. package/dist/services/controller-fanout.js +13 -6
  47. package/dist/services/controller-memory-worker.js +3 -2
  48. package/dist/services/dashboard.js +2 -2
  49. package/dist/services/descriptor-run-settlement.js +5 -3
  50. package/dist/services/descriptor-run-start.js +22 -3
  51. package/dist/services/descriptor-stage-coordinator.js +37 -4
  52. package/dist/services/descriptor-stage-settlement.js +2 -1
  53. package/dist/services/diagnostic-evidence.js +73 -0
  54. package/dist/services/diagnostic-report-publication.js +72 -0
  55. package/dist/services/diagnostic-report.js +67 -0
  56. package/dist/services/diagnostic-run-bundle.js +74 -0
  57. package/dist/services/diagnostic-snapshot.js +159 -0
  58. package/dist/services/diagnostic-stage-handlers.js +108 -0
  59. package/dist/services/diagnostic-stage-results.js +132 -0
  60. package/dist/services/diagnostic-start.js +84 -0
  61. package/dist/services/diagnostic-work-batch.js +34 -0
  62. package/dist/services/diagnostic-work-collection.js +97 -0
  63. package/dist/services/diagnostic-work-registration.js +101 -0
  64. package/dist/services/diagnostic-work-results.js +93 -0
  65. package/dist/services/eval-snapshots.js +85 -29
  66. package/dist/services/execution-bundles.js +19 -7
  67. package/dist/services/flow-catalog.js +6 -1
  68. package/dist/services/frozen-engine.js +37 -2
  69. package/dist/services/hybrid-contracts.js +2 -0
  70. package/dist/services/installed-flow-source.js +25 -3
  71. package/dist/services/lifecycle-invocations.js +147 -34
  72. package/dist/services/memory-init-contexts.js +16 -0
  73. package/dist/services/memory-init-controller-start.js +12 -4
  74. package/dist/services/memory-init-lint-capability.js +5 -5
  75. package/dist/services/memory-init-native-capacity.js +4 -4
  76. package/dist/services/memory-init-preflight.js +10 -16
  77. package/dist/services/memory-init-worktrunk-capability.js +3 -7
  78. package/dist/services/memory-layer.js +4 -3
  79. package/dist/services/memory-tool-probe.js +25 -0
  80. package/dist/services/memory-verification-checks.js +15 -4
  81. package/dist/services/native-daemon-history.js +2 -1
  82. package/dist/services/provider-capacity.js +43 -38
  83. package/dist/services/release-cache.js +8 -0
  84. package/dist/services/run-control.js +2 -1
  85. package/dist/services/run-controller-adapter.js +2 -1
  86. package/dist/services/run-controller-process.js +2 -1
  87. package/dist/services/run-controller-recovery.js +2 -1
  88. package/dist/services/run-controller.js +85 -15
  89. package/dist/services/run-fork.js +1 -1
  90. package/dist/services/runs.js +6 -1
  91. package/dist/services/runtime-scope-resume.js +12 -6
  92. package/dist/services/runtime-scope-stop.js +3 -2
  93. package/dist/services/runtime-service.js +2 -1
  94. package/dist/services/stage-handlers.js +16 -3
  95. package/dist/services/stage-pause.js +4 -1
  96. package/dist/services/version-status.js +1 -1
  97. package/dist/services/vnext-code.js +2 -2
  98. package/dist/services/vnext-fanout.js +31 -1
  99. package/dist/services/work-registry.js +37 -6
  100. package/dist/services/workspace-bootstrap.js +2 -1
  101. package/package.json +6 -3
@@ -40,6 +40,8 @@ import { acceptedDecisionPrecedence, loadExternalStageContext, renderRetainedSta
40
40
  import { reviewEnvironmentAllowed, reviewExecutionCopyHash, reviewSourceHash, reviewSourcePaths } from "./review-copy.js";
41
41
  import { latestRunVerificationMatrix, verificationMatrixInstruction, verificationMatrixContract } from "./verification-matrix.js";
42
42
  import { acceptedIntentSourceRole } from "./accepted-intent.js";
43
+ import { isDiagnosticFlow } from "../domain/diagnostic-flows.js";
44
+ import { validateDiagnosticWorkResult } from "./diagnostic-work-results.js";
43
45
  const workColumns = "work_id, project_id, run_id, parent_work_id, task, launch_policy, result_schema, payload_json, depends_on_json, status, result, created_at, started_at, updated_at, completed_at";
44
46
  export function ensureWorkRegistry(context) { context.db.get("SELECT 1 FROM works LIMIT 1"); context.db.get("SELECT 1 FROM work_sessions LIMIT 1"); }
45
47
  function ownsPhysicalWorkSession(context, projectId, owner, identity) {
@@ -189,6 +191,8 @@ export function validateWorkBatch(value) {
189
191
  export function assertGenericWorkBatchAllowed(context, parentWorkId) {
190
192
  const parent = requireWork(context, parentWorkId);
191
193
  const run = context.db.get("SELECT flow_kind FROM runs WHERE project_id=? AND id=?", [parent.project_id, parent.run_id]);
194
+ if (run && isDiagnosticFlow(run.flow_kind))
195
+ throw new AppError("diagnostic_work_registration_required", "Diagnostic Stage handlers register the assigned read-only graph; generic allocation is not supported", 2, { phase: "prepare", effect: "no_effect", next_action: "use_issued_stage_entry" });
192
196
  if (run && ["mb-init", "mb-upgrade"].includes(run.flow_kind))
193
197
  throw new AppError("memory_work_registration_required", "Use the issued memory compose/review/corrections registration, not generic work add-batch", 2, { phase: "prepare", effect: "no_effect", recoverable: true, next_action: "use_issued_memory_registration" });
194
198
  }
@@ -752,7 +756,7 @@ function preparedCoordinatorRoute(context, work, input, snapshot) {
752
756
  // independently retained RUN authority fences it again without compiling
753
757
  // descriptor schemas under this (possibly caller-owned) SQL writer.
754
758
  assertPreparedRunBundleSqlAuthority(context, { projectId: work.project_id, runId: work.run_id }, admitted.bundle);
755
- if (admitted.bundle.descriptor.descriptor.id === "mb-init") {
759
+ if (admitted.bundle.descriptor.descriptor.id === "mb-init" || isDiagnosticFlow(admitted.bundle.descriptor.descriptor.id)) {
756
760
  const retained = readDescriptorStageInput(context, { projectId: work.project_id, runId: work.run_id, stage: input.stage }, admitted.bundle);
757
761
  const payload = retained.input.payload_base64;
758
762
  if (typeof payload !== "string")
@@ -1092,7 +1096,7 @@ export function finishStageCoordinatorWork(context, id, result) {
1092
1096
  const link = context.db.get("SELECT * FROM work_sessions WHERE work_id = ? AND status = 'running' ORDER BY created_at DESC LIMIT 1", [id]);
1093
1097
  if (!link)
1094
1098
  throw new AppError("runtime_missing", "Coordinator has no open Work/Session link", 1);
1095
- validateWorkResult(work, result, run.project_root, run.workspace_root, requireRunHome(run), run.id, link.result_path);
1099
+ validateWorkResult(context, work, result, run.project_root, run.workspace_root, requireRunHome(run), run.id, link.result_path);
1096
1100
  finishFanInWork(context, id, result);
1097
1101
  context.db.run("UPDATE sessions SET status = 'idle', updated_at = ? WHERE project_id = ? AND session_id = ? AND NOT EXISTS (SELECT 1 FROM work_sessions WHERE session_id = ? AND status = 'running')", [context.now(), work.project_id, link.session_id, link.session_id]);
1098
1102
  settleRecoveryWork(context, id, "completed");
@@ -1538,7 +1542,7 @@ async function settle(context, id, status, result, progress, retry, memoryResult
1538
1542
  else {
1539
1543
  if (memoryResult)
1540
1544
  throw new AppError("memory_work_result_preparation_required", "Prepared memory output cannot settle another Work schema", 1);
1541
- validateWorkResult(work, result, run.project_root, run.workspace_root, requireRunHome(run), run.id, link?.result_path ?? null);
1545
+ validateWorkResult(context, work, result, run.project_root, run.workspace_root, requireRunHome(run), run.id, link?.result_path ?? null);
1542
1546
  }
1543
1547
  const packet = codePacket(work);
1544
1548
  if (packet) {
@@ -1665,7 +1669,7 @@ function reactivateBoundSession(context, projectId, sessionId, now) {
1665
1669
  }
1666
1670
  export function workResultByteLimit(context, id) {
1667
1671
  const schema = requireWork(context, id).result_schema;
1668
- return ["dd-flow/memory-composition-work-result@1", "dd-flow/memory-review-work-result@1", "dd-flow/memory-repair-work-result@1"].includes(schema ?? "") ? 1024 * 1024 : undefined;
1672
+ return ["dd-flow/memory-composition-work-result@1", "dd-flow/memory-review-work-result@1", "dd-flow/memory-repair-work-result@1", "dd-flow/diagnostic-work-result@1"].includes(schema ?? "") ? 1024 * 1024 : undefined;
1669
1673
  }
1670
1674
  export function prepareWorkResult(context, id, result, progress) {
1671
1675
  try {
@@ -1685,16 +1689,23 @@ export function prepareWorkResult(context, id, result, progress) {
1685
1689
  memoryResult.assertSettlementScope(context, link.session_id, link.id);
1686
1690
  return;
1687
1691
  }
1688
- validateWorkResult(work, result, run.project_root, run.workspace_root, requireRunHome(run), run.id, link?.result_path ?? null);
1692
+ validateWorkResult(context, work, result, run.project_root, run.workspace_root, requireRunHome(run), run.id, link?.result_path ?? null);
1689
1693
  }
1690
1694
  catch (error) {
1691
1695
  prepareError(error, { work_id: id, input_sha256: sha256(result) });
1692
1696
  }
1693
1697
  }
1694
- function validateWorkResult(work, result, projectRoot, workspaceRoot, runHome, runId, resultPath) {
1698
+ function validateWorkResult(context, work, result, projectRoot, workspaceRoot, runHome, runId, resultPath) {
1695
1699
  assertMemoryRepairWritePrepared(work);
1696
1700
  if (!work.result_schema)
1697
1701
  return;
1702
+ if (work.result_schema === "dd-flow/diagnostic-work-result@1") {
1703
+ const { bundle, packet } = diagnosticWorkAuthority(context, work, projectRoot);
1704
+ if (typeof packet.aspect_id !== "string" || !["aspect", "critic"].includes(String(packet.role)))
1705
+ throw new AppError("diagnostic_work_input_invalid", "Diagnostic Work has no assigned role/aspect", 1, { effect: "no_effect" });
1706
+ validateDiagnosticWorkResult(Buffer.from(result), bundle.blob("schemas/diagnostic-work-result.schema.json"), workspaceRoot, packet, { workId: work.work_id, aspectId: packet.aspect_id, role: packet.role });
1707
+ return;
1708
+ }
1698
1709
  if (["dd-flow/memory-composition-work-result@1", "dd-flow/memory-review-work-result@1"].includes(work.result_schema ?? ""))
1699
1710
  throw new AppError("memory_work_result_preparation_required", "Memory Work completion requires admitted registered output, not a mutable schema lookup", 1);
1700
1711
  if (!resultPath)
@@ -1829,9 +1840,29 @@ export function validateReviewResolutions(workId, assigned, resolutions) {
1829
1840
  if (missing.length || unexpected.length || duplicate)
1830
1841
  throw new AppError("review_repair_incomplete", "Review repair must include exactly one resolution for each assigned finding reference", 2, { work_id: workId, missing, unexpected, duplicate });
1831
1842
  }
1843
+ function diagnosticWorkAuthority(context, work, projectRoot) {
1844
+ const custody = readWorkBatchCustody(context, work.work_id);
1845
+ const bundle = readFlowRunExecutionBundle(context, { projectRoot, runId: work.run_id });
1846
+ const payload = parsePayload(work), packet = payload?.diagnostic;
1847
+ if (!bundle || !isDiagnosticFlow(bundle.manifest.flow_id) || !packet || payload?.read_only !== true
1848
+ || !["diagnostic-aspect", "diagnostic-critic"].includes(String(payload.kind))
1849
+ || packet.flow_id !== bundle.manifest.flow_id || packet.run_id !== work.run_id || packet.stage !== custody.scope.stage
1850
+ || packet.key !== custody.item_key || packet.packet_sha256 !== hybridDigest({ ...packet, packet_sha256: undefined }))
1851
+ throw new AppError("diagnostic_work_input_invalid", "Diagnostic Work requires its immutable registered assignment", 1, { effect: "no_effect" });
1852
+ assertPreparedRunBundleSqlAuthority(context, { projectId: work.project_id, runId: work.run_id }, bundle);
1853
+ return { bundle, packet };
1854
+ }
1832
1855
  function renderWorkerPrompt(context, work, run, dependencies, commands, workspaceView, reviewInput) {
1833
1856
  const payload = parsePayload(work);
1834
1857
  const runIndex = JSON.parse(context.db.get("SELECT index_json FROM runs WHERE project_id=? AND id=?", [work.project_id, work.run_id]).index_json);
1858
+ if (isDiagnosticFlow(runIndex.execution_bundle?.flow_id)) {
1859
+ assertRunBundleSqlAuthority(context, { projectId: work.project_id, runId: work.run_id }, runIndex.execution_bundle);
1860
+ const { bundle, packet } = diagnosticWorkAuthority(context, work, run.project_root);
1861
+ return ["<diagnostic_work_packet>", JSON.stringify(packet, null, 2), "</diagnostic_work_packet>", "",
1862
+ "<frozen_work_result_schema>", bundle.blob("schemas/diagnostic-work-result.schema.json").toString("utf8"), "</frozen_work_result_schema>", "",
1863
+ "The packet is the assigned read-only diagnostic task, not an SDLC CODE or repair task. Report uncertainty and all assigned candidate decisions without editing the snapshot or original project.",
1864
+ renderWorkerPromptBody(context, work, run, dependencies, commands)].join("\n");
1865
+ }
1835
1866
  if (["mb-init", "mb-upgrade"].includes(runIndex.execution_bundle?.flow_id) && (payload?.memory_composition || payload?.kind === "memory-review" || payload?.kind === "memory-repair")) {
1836
1867
  assertRunBundleSqlAuthority(context, { projectId: work.project_id, runId: work.run_id }, runIndex.execution_bundle);
1837
1868
  // Memory Work owns a descriptor packet, not a missing SDLC SPECIFY or PLAN.
@@ -2,6 +2,7 @@ import crypto from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { AppError } from "../shared/errors.js";
5
+ import { retainedBrowserEnvironment } from "./check-environment.js";
5
6
  import { assertRunMutationAllowed } from "./run-recovery.js";
6
7
  import { codeExecutionEnvironment, reconcileWorkspaceOwnership, runCheck, workspaceOperationId } from "./code-checks.js";
7
8
  import { confirmManagedProcess, finishManagedProcess, renewManagedProcess, managedOwnerIsAlive, managedProcessStatus, processTreeIsAlive, registerManagedProcess } from "./managed-processes.js";
@@ -56,7 +57,7 @@ export async function runWorkspaceBootstrap(context, input) {
56
57
  finishManagedProcess(context, { id: managed.id, leaseToken: managed.lease_token, state: "failed", reason: "dispatch_fenced_before_spawn" });
57
58
  throw error;
58
59
  }
59
- const completed = await runCheck(input.command, input.workspaceRoot, { ...codeExecutionEnvironment(input.workspaceRoot), DD_FLOW_CHECK_COMPLETION_FILE: completionPath }, stdout, stderr, elapsed => input.progress?.(`workspace bootstrap still running (${elapsed}s); logs: ${directory}; next report in 15s`), pid => confirmManagedProcess(context, { id: managed.id, leaseToken: managed.lease_token, pid, processGroupId: process.platform === "win32" ? null : pid }), attemptMs => renewManagedProcess({ ...context, resourceDatabaseMode: "prepared_existing", databaseDeadlineAt: Date.now() + attemptMs }, { id: managed.id, leaseToken: managed.lease_token }));
60
+ const completed = await runCheck(input.command, input.workspaceRoot, { ...codeExecutionEnvironment(input.workspaceRoot, retainedBrowserEnvironment(context.env)), DD_FLOW_CHECK_COMPLETION_FILE: completionPath }, stdout, stderr, elapsed => input.progress?.(`workspace bootstrap still running (${elapsed}s); logs: ${directory}; next report in 15s`), pid => confirmManagedProcess(context, { id: managed.id, leaseToken: managed.lease_token, pid, processGroupId: process.platform === "win32" ? null : pid }), attemptMs => renewManagedProcess({ ...context, resourceDatabaseMode: "prepared_existing", databaseDeadlineAt: Date.now() + attemptMs }, { id: managed.id, leaseToken: managed.lease_token }));
60
61
  const current = managedProcessStatus(context).find(item => item.id === managed.id);
61
62
  if (processTreeIsAlive(current))
62
63
  throw new AppError("bootstrap_tree_not_settled", "Bootstrap shell exited but still owns live processes; resources were retained for inspection", 2, { process_id: managed.id, stdout_path: stdoutPath, stderr_path: stderrPath });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deksden-com/dd-flow-cli",
3
- "version": "0.9.0-beta.145",
3
+ "version": "0.9.0-beta.149",
4
4
  "description": "Mechanical runtime CLI for dd-flow workflows.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.23.0",
@@ -53,10 +53,11 @@
53
53
  "release:canon:archive": "node tools/create-canon-release.mjs"
54
54
  },
55
55
  "devDependencies": {
56
- "@opencode/client": "2.0.28",
57
- "@opencode/plugin": "2.0.28",
56
+ "@bufbuild/protoc-gen-es": "2.16.0",
58
57
  "@changesets/cli": "^2.31.0",
59
58
  "@eslint/js": "^9.39.1",
59
+ "@opencode/client": "2.0.28",
60
+ "@opencode/plugin": "2.0.28",
60
61
  "@types/node": "^24.10.1",
61
62
  "@types/semver": "7.8.0",
62
63
  "eslint": "^9.39.1",
@@ -65,6 +66,8 @@
65
66
  "vitest": "^4.0.13"
66
67
  },
67
68
  "dependencies": {
69
+ "@bufbuild/protobuf": "2.16.0",
70
+ "@grpc/grpc-js": "1.14.6",
68
71
  "ajv": "^8.20.0",
69
72
  "jsonc-parser": "3.3.1",
70
73
  "semver": "7.8.1",