@deksden-com/dd-flow-cli 0.9.0-beta.51 → 0.9.0-beta.52
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @deksden-com/dd-flow-cli
|
|
2
2
|
|
|
3
|
+
## 0.9.0-beta.52
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Distinguish released workspace leases from physical processes during stage-boundary capture, RUN settlement and runtime-scope stop/drain. Preserve active-lease, child-process, physical-identity and exact registration checks instead of waiting forever for a PID on a logical gate.
|
|
8
|
+
|
|
3
9
|
## 0.9.0-beta.51
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/build-info.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"cli_package": "@deksden-com/dd-flow-cli",
|
|
3
|
-
"cli_version": "0.9.0-beta.
|
|
4
|
-
"cli_commit": "
|
|
5
|
-
"built_at": "2026-09-
|
|
3
|
+
"cli_version": "0.9.0-beta.52",
|
|
4
|
+
"cli_commit": "9f8e20f5aab016e2e7246b8939af9e4ad91e37dc",
|
|
5
|
+
"built_at": "2026-09-12T14:24:25.044Z",
|
|
6
6
|
"built_with_canon": {
|
|
7
7
|
"version": "4.1.0",
|
|
8
8
|
"commit": "ef349bf47cba1c987468e51d73a0dbadbd48dc1f",
|
|
@@ -175,6 +175,13 @@ export function claimExpiredManagedProcesses(context, ownerId) {
|
|
|
175
175
|
throw error;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
+
/** Workspace gates are leases, not spawned processes. Children retain their own registrations. */
|
|
179
|
+
export function managedLeaseReleased(record) {
|
|
180
|
+
const metadata = parseMetadata(record.metadata_json);
|
|
181
|
+
return record.kind === "workspace-gate" && record.pid === null && record.pid_started_at === null
|
|
182
|
+
&& metadata.process_group_id == null && metadata.role === "check_gate"
|
|
183
|
+
&& ["stopped", "failed"].includes(record.state) && Boolean(record.finished_at);
|
|
184
|
+
}
|
|
178
185
|
export function managedProcessStatus(context) {
|
|
179
186
|
return registry(context).all("SELECT * FROM managed_processes ORDER BY updated_at DESC, id");
|
|
180
187
|
}
|
|
@@ -9,7 +9,7 @@ import path from "node:path";
|
|
|
9
9
|
import { adapterSessionId, runHarnessAdapter } from "./harness-adapter.js";
|
|
10
10
|
import { runtimeHarness } from "./execution-policy.js";
|
|
11
11
|
import { harnessKey } from "./harness-config.js";
|
|
12
|
-
import { finishManagedProcess, managedProcessBinding, managedProcessRuntimeHome, managedProcessStatus, processIsAlive, processTreeIsAlive, resourceHome, stopManagedProcess } from "./managed-processes.js";
|
|
12
|
+
import { finishManagedProcess, managedLeaseReleased, managedProcessBinding, managedProcessRuntimeHome, managedProcessStatus, processIsAlive, processTreeIsAlive, resourceHome, stopManagedProcess } from "./managed-processes.js";
|
|
13
13
|
import { reconcileUnfinishedChecks } from "./code-checks.js";
|
|
14
14
|
import { controlStatusReceipt } from "./run-control-receipt.js";
|
|
15
15
|
import { assertNativeCancellationReceipt, cancelControlledNativeSession, inspectControlledNativeSession } from "./native-session-control.js";
|
|
@@ -473,6 +473,10 @@ async function reconcileOwnedSessions(context, input, interrupt, boundary) {
|
|
|
473
473
|
}
|
|
474
474
|
}));
|
|
475
475
|
const processResults = Promise.all(processTargets.map(async ({ home, record }) => {
|
|
476
|
+
if (managedLeaseReleased(record))
|
|
477
|
+
return { process_id: record.id, kind: record.kind, status: "completed", receipt: { source: "managed_lease_released", ...managedProcessBinding(record, home), finished_at: record.finished_at } };
|
|
478
|
+
if (record.kind === "workspace-gate")
|
|
479
|
+
return { process_id: record.id, kind: record.kind, status: "pending", reason: "managed_lease_unsettled" };
|
|
476
480
|
if (!record.pid || !record.pid_started_at)
|
|
477
481
|
return { process_id: record.id, kind: record.kind, status: "pending", reason: "managed_process_identity_unknown" };
|
|
478
482
|
if (!interrupt && processTreeIsAlive(record))
|
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { createContext } from "../runtime/context.js";
|
|
5
5
|
import { getResourceDatabase } from "../storage/database.js";
|
|
6
6
|
import { AppError } from "../shared/errors.js";
|
|
7
|
-
import { finishManagedProcess, managedProcessBinding, managedProcessStatus, processTreeIsAlive, resourceHome, stopManagedProcess } from "./managed-processes.js";
|
|
7
|
+
import { finishManagedProcess, managedLeaseReleased, managedProcessBinding, managedProcessStatus, processTreeIsAlive, resourceHome, stopManagedProcess } from "./managed-processes.js";
|
|
8
8
|
import { requestRuntimeScopeControl, runtimeBudgetStatus, scopeLocalProcessRole, validateRuntimeScopeManifest } from "./runtime-budget.js";
|
|
9
9
|
import { nativeInventoryVersion, recordRunControlIntent, retainedDaemonOperations, runControlStatus } from "./run-control.js";
|
|
10
10
|
import { requestRunControl } from "./run-control-worker.js";
|
|
@@ -125,7 +125,7 @@ export function retainScopeDrain(context, control, processes, runs, native, prob
|
|
|
125
125
|
}
|
|
126
126
|
export function scopeRunProcessEvidence(record, runs, registryHome) {
|
|
127
127
|
const metadata = JSON.parse(record.metadata_json);
|
|
128
|
-
if (!record.pid || !record.pid_started_at || !record.project_id || !record.run_id || !metadata.dd_flow_home)
|
|
128
|
+
if ((!managedLeaseReleased(record) && (!record.pid || !record.pid_started_at)) || !record.project_id || !record.run_id || !metadata.dd_flow_home)
|
|
129
129
|
return null;
|
|
130
130
|
for (const run of runs) {
|
|
131
131
|
if (run.runtime_home !== metadata.dd_flow_home || run.project_id !== record.project_id || run.run_id !== record.run_id)
|
|
@@ -3,7 +3,7 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { AppError } from "../shared/errors.js";
|
|
5
5
|
import { runHarnessAdapter } from "./harness-adapter.js";
|
|
6
|
-
import { managedProcessBinding, managedProcessStatus, processIsAlive, processTreeIsAlive, resourceHome, stopManagedProcess } from "./managed-processes.js";
|
|
6
|
+
import { managedLeaseReleased, managedProcessBinding, managedProcessStatus, processIsAlive, processTreeIsAlive, resourceHome, stopManagedProcess } from "./managed-processes.js";
|
|
7
7
|
import { fenceRuntimeBudget, runtimeBudgetStatus, scopeLocalProcessRole } from "./runtime-budget.js";
|
|
8
8
|
import { retainedDaemonOperations } from "./run-control.js";
|
|
9
9
|
import { historicalDaemonSettlement } from "./native-daemon-history.js";
|
|
@@ -62,6 +62,10 @@ export async function stopRuntimeScope(context, scopeId, requestId) {
|
|
|
62
62
|
for (const record of runtimeBudgetStatus(context, scopeId).processes) {
|
|
63
63
|
if (covered.has(record.id))
|
|
64
64
|
continue;
|
|
65
|
+
if (managedLeaseReleased(record)) {
|
|
66
|
+
nodes.push({ process_id: record.id, settled: true });
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
65
69
|
const metadata = JSON.parse(record.metadata_json);
|
|
66
70
|
// RUN control owns active controllers/checks. Adopt only its already-finished
|
|
67
71
|
// physical registrations here; death alone is not a completed RUN operation.
|