fix: 收敛投影权威渲染职责

This commit is contained in:
Codex
2026-07-13 20:44:40 +02:00
parent c1af68475e
commit afc56ad067
4 changed files with 16 additions and 8 deletions
@@ -6,7 +6,7 @@ import path from "node:path";
const repoDir = process.cwd();
const overlay = readOverlay();
const runtimePath = process.env.UNIDESK_RUNTIME_GITOPS_RUNTIME_PATH || requiredOverlayString("runtimePath");
const runtimePath = requiredOverlayString("runtimePath");
const runtimeDir = path.resolve(repoDir, runtimePath);
const prometheusOperatorKinds = new Set(["ServiceMonitor", "PrometheusRule", "PodMonitor", "Probe"]);
+3 -6
View File
@@ -545,7 +545,7 @@ export interface HwlabRuntimeKafkaShadowProducerSpec {
export interface HwlabRuntimeKafkaEventBridgeSpec {
readonly enabled: boolean;
readonly authority: "transactional-projection" | "direct-live";
readonly authority: "transactional-projection";
readonly features: {
readonly directPublish: boolean;
readonly liveKafkaSse: boolean;
@@ -1245,7 +1245,7 @@ function codeAgentKafkaEventBridgeConfig(value: unknown, path: string): HwlabRun
const raw = asRecord(value, path);
const features = asRecord(raw.features, `${path}.features`);
const enabled = booleanField(raw, "enabled", path);
const authority = enumStringField(raw, "authority", path, ["transactional-projection", "direct-live"] as const);
const authority = enumStringField(raw, "authority", path, ["transactional-projection"] as const);
const directPublish = booleanField(features, "directPublish", `${path}.features`);
const liveKafkaSse = booleanField(features, "liveKafkaSse", `${path}.features`);
const kafkaRefreshReplay = booleanField(features, "kafkaRefreshReplay", `${path}.features`);
@@ -1261,12 +1261,9 @@ function codeAgentKafkaEventBridgeConfig(value: unknown, path: string): HwlabRun
if (kafkaRefreshReplay && !liveKafkaSse) {
throw new Error(`${path}.features.liveKafkaSse must be true when ${path}.features.kafkaRefreshReplay is true`);
}
if (authority === "transactional-projection" && (!enabled || directPublish || liveKafkaSse || kafkaRefreshReplay || !transactionalProjector || !projectionOutboxRelay || !projectionRealtime)) {
if (!enabled || directPublish || liveKafkaSse || kafkaRefreshReplay || !transactionalProjector || !projectionOutboxRelay || !projectionRealtime) {
throw new Error(`${path}.authority transactional-projection requires enabled transactionalProjector/projectionOutboxRelay/projectionRealtime and disables directPublish/liveKafkaSse/kafkaRefreshReplay`);
}
if (authority === "direct-live" && (!enabled || !directPublish || !liveKafkaSse || transactionalProjector || projectionOutboxRelay || projectionRealtime)) {
throw new Error(`${path}.authority direct-live requires enabled directPublish/liveKafkaSse and disables transactional projection capabilities`);
}
const transactionalProjectorConfig = raw.transactionalProjector === undefined
? undefined
: codeAgentKafkaTransactionalProjectorConfig(raw.transactionalProjector, `${path}.transactionalProjector`);
-1
View File
@@ -1539,7 +1539,6 @@ export function renderNodeRuntimeControlPlaneOnNode(spec: HwlabRuntimeLaneSpec,
`--web-endpoint ${shellQuote(spec.publicWebUrl)}`,
`--out ${shellQuote(renderDir)}`,
].join(" "),
`UNIDESK_RUNTIME_GITOPS_OVERLAY_B64="$overlay_b64" UNIDESK_RUNTIME_GITOPS_RUNTIME_PATH="$render_dir/${spec.runtimeRenderDir}" node ${shellQuote(rootPath("scripts/native/hwlab/runtime-gitops-postprocess.mjs"))}`,
...nodeRuntimePipelinePostprocessScript(),
].join("\n");
return { result: runNodeHostScriptAsync(spec, script, timeoutSeconds, `${spec.nodeId.toLowerCase()}-${spec.lane}-render`), renderDir, worktreeDir, location: "node-host" };
@@ -3,8 +3,10 @@ import { mkdtemp, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "bun:test";
import { readFileSync } from "node:fs";
import { hwlabRuntimeLaneSpecForNode } from "../hwlab-node-lanes";
import { rootPath } from "../config";
import { buildWebObserveCommandVisibility, nodeWebProbeRealtimeFanoutProfiles, nodeWebProbeWorkbenchKafkaDebugReplay, nodeWebProbeWorkbenchTraceReadability, resolveWebObserveActionJson } from "./web-probe-observe-actions";
test("realtime authority runner contract derives topics, groups, and transactional capabilities from owning YAML", () => {
@@ -60,6 +62,16 @@ test("realtime authority runner contract derives topics, groups, and transaction
});
});
test("realtime authority parser and inline render expose no direct authority or duplicate native postprocess execution", () => {
const laneSource = readFileSync(rootPath("scripts", "src", "hwlab-node-lanes.ts"), "utf8");
const renderSource = readFileSync(rootPath("scripts", "src", "hwlab-node", "render.ts"), "utf8");
assert.doesNotMatch(laneSource, /direct-live/u);
assert.equal(renderSource.includes("UNIDESK_RUNTIME_GITOPS_RUNTIME_PATH"), false);
assert.equal(renderSource.includes('UNIDESK_RUNTIME_GITOPS_OVERLAY_B64="$overlay_b64" UNIDESK_RUNTIME_GITOPS_RUNTIME_PATH'), false);
assert.match(renderSource, /runtimeGitopsPostprocessScript\(\)/u);
assert.match(renderSource, /writeRuntimeGitopsNativeScript\("runtime-gitops-postprocess\.mjs"/u);
});
test("Workbench Kafka debug replay runner contract is derived from owning YAML", () => {
assert.deepEqual(nodeWebProbeWorkbenchKafkaDebugReplay(hwlabRuntimeLaneSpecForNode("v03", "NC01")), {
enabled: true,