建立ToolDbProcessPort合约层

结论:已新增ToolDbProcessPort合约、OPFS tool DB flat-file/transcript store和Node/WASM gates,baseline保持28/28/131/0且promotion继续锁定。
This commit is contained in:
2026-06-19 06:36:26 +08:00
parent d9ac3770a7
commit d8e0196c61
13 changed files with 711 additions and 0 deletions

View File

@@ -90,6 +90,9 @@ import {
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
createProjectReleaseReadinessReport,
createProjectReleaseReadinessSummaryViewModel,
createLinuxCncToolDbProcessPort,
createToolDbProcessDiagnostics,
createToolDbTransactionPlan,
createVirtualHalBridgeActionPlan,
createVirtualHalBridgeReadiness,
createVirtualHalCommandScriptFixtureReport,
@@ -153,6 +156,8 @@ import {
loadMachineSessionSnapshot,
loadMachineTextFiles,
loadMachineToolTableFromOpfs,
loadToolDbFile,
loadToolDbTranscript,
loadTextFile,
machineFilePaths,
machineIniPath,
@@ -172,7 +177,13 @@ import {
saveSessionSnapshot,
saveTextFile,
sessionSnapshotPath,
saveToolDbFile,
saveToolDbTranscript,
toolDbFilePath,
toolDbRootPath,
toolDbTranscriptPath,
toolTablePath,
validateToolDbTranscript,
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
validateSessionSnapshot,
} from "../../../runtime/sdk/src/index.js";
@@ -490,6 +501,9 @@ const requiredExports = [
["loadTextFile", loadTextFile],
["machineIniPath", machineIniPath],
["toolTablePath", toolTablePath],
["toolDbRootPath", toolDbRootPath],
["toolDbFilePath", toolDbFilePath],
["toolDbTranscriptPath", toolDbTranscriptPath],
["parameterFilePath", parameterFilePath],
["gcodeProgramPath", gcodeProgramPath],
["sessionSnapshotPath", sessionSnapshotPath],
@@ -507,6 +521,14 @@ const requiredExports = [
["saveMachineTextFiles", saveMachineTextFiles],
["loadMachineTextFiles", loadMachineTextFiles],
["gcodeFilenameFromProgramPath", gcodeFilenameFromProgramPath],
["createLinuxCncToolDbProcessPort", createLinuxCncToolDbProcessPort],
["createToolDbProcessDiagnostics", createToolDbProcessDiagnostics],
["createToolDbTransactionPlan", createToolDbTransactionPlan],
["validateToolDbTranscript", validateToolDbTranscript],
["saveToolDbFile", saveToolDbFile],
["loadToolDbFile", loadToolDbFile],
["saveToolDbTranscript", saveToolDbTranscript],
["loadToolDbTranscript", loadToolDbTranscript],
["restoreMachineParametersFromOpfs", restoreMachineParametersFromOpfs],
["loadMachineToolTableFromOpfs", loadMachineToolTableFromOpfs],
["loadMachineSessionFromOpfs", loadMachineSessionFromOpfs],

View File

@@ -0,0 +1,95 @@
import assert from "node:assert/strict";
import {
TOOL_DB_PROCESS_PORT_CONTRACT_VERSION,
TOOL_DB_TRANSACTION_PLAN,
createLinuxCncToolDbProcessPort,
createToolDbProcessDiagnostics,
createToolDbTransactionPlan,
validateToolDbTranscript,
} from "../../../runtime/sdk/src/tool-db-process-port.js";
assert.equal(TOOL_DB_PROCESS_PORT_CONTRACT_VERSION, 1);
assert.deepEqual(
createToolDbTransactionPlan().map((step) => step.phase),
[
"startup_handshake",
"initial_get_all",
"tool_offset_notify",
"spindle_load_notify",
"spindle_unload_notify",
],
);
assert.equal(TOOL_DB_TRANSACTION_PLAN[0].expect, "v2.1");
assert.equal(TOOL_DB_TRANSACTION_PLAN.every((step) => step.requiresFini || step.phase === "startup_handshake"), true);
const port = createLinuxCncToolDbProcessPort({
dbProgramPath: "./db_nonran.py",
sourceFiles: [
"configs/sim/axis/db_demo/db_nonran.py",
"configs/sim/axis/db_demo/db.py",
"lib/python/tooldb.py",
],
runtimeMode: "contract-only",
});
const startResult = await port.start();
assert.deepEqual(startResult, {
runtimeMode: "contract-only",
runtimeExecutionReady: false,
executionEnabled: false,
promotionAllowed: false,
});
const blockedPlan = await port.runTransactionPlan();
assert.equal(blockedPlan.status, "blocked_runtime_adapter_required");
assert.equal(blockedPlan.runtimeExecutionReady, false);
assert.equal(blockedPlan.executionEnabled, false);
assert.equal(blockedPlan.promotionAllowed, false);
assert.equal(blockedPlan.tblFallbackSufficient, false);
const transcript = [
{ direction: "read", line: "v2.1" },
{ direction: "write", line: "g" },
{ direction: "read", line: "T10 P110 D0.10 Z0.10" },
{ direction: "read", line: "FINI (get_cmd)" },
{ direction: "write", line: "p t11 p111 d0.33 z0.11" },
{ direction: "read", line: "FINI (update recvd) t11 p111 d0.33 z0.11" },
{ direction: "write", line: "l t14 p0" },
{ direction: "read", line: "FINI (update recvd) t14 p0" },
{ direction: "write", line: "u t0 p0" },
{ direction: "read", line: "FINI (update recvd) t0 p0" },
];
const validation = validateToolDbTranscript(transcript);
assert.equal(validation.ready, true);
assert.equal(validation.hasVersion, true);
assert.equal(validation.hasGetAll, true);
assert.equal(validation.hasFini, true);
assert.equal(validation.hasPut, true);
assert.equal(validation.hasLoad, true);
assert.equal(validation.hasUnload, true);
const diagnostics = createToolDbProcessDiagnostics({
dbProgramPath: "./db_nonran.py",
opfsDbPath: "/machines/db-demo/tool-db/db_nonran_file",
transcript,
dbFileText: "T11 P111 D0.33 Z0.11\nT14 P114 D0.14 Z0.14\n",
startupToolCount: 10,
mutationCount: 3,
runtimeMode: "wasm-tool-db-protocol-worker",
});
assert.equal(diagnostics.dbProgramPath, "./db_nonran.py");
assert.equal(diagnostics.protocolTranscriptReady, true);
assert.equal(diagnostics.opfsPersistenceReady, true);
assert.equal(diagnostics.startupToolCount, 10);
assert.equal(diagnostics.mutationCount, 3);
assert.equal(diagnostics.tblFallbackSufficient, false);
assert.equal(diagnostics.runtimeExecutionReady, false);
assert.equal(diagnostics.executionEnabled, false);
assert.equal(diagnostics.promotionAllowed, false);
assert.match(diagnostics.transcriptHash, /^[0-9a-f]{8}$/);
assert.match(diagnostics.dbFileHash, /^[0-9a-f]{8}$/);
assert.equal(port.close().promotionAllowed, false);
console.log("tool_db_process_port_sdk=ok");

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
node "$ROOT_DIR/tests/sdk/node/verify_tool_db_process_port.mjs"