fix: align v02 gateway evidence environment
This commit is contained in:
@@ -30,6 +30,7 @@ test("gateway outbound transport registers session and keeps shell execution dis
|
|||||||
cloud.enqueue(shellRequest({ id: "req_disabled_shell", traceId: "trc_disabled_shell", command: "echo should-not-run" }));
|
cloud.enqueue(shellRequest({ id: "req_disabled_shell", traceId: "trc_disabled_shell", command: "echo should-not-run" }));
|
||||||
const result = await cloud.waitForResult("req_disabled_shell");
|
const result = await cloud.waitForResult("req_disabled_shell");
|
||||||
assert.equal(result.response.error.data.reason, "cmd_exec_disabled");
|
assert.equal(result.response.error.data.reason, "cmd_exec_disabled");
|
||||||
|
assert.equal(result.response.meta.environment, "v02");
|
||||||
assert.equal(result.gatewaySessionId, "gws_gateway_disabled_test");
|
assert.equal(result.gatewaySessionId, "gws_gateway_disabled_test");
|
||||||
} finally {
|
} finally {
|
||||||
await gateway.stop();
|
await gateway.stop();
|
||||||
@@ -61,6 +62,10 @@ test("gateway outbound transport executes cloud requests without blocking poll l
|
|||||||
|
|
||||||
assert.equal(quick.response.result.shellExecuted, true, JSON.stringify(quick.response, null, 2));
|
assert.equal(quick.response.result.shellExecuted, true, JSON.stringify(quick.response, null, 2));
|
||||||
assert.equal(quick.response.result.exitCode, 0, JSON.stringify(quick.response, null, 2));
|
assert.equal(quick.response.result.exitCode, 0, JSON.stringify(quick.response, null, 2));
|
||||||
|
assert.equal(quick.response.meta.environment, "v02");
|
||||||
|
assert.equal(quick.response.result.environment, "v02");
|
||||||
|
assert.equal(quick.response.result.audit.environment, "v02");
|
||||||
|
assert.equal(quick.response.result.evidence.environment, "v02");
|
||||||
assert.match(quick.response.result.stdout, /quick-done/u);
|
assert.match(quick.response.result.stdout, /quick-done/u);
|
||||||
assert.equal(slow.response.result.shellExecuted, true, JSON.stringify(slow.response, null, 2));
|
assert.equal(slow.response.result.shellExecuted, true, JSON.stringify(slow.response, null, 2));
|
||||||
assert.equal(slow.response.result.exitCode, 0, JSON.stringify(slow.response, null, 2));
|
assert.equal(slow.response.result.exitCode, 0, JSON.stringify(slow.response, null, 2));
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { spawn } from "node:child_process";
|
|||||||
import { createAuditEvent, createEvidenceRecord, operationContext } from "../../internal/sim/l2-runtime.mjs";
|
import { createAuditEvent, createEvidenceRecord, operationContext } from "../../internal/sim/l2-runtime.mjs";
|
||||||
import { createGatewayState, createHealth } from "../../internal/sim/model.mjs";
|
import { createGatewayState, createHealth } from "../../internal/sim/model.mjs";
|
||||||
import { createJsonServer, fetchJson, listen, parsePort } from "../../internal/sim/http.mjs";
|
import { createJsonServer, fetchJson, listen, parsePort } from "../../internal/sim/http.mjs";
|
||||||
import { ERROR_CODES, JSON_RPC_VERSION, createRpcErrorBody } from "../../internal/protocol/index.mjs";
|
import { ENVIRONMENT_DEV, ERROR_CODES, JSON_RPC_VERSION, createRpcErrorBody, isProtocolEnvironment } from "../../internal/protocol/index.mjs";
|
||||||
|
|
||||||
const gatewayId = process.env.HWLAB_GATEWAY_ID ?? "gateway_dev_stub";
|
const gatewayId = process.env.HWLAB_GATEWAY_ID ?? "gateway_dev_stub";
|
||||||
const gatewaySessionId = process.env.HWLAB_GATEWAY_SESSION_ID ?? `gws_${gatewayId}`;
|
const gatewaySessionId = process.env.HWLAB_GATEWAY_SESSION_ID ?? `gws_${gatewayId}`;
|
||||||
@@ -15,6 +15,7 @@ const pollIntervalMs = parsePositiveInteger(process.env.HWLAB_GATEWAY_POLL_INTER
|
|||||||
const commandTimeoutMs = parsePositiveInteger(process.env.HWLAB_GATEWAY_CMD_TIMEOUT_MS, 120000);
|
const commandTimeoutMs = parsePositiveInteger(process.env.HWLAB_GATEWAY_CMD_TIMEOUT_MS, 120000);
|
||||||
const outputLimitBytes = parsePositiveInteger(process.env.HWLAB_GATEWAY_CMD_OUTPUT_LIMIT_BYTES, 65536);
|
const outputLimitBytes = parsePositiveInteger(process.env.HWLAB_GATEWAY_CMD_OUTPUT_LIMIT_BYTES, 65536);
|
||||||
const maxInflightRequests = parsePositiveInteger(process.env.HWLAB_GATEWAY_MAX_INFLIGHT, 3);
|
const maxInflightRequests = parsePositiveInteger(process.env.HWLAB_GATEWAY_MAX_INFLIGHT, 3);
|
||||||
|
const gatewayEnvironment = normalizeEnvironment(process.env.HWLAB_ENVIRONMENT || process.env.HWLAB_GITOPS_PROFILE || ENVIRONMENT_DEV);
|
||||||
const resourceId = process.env.HWLAB_GATEWAY_RESOURCE_ID ?? "res_windows_host";
|
const resourceId = process.env.HWLAB_GATEWAY_RESOURCE_ID ?? "res_windows_host";
|
||||||
const boxId = process.env.HWLAB_GATEWAY_BOX_ID ?? "box_windows_host";
|
const boxId = process.env.HWLAB_GATEWAY_BOX_ID ?? "box_windows_host";
|
||||||
const commandExecutionEnabled = truthy(process.env.HWLAB_GATEWAY_CMD_EXEC_ENABLED) || truthy(process.env.HWLAB_GATEWAY_DEMO_OPEN);
|
const commandExecutionEnabled = truthy(process.env.HWLAB_GATEWAY_CMD_EXEC_ENABLED) || truthy(process.env.HWLAB_GATEWAY_DEMO_OPEN);
|
||||||
@@ -142,6 +143,7 @@ function startCloudRequest(request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleCloudRequest(request) {
|
async function handleCloudRequest(request) {
|
||||||
|
const environment = requestEnvironment(request?.meta);
|
||||||
const context = operationContext({
|
const context = operationContext({
|
||||||
operationId: request.params?.operationId,
|
operationId: request.params?.operationId,
|
||||||
traceId: request.meta?.traceId,
|
traceId: request.meta?.traceId,
|
||||||
@@ -159,12 +161,12 @@ async function handleCloudRequest(request) {
|
|||||||
method: request.method ?? null
|
method: request.method ?? null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const result = await invokeShell(request.params ?? {}, context);
|
const result = await invokeShell(request.params ?? {}, context, environment);
|
||||||
response = {
|
response = {
|
||||||
jsonrpc: JSON_RPC_VERSION,
|
jsonrpc: JSON_RPC_VERSION,
|
||||||
id: request.id,
|
id: request.id,
|
||||||
result,
|
result,
|
||||||
meta: responseMeta(context.traceId)
|
meta: responseMeta(context.traceId, environment)
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const body = error?.body ?? createRpcErrorBody({
|
const body = error?.body ?? createRpcErrorBody({
|
||||||
@@ -176,7 +178,7 @@ async function handleCloudRequest(request) {
|
|||||||
jsonrpc: JSON_RPC_VERSION,
|
jsonrpc: JSON_RPC_VERSION,
|
||||||
id: request.id,
|
id: request.id,
|
||||||
error: body.error,
|
error: body.error,
|
||||||
meta: responseMeta(context.traceId)
|
meta: responseMeta(context.traceId, environment)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +187,7 @@ async function handleCloudRequest(request) {
|
|||||||
|
|
||||||
async function postGatewayBusyResult(request) {
|
async function postGatewayBusyResult(request) {
|
||||||
const traceId = request?.meta?.traceId ?? `trc_gateway_busy_${Date.now()}`;
|
const traceId = request?.meta?.traceId ?? `trc_gateway_busy_${Date.now()}`;
|
||||||
|
const environment = requestEnvironment(request?.meta);
|
||||||
const body = createRpcErrorBody({
|
const body = createRpcErrorBody({
|
||||||
code: ERROR_CODES.operationRejected,
|
code: ERROR_CODES.operationRejected,
|
||||||
message: "Gateway is busy; retry after an in-flight command finishes or increase HWLAB_GATEWAY_MAX_INFLIGHT.",
|
message: "Gateway is busy; retry after an in-flight command finishes or increase HWLAB_GATEWAY_MAX_INFLIGHT.",
|
||||||
@@ -199,7 +202,7 @@ async function postGatewayBusyResult(request) {
|
|||||||
jsonrpc: JSON_RPC_VERSION,
|
jsonrpc: JSON_RPC_VERSION,
|
||||||
id: request?.id ?? null,
|
id: request?.id ?? null,
|
||||||
error: body.error,
|
error: body.error,
|
||||||
meta: responseMeta(traceId)
|
meta: responseMeta(traceId, environment)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +222,7 @@ async function postGatewayResult(response) {
|
|||||||
state.outbound.lastResultError = null;
|
state.outbound.lastResultError = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function invokeShell(params, context) {
|
async function invokeShell(params, context, environment = gatewayEnvironment) {
|
||||||
if (!commandExecutionEnabled) {
|
if (!commandExecutionEnabled) {
|
||||||
throw rpcError(ERROR_CODES.operationRejected, "Gateway command execution is disabled", {
|
throw rpcError(ERROR_CODES.operationRejected, "Gateway command execution is disabled", {
|
||||||
reason: "cmd_exec_disabled",
|
reason: "cmd_exec_disabled",
|
||||||
@@ -248,6 +251,7 @@ async function invokeShell(params, context) {
|
|||||||
actorType: "service",
|
actorType: "service",
|
||||||
actorId: "svc_hwlab-gateway",
|
actorId: "svc_hwlab-gateway",
|
||||||
outcome: status === "succeeded" ? "succeeded" : "failed",
|
outcome: status === "succeeded" ? "succeeded" : "failed",
|
||||||
|
environment,
|
||||||
metadata: {
|
metadata: {
|
||||||
gatewayId,
|
gatewayId,
|
||||||
resourceId: params.resourceId ?? resourceId,
|
resourceId: params.resourceId ?? resourceId,
|
||||||
@@ -266,6 +270,7 @@ async function invokeShell(params, context) {
|
|||||||
operationId: context.operationId,
|
operationId: context.operationId,
|
||||||
traceId: context.traceId,
|
traceId: context.traceId,
|
||||||
kind: "trace",
|
kind: "trace",
|
||||||
|
environment,
|
||||||
payload: {
|
payload: {
|
||||||
gatewayId,
|
gatewayId,
|
||||||
gatewaySessionId,
|
gatewaySessionId,
|
||||||
@@ -294,6 +299,7 @@ async function invokeShell(params, context) {
|
|||||||
accepted: true,
|
accepted: true,
|
||||||
status,
|
status,
|
||||||
serviceId: "hwlab-gateway",
|
serviceId: "hwlab-gateway",
|
||||||
|
environment,
|
||||||
gatewayId,
|
gatewayId,
|
||||||
gatewaySessionId,
|
gatewaySessionId,
|
||||||
operationId: context.operationId,
|
operationId: context.operationId,
|
||||||
@@ -516,14 +522,22 @@ function normalizeShellInput(params = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function responseMeta(traceId) {
|
function responseMeta(traceId, environment = gatewayEnvironment) {
|
||||||
return {
|
return {
|
||||||
traceId,
|
traceId,
|
||||||
serviceId: "hwlab-gateway",
|
serviceId: "hwlab-gateway",
|
||||||
environment: "dev"
|
environment: normalizeEnvironment(environment)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requestEnvironment(meta = {}) {
|
||||||
|
return normalizeEnvironment(meta?.environment || gatewayEnvironment);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeEnvironment(environment) {
|
||||||
|
return isProtocolEnvironment(environment) ? environment : ENVIRONMENT_DEV;
|
||||||
|
}
|
||||||
|
|
||||||
function rpcError(code, message, data = {}) {
|
function rpcError(code, message, data = {}) {
|
||||||
const error = new Error(message);
|
const error = new Error(message);
|
||||||
error.code = code;
|
error.code = code;
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ cloud API: http://74.48.78.17:19667
|
|||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
set "HWLAB_GATEWAY_CLOUD_URL=http://74.48.78.17:19667"
|
set "HWLAB_GATEWAY_CLOUD_URL=http://74.48.78.17:19667"
|
||||||
|
set "HWLAB_ENVIRONMENT=v02"
|
||||||
set "HWLAB_GATEWAY_ID=gtw_D601_F103"
|
set "HWLAB_GATEWAY_ID=gtw_D601_F103"
|
||||||
set "HWLAB_GATEWAY_SESSION_ID=gws_D601_F103"
|
set "HWLAB_GATEWAY_SESSION_ID=gws_D601_F103"
|
||||||
set "HWLAB_GATEWAY_RESOURCE_ID=res_windows_host"
|
set "HWLAB_GATEWAY_RESOURCE_ID=res_windows_host"
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ Code Agent 第一版 skill 来源分为两类:预装 skill 读取镜像内只
|
|||||||
| `HWLAB_SKILLS_COMMIT_ID` | 已实现 | v02 render 已注入 source commit。 |
|
| `HWLAB_SKILLS_COMMIT_ID` | 已实现 | v02 render 已注入 source commit。 |
|
||||||
| `HWLAB_SKILLS_VERSION` | 未完全实现 | 当前 render 未稳定注入 version,manager/worker readiness 仍可能报告缺失。 |
|
| `HWLAB_SKILLS_VERSION` | 未完全实现 | 当前 render 未稳定注入 version,manager/worker readiness 仍可能报告缺失。 |
|
||||||
| 作为 Code Agent 运行时依赖 | 不采用 | Code Agent 读取镜像内 skills,不应每轮依赖该服务。 |
|
| 作为 Code Agent 运行时依赖 | 不采用 | Code Agent 读取镜像内 skills,不应每轮依赖该服务。 |
|
||||||
| 用户上传 skill PVC 持久化 | 未实现 | 第一版要求由 `hwlab-cloud-api` 写入 `/data/user-skills`,不使用 Postgres。 |
|
| 用户上传 skill PVC 持久化 | 已实现 | `hwlab-cloud-api` 写入 `/data/user-skills`,metadata 保持为 PVC 内普通 JSON,不使用 Postgres。 |
|
||||||
| 预装/上传双目录发现 | 未实现 | 第一版要求 `HWLAB_CODE_AGENT_SKILLS_DIRS=/app/skills:/data/user-skills` 或等价多目录配置。 |
|
| 预装/上传双目录发现 | 已实现 | `HWLAB_CODE_AGENT_SKILLS_DIRS` 同时覆盖 `/app/skills` 与 `/data/user-skills`;resolver 使用多目录发现并保留 source/sourceRoot。 |
|
||||||
| Codex `.agents/skills` 聚合入口 | 未实现 | 第一版要求在 `/workspace/hwlab/.agents/skills` 创建来源前缀 symlink。 |
|
| Codex `.agents/skills` 聚合入口 | 已实现 | `/workspace/hwlab/.agents/skills` 由 cloud-api 幂等维护来源前缀 symlink,预装为 `preinstalled-<name>`,上传为 `uploaded-<id>`。 |
|
||||||
| 同名 skill 不覆盖不合并 | 未实现 | 当前发现逻辑不得只按 skill name 去重,需保留同名不同来源。 |
|
| 同名 skill 不覆盖不合并 | 已实现 | 列表、预览、聚合和 prompt discovery 均按来源与路径/ID 区分;同名预装和上传 skill 可同时存在。 |
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
- command execution 默认关闭;只有显式 `HWLAB_GATEWAY_CMD_EXEC_ENABLED=1` 或 demo open 时才执行 shell。
|
- command execution 默认关闭;只有显式 `HWLAB_GATEWAY_CMD_EXEC_ENABLED=1` 或 demo open 时才执行 shell。
|
||||||
- command execution 必须同时读取 stdout/stderr,并对每路输出做有界收集和 `stdoutTruncated`/`stderrTruncated` 标记,避免任一路 pipe 填满导致子进程或 gateway result 卡死。默认 bounded body 可以截断,但必须保留字节数、truncated 标记和 enough preview;需要完整超大输出时应另设计 evidence/spool,不得把完整无限输出塞进同步 JSON 响应。
|
- command execution 必须同时读取 stdout/stderr,并对每路输出做有界收集和 `stdoutTruncated`/`stderrTruncated` 标记,避免任一路 pipe 填满导致子进程或 gateway result 卡死。默认 bounded body 可以截断,但必须保留字节数、truncated 标记和 enough preview;需要完整超大输出时应另设计 evidence/spool,不得把完整无限输出塞进同步 JSON 响应。
|
||||||
- gateway inflight 上限是背压机制,不是黑洞机制。超过 `maxInflightRequests` 时,Cloud API/gateway 必须返回包含 `reason=gateway_busy`、`inflightCount` 和 `maxInflightRequests` 的结构化结果,调用方可重试或排队。
|
- gateway inflight 上限是背压机制,不是黑洞机制。超过 `maxInflightRequests` 时,Cloud API/gateway 必须返回包含 `reason=gateway_busy`、`inflightCount` 和 `maxInflightRequests` 的结构化结果,调用方可重试或排队。
|
||||||
|
- gateway 回传的 JSON-RPC `meta.environment`、dispatch audit 和 evidence 的 `environment` 必须跟随 cloud-api 请求 meta;没有合法请求 meta 时才回退到 gateway 进程的 `HWLAB_ENVIRONMENT` / `HWLAB_GITOPS_PROFILE`,v02 lane 不得把硬件证据标成 `dev`。
|
||||||
|
|
||||||
## API 接口说明
|
## API 接口说明
|
||||||
|
|
||||||
@@ -41,6 +42,10 @@
|
|||||||
|
|
||||||
阅读 docs/reference/spec-v02-hwlab-gateway.md,然后在 `G14:/root/hwlab-v02` 用 `hwlab-cli client gateway pressure` 手动测试以下内容:对目标 gateway 运行 small stdout、至少 128KiB stdout、至少 128KiB 单行 stdout、至少 128KiB stderr、短 timeout 和超过 gateway `maxInflightRequests` 的并发请求。验收条件是全部场景在 CLI timeout 内返回结构化 JSON;大输出显示 truncated 标记,timeout 显示 `timed_out`,超容量显示 `gateway_busy`,不能出现无输出、HTTP transport timeout 或 Code Agent trace 黑洞。
|
阅读 docs/reference/spec-v02-hwlab-gateway.md,然后在 `G14:/root/hwlab-v02` 用 `hwlab-cli client gateway pressure` 手动测试以下内容:对目标 gateway 运行 small stdout、至少 128KiB stdout、至少 128KiB 单行 stdout、至少 128KiB stderr、短 timeout 和超过 gateway `maxInflightRequests` 的并发请求。验收条件是全部场景在 CLI timeout 内返回结构化 JSON;大输出显示 truncated 标记,timeout 显示 `timed_out`,超容量显示 `gateway_busy`,不能出现无输出、HTTP transport timeout 或 Code Agent trace 黑洞。
|
||||||
|
|
||||||
|
## T4
|
||||||
|
|
||||||
|
阅读 docs/reference/spec-v02-hwlab-gateway.md,然后通过 v02 cloud-api/device-pod 触发一次 gateway shell dispatch,确认 JSON-RPC response meta、dispatch audit 和 evidence 的 `environment` 都是 `v02`。
|
||||||
|
|
||||||
## 规格的实现情况
|
## 规格的实现情况
|
||||||
|
|
||||||
| 规格项 | 状态 | 说明 |
|
| 规格项 | 状态 | 说明 |
|
||||||
@@ -49,6 +54,7 @@
|
|||||||
| outbound poll/result | 已实现 | 与 cloud-api registry 对接。 |
|
| outbound poll/result | 已实现 | 与 cloud-api registry 对接。 |
|
||||||
| bounded shell execution | 已实现 | 受 env 开关、timeout 和 output limit 约束。 |
|
| bounded shell execution | 已实现 | 受 env 开关、timeout 和 output limit 约束。 |
|
||||||
| gateway 压测闭环 | 已实现 | `hwlab-cli client gateway pressure` 覆盖大输出、timeout 和并发背压,不依赖 shell pipe 裁剪。 |
|
| gateway 压测闭环 | 已实现 | `hwlab-cli client gateway pressure` 覆盖大输出、timeout 和并发背压,不依赖 shell pipe 裁剪。 |
|
||||||
|
| v02 environment 标记 | 已实现 | response meta、audit 和 evidence 从请求 meta 或 gateway env 派生,不把 v02 dispatch 证据落回 `dev`。 |
|
||||||
| device-pod grant/lease | 不在本服务 | 由 cloud-api/device-pod 负责。 |
|
| device-pod grant/lease | 不在本服务 | 由 cloud-api/device-pod 负责。 |
|
||||||
| 生产级 gateway 多租户隔离 | 未完全实现 | 当前是 demo/transport skeleton。 |
|
| 生产级 gateway 多租户隔离 | 未完全实现 | 当前是 demo/transport skeleton。 |
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createHash, randomUUID } from "node:crypto";
|
import { createHash, randomUUID } from "node:crypto";
|
||||||
|
|
||||||
import { createRpcErrorBody, ENVIRONMENT_DEV, ERROR_CODES } from "../protocol/index.mjs";
|
import { createRpcErrorBody, ENVIRONMENT_DEV, ERROR_CODES, isProtocolEnvironment } from "../protocol/index.mjs";
|
||||||
import { getPortDefinition } from "./model.mjs";
|
import { getPortDefinition } from "./model.mjs";
|
||||||
|
|
||||||
export const AUDIT_SHAPE_FIELDS = Object.freeze([
|
export const AUDIT_SHAPE_FIELDS = Object.freeze([
|
||||||
@@ -76,6 +76,7 @@ export function createAuditEvent({
|
|||||||
outcome,
|
outcome,
|
||||||
reason,
|
reason,
|
||||||
metadata = {},
|
metadata = {},
|
||||||
|
environment = ENVIRONMENT_DEV,
|
||||||
occurredAt = isoNow()
|
occurredAt = isoNow()
|
||||||
}) {
|
}) {
|
||||||
return {
|
return {
|
||||||
@@ -90,7 +91,7 @@ export function createAuditEvent({
|
|||||||
...(gatewaySessionId ? { gatewaySessionId } : {}),
|
...(gatewaySessionId ? { gatewaySessionId } : {}),
|
||||||
...(operationId ? { operationId } : {}),
|
...(operationId ? { operationId } : {}),
|
||||||
serviceId,
|
serviceId,
|
||||||
environment: ENVIRONMENT_DEV,
|
environment: normalizeEnvironment(environment),
|
||||||
...(outcome ? { outcome } : {}),
|
...(outcome ? { outcome } : {}),
|
||||||
...(reason ? { reason } : {}),
|
...(reason ? { reason } : {}),
|
||||||
metadata,
|
metadata,
|
||||||
@@ -106,14 +107,17 @@ export function createEvidenceRecord({
|
|||||||
kind = "measurement",
|
kind = "measurement",
|
||||||
payload = {},
|
payload = {},
|
||||||
metadata = {},
|
metadata = {},
|
||||||
|
environment = ENVIRONMENT_DEV,
|
||||||
createdAt = isoNow()
|
createdAt = isoNow()
|
||||||
}) {
|
}) {
|
||||||
|
const normalizedEnvironment = normalizeEnvironment(environment);
|
||||||
const serialized = JSON.stringify({
|
const serialized = JSON.stringify({
|
||||||
serviceId,
|
serviceId,
|
||||||
projectId,
|
projectId,
|
||||||
operationId,
|
operationId,
|
||||||
traceId,
|
traceId,
|
||||||
kind,
|
kind,
|
||||||
|
environment: normalizedEnvironment,
|
||||||
payload,
|
payload,
|
||||||
metadata,
|
metadata,
|
||||||
createdAt
|
createdAt
|
||||||
@@ -130,7 +134,7 @@ export function createEvidenceRecord({
|
|||||||
sha256,
|
sha256,
|
||||||
sizeBytes: Buffer.byteLength(serialized),
|
sizeBytes: Buffer.byteLength(serialized),
|
||||||
serviceId,
|
serviceId,
|
||||||
environment: ENVIRONMENT_DEV,
|
environment: normalizedEnvironment,
|
||||||
metadata: {
|
metadata: {
|
||||||
traceId,
|
traceId,
|
||||||
...metadata
|
...metadata
|
||||||
@@ -139,6 +143,10 @@ export function createEvidenceRecord({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeEnvironment(environment) {
|
||||||
|
return isProtocolEnvironment(environment) ? environment : ENVIRONMENT_DEV;
|
||||||
|
}
|
||||||
|
|
||||||
export function normalizePortValue(value, definition) {
|
export function normalizePortValue(value, definition) {
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return value;
|
return value;
|
||||||
|
|||||||
Reference in New Issue
Block a user