feat(orchestrator): harden zero-impact shadow rollout

Gate and bound Portal shadow observations while preserving Native execution. Add fail-closed service boundaries, terminal retention controls, Canary readiness telemetry, ops visibility, and isolated regression coverage.
This commit is contained in:
john
2026-07-25 07:28:37 +08:00
parent 08a48e4849
commit 6df82818c5
33 changed files with 1569 additions and 108 deletions
+14 -2
View File
@@ -222,6 +222,12 @@ export type OrchestratorRuntime = {
executesLangGraph: boolean;
plansLangGraph: boolean;
shadowsLangGraph: boolean;
shadowObservation: {
requested: boolean;
enabled: boolean;
reason: string | null;
environmentGate: boolean;
};
executionHandoff: {
implemented: boolean;
requested: boolean;
@@ -286,8 +292,10 @@ export type OrchestratorShadowMetrics = {
observations: number;
successes: number;
failures: number;
skipped: number;
successRate: number | null;
failureRate: number | null;
skipRate: number | null;
latencyP50Ms: number | null;
latencyP95Ms: number | null;
nativeSucceeded: number;
@@ -304,7 +312,7 @@ export type OrchestratorShadowRun = {
sessionId: string | null;
nativeStatus: string;
nativeAttempts: number;
shadowStatus: 'succeeded' | 'failed';
shadowStatus: 'succeeded' | 'failed' | 'skipped';
engine: string;
configVersion: number | null;
phase: string | null;
@@ -313,6 +321,7 @@ export type OrchestratorShadowRun = {
executorAdapter: string | null;
latencyMs: number | null;
error: { code: string; message: string } | null;
skipReason: string | null;
observedAt: number;
nativeCompletedAt: number | null;
};
@@ -386,6 +395,7 @@ export type OrchestratorCanaryReadiness = {
hours: number;
minObservations: number;
minSuccessRate: number;
maxSkipRate: number;
maxP95LatencyMs: number;
minLatencyCoverageRate: number;
minNativeSettledRate: number;
@@ -398,7 +408,9 @@ export type OrchestratorCanaryReadiness = {
excludedSynthetic: number;
successes: number;
failures: number;
skipped: number;
successRate: number | null;
skipRate: number | null;
latencyCoverageRate: number | null;
latencyP95Ms: number | null;
nativeSettledRate: number | null;
@@ -521,7 +533,7 @@ export async function fetchOrchestratorRuntime() {
export async function fetchOrchestratorShadowRuns(params: {
hours?: number;
limit?: number;
status?: 'all' | 'succeeded' | 'failed';
status?: 'all' | 'succeeded' | 'failed' | 'skipped';
} = {}) {
const query = new URLSearchParams();
if (params.hours) query.set('hours', String(params.hours));