From 3e0750eb3c25928e3edabd5d2d7fb6fd5963bcdf Mon Sep 17 00:00:00 2001 From: root Date: Tue, 7 Jul 2026 09:47:47 +0000 Subject: [PATCH] feat(dqo): deploy tip-dqo self-heal orchestrator - escalation-sink: add NTFY_TOKEN Bearer auth header support - self-heal-guards: pass max_load from GuardConfig to isLoadAcceptable - control-loop: include MAX_LOAD in guardConfig so DQO_MAX_LOAD env is respected --- packages/scraper/src/orchestrator/control-loop.ts | 1 + packages/scraper/src/orchestrator/escalation-sink.ts | 1 + packages/scraper/src/orchestrator/self-heal-guards.ts | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/scraper/src/orchestrator/control-loop.ts b/packages/scraper/src/orchestrator/control-loop.ts index 54e2473..af3cbfd 100644 --- a/packages/scraper/src/orchestrator/control-loop.ts +++ b/packages/scraper/src/orchestrator/control-loop.ts @@ -83,6 +83,7 @@ function guardConfig(t: Target): GuardConfig { budget_per_day: t.budget_per_day, max_backoff_hours: t.max_backoff_hours, circuit_breaker_strikes: t.circuit_breaker_strikes, + max_load: MAX_LOAD, }; } diff --git a/packages/scraper/src/orchestrator/escalation-sink.ts b/packages/scraper/src/orchestrator/escalation-sink.ts index 1becc7e..8d7ea31 100644 --- a/packages/scraper/src/orchestrator/escalation-sink.ts +++ b/packages/scraper/src/orchestrator/escalation-sink.ts @@ -36,6 +36,7 @@ export async function notify( Title: title, Priority: level === "page" ? "high" : "default", Tags: level === "page" ? "rotating_light" : "warning", + ...(process.env.NTFY_TOKEN ? { Authorization: `Bearer ${process.env.NTFY_TOKEN}` } : {}), }, body, signal: AbortSignal.timeout(10_000), diff --git a/packages/scraper/src/orchestrator/self-heal-guards.ts b/packages/scraper/src/orchestrator/self-heal-guards.ts index ce47547..1972cd3 100644 --- a/packages/scraper/src/orchestrator/self-heal-guards.ts +++ b/packages/scraper/src/orchestrator/self-heal-guards.ts @@ -22,6 +22,7 @@ export interface GuardConfig { budget_per_day: number; max_backoff_hours: number; circuit_breaker_strikes: number; + max_load?: number; } /** Facts read from the self_heal_dispatch ledger for one source. */ @@ -118,7 +119,7 @@ export function canDispatch( budgetOk(facts, cfg), minIntervalOk(facts, cfg, now), backoffElapsed(facts, cfg, now), - isLoadAcceptable(load1), + isLoadAcceptable(load1, cfg.max_load), ]; const failed = checks.find((c) => !c.allow); return failed ?? { allow: true, reason: "all guardrails passed" };