feat(orchestrator): enforce Page Data validation gate

This commit is contained in:
john
2026-07-25 14:27:07 +08:00
parent 417aa9c78b
commit 721db19a92
10 changed files with 432 additions and 43 deletions
+19
View File
@@ -151,6 +151,10 @@ function runtimeState(config, env = process.env) {
env.MEMIND_ORCHESTRATOR_EXECUTION_HANDOFF_ENABLED,
false,
);
const environmentPageDataValidationGate = normalizeBoolean(
env.MEMIND_ORCHESTRATOR_PAGE_DATA_VALIDATION_GATE_ENABLED,
false,
);
const configured = config.primaryEngine !== WORKFLOW_ENGINE.LANGGRAPH || Boolean(config.serviceUrl);
let reason = null;
if (killSwitch) reason = 'kill_switch';
@@ -175,6 +179,8 @@ function runtimeState(config, env = process.env) {
const shadowObservationEnabled = !reason
&& environmentShadowObservationGate
&& shadowObservationRequested;
const pageDataValidationGateEnabled = environmentPageDataValidationGate
&& shadowObservationEnabled;
return {
killSwitch,
configured,
@@ -203,6 +209,19 @@ function runtimeState(config, env = process.env) {
: 'environment_shadow_observation_gate_disabled',
environmentGate: environmentShadowObservationGate,
},
pageDataValidationGate: {
requested: environmentPageDataValidationGate,
enabled: pageDataValidationGateEnabled,
failClosed: true,
reason: pageDataValidationGateEnabled
? null
: !environmentPageDataValidationGate
? 'environment_page_data_validation_gate_disabled'
: !shadowObservationEnabled
? 'shadow_observation_not_enabled'
: 'page_data_validation_gate_disabled',
environmentGate: environmentPageDataValidationGate,
},
executionHandoff: {
implemented: EXECUTION_HANDOFF_IMPLEMENTED,
requested: executionHandoffRequested,
@@ -46,6 +46,13 @@ test('orchestrator config defaults to a disabled native-safe runtime', async ()
reason: 'shadow_observation_not_requested',
environmentGate: false,
});
assert.deepEqual(state.runtime.pageDataValidationGate, {
requested: false,
enabled: false,
failClosed: true,
reason: 'environment_page_data_validation_gate_disabled',
environmentGate: false,
});
assert.equal(state.engines.find((engine) => engine.id === 'native').configured, true);
assert.equal(state.engines.find((engine) => engine.id === 'langgraph').configured, false);
assert.deepEqual(
@@ -275,6 +282,34 @@ test('Shadow runtime reports the independent Portal observation wiring gate', as
reason: null,
environmentGate: true,
});
assert.deepEqual(runtime.runtime.pageDataValidationGate, {
requested: false,
enabled: false,
failClosed: true,
reason: 'environment_page_data_validation_gate_disabled',
environmentGate: false,
});
});
test('Page Data validation gate is effective only with Shadow wiring and its own environment gate', async () => {
const service = createOrchestratorAdminConfigService(createPool(), {
env: {
MEMIND_ORCHESTRATOR_SHADOW_OBSERVATION_ENABLED: '1',
MEMIND_ORCHESTRATOR_PAGE_DATA_VALIDATION_GATE_ENABLED: '1',
},
});
await service.updateAdminConfig({
mode: 'shadow',
serviceUrl: 'http://127.0.0.1:8093',
});
const runtime = await service.getRuntimeState();
assert.deepEqual(runtime.runtime.pageDataValidationGate, {
requested: true,
enabled: true,
failClosed: true,
reason: null,
environmentGate: true,
});
});
test('orchestrator emergency kill switch always forces native selection', async () => {