From 82a6dc0417a287df3e6b3c6c00e891f23437b06b Mon Sep 17 00:00:00 2001 From: Lev Date: Wed, 15 Apr 2026 03:11:57 +0200 Subject: [PATCH 1/2] fix(kill_switch): use strict > for expiry check (expires_at is exclusive) --- src/fairvisor/kill_switch.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fairvisor/kill_switch.lua b/src/fairvisor/kill_switch.lua index 7c7aaea..cb4ef78 100644 --- a/src/fairvisor/kill_switch.lua +++ b/src/fairvisor/kill_switch.lua @@ -121,7 +121,7 @@ function _M.check(kill_switches, descriptors, route, now) end end - if expires_epoch == nil or expires_epoch >= now then + if expires_epoch == nil or expires_epoch > now then local scope_value = descriptors and descriptors[kill_switch.scope_key] if scope_value ~= nil and scope_value == kill_switch.scope_value then if kill_switch.route == nil or kill_switch.route == route then @@ -141,3 +141,4 @@ function _M.check(kill_switches, descriptors, route, now) end return _M + From 82443f40f3d247a22f9eb462e73bd053613cffbf Mon Sep 17 00:00:00 2001 From: Lev Date: Wed, 15 Apr 2026 03:12:32 +0200 Subject: [PATCH 2/2] =?UTF-8?q?test(kill=5Fswitch):=20add=20AC-13=20expiry?= =?UTF-8?q?=20boundary=20scenario=20(now=20=3D=3D=20expires=5Fepoch=20?= =?UTF-8?q?=E2=86=92=20not=20matched)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/unit/features/kill_switch.feature | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spec/unit/features/kill_switch.feature b/spec/unit/features/kill_switch.feature index 8df22aa..e9d7e50 100644 --- a/spec/unit/features/kill_switch.feature +++ b/spec/unit/features/kill_switch.feature @@ -110,6 +110,18 @@ Feature: Kill-switch enforcement When I check kill switches Then result is matched with kill_switch reason + Scenario: AC-13 Kill-switch is inactive at exact expiry epoch (boundary) + Given the nginx mock environment is reset + And kill switches include scope "jwt:org_id" value "org_xyz" expiring at "2026-02-03T14:00:00Z" + And descriptors include "jwt:org_id" as "org_xyz" + And the route is "/v1/inference" + And the current time is ISO "2026-02-03T14:00:00Z" + When I validate kill switches + Then validation succeeds + And the kill switch has cached expiry epoch + When I check kill switches + Then result is not matched + Rule: Validation Scenario: AC-11 Validation rejects invalid scope_key format Given kill switches include scope "invalid_format" value "org_xyz" @@ -148,3 +160,4 @@ Feature: Kill-switch enforcement Scenario: Reject impossible calendar date When I parse timestamp "2026-02-30T14:00:00Z" Then parsed epoch is nil +