← back to Dw Daily Catchup 20260909
Bound catch-up retries to the 462 verified remaining candidates
7ec14eb0b3acf6b9b94b3b33f18159d2320546f5 · 2026-09-09 11:30:25 -0700 · Steve Abrams
Files touched
M config/daily-catchup-2026-09-09.jsonM lib/activation-allowance.jsM rotate-activate.jsM test/activation-allowance.test.js
Diff
commit 7ec14eb0b3acf6b9b94b3b33f18159d2320546f5
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 9 11:30:25 2026 -0700
Bound catch-up retries to the 462 verified remaining candidates
---
config/daily-catchup-2026-09-09.json | 1 +
lib/activation-allowance.js | 5 +++--
rotate-activate.js | 5 ++++-
test/activation-allowance.test.js | 6 ++++--
4 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/config/daily-catchup-2026-09-09.json b/config/daily-catchup-2026-09-09.json
index 4685757..e4a3033 100644
--- a/config/daily-catchup-2026-09-09.json
+++ b/config/daily-catchup-2026-09-09.json
@@ -5,6 +5,7 @@
"approved_by": "Steve",
"authorization": "start loading for the day now",
"starting_daily_used": 37,
+ "max_additional": 462,
"max_daily": 500,
"scope": "One-time catch-up for this date. Skip hourly pacing only when explicitly invoked; preserve the fixed vendor authorization, all other gates, zero Gemini and daily500."
}
diff --git a/lib/activation-allowance.js b/lib/activation-allowance.js
index 8ece3e6..e8ef87b 100644
--- a/lib/activation-allowance.js
+++ b/lib/activation-allowance.js
@@ -5,7 +5,7 @@ function assertDailyCatchup(date, authorization, now = new Date()) {
authorization?.schema_version !== 1 || authorization.ticket !== 'TK-11326' ||
authorization.date !== date || authorization.approved_by !== 'Steve' ||
authorization.authorization !== 'start loading for the day now' ||
- authorization.starting_daily_used !== 37 || authorization.max_daily !== 500)
+ authorization.starting_daily_used !== 37 || authorization.max_additional !== 462 || authorization.max_daily !== 500)
throw new Error('Daily catch-up authorization is invalid or expired');
}
@@ -21,7 +21,8 @@ function activationAllowance({ dailyUsed, hourlyUsed, requested = null, dailyCap
if (catchupDate !== null) {
assertDailyCatchup(catchupDate, authorization, now);
if (dailyUsed < authorization.starting_daily_used) throw new Error('Daily ledger is below approved catch-up baseline');
- return { cap: Math.min(requested ?? dailyRemaining, dailyRemaining), mode: 'daily-catchup', dailyRemaining, hourlyRemaining };
+ const authorizedRemaining = Math.max(0, authorization.starting_daily_used + authorization.max_additional - dailyUsed);
+ return { cap: Math.min(requested ?? dailyRemaining, dailyRemaining, authorizedRemaining), mode: 'daily-catchup', dailyRemaining, hourlyRemaining };
}
return { cap: Math.min(requested ?? dailyRemaining, dailyRemaining, hourlyRemaining), mode: 'hourly', dailyRemaining, hourlyRemaining };
}
diff --git a/rotate-activate.js b/rotate-activate.js
index faa9b56..a3a4443 100644
--- a/rotate-activate.js
+++ b/rotate-activate.js
@@ -416,7 +416,10 @@ function leakGuard(title, vendor) {
// COMMIT: flip → ACTIVE, add 'New Arrival', publish to channels (ex-Google).
if (CATCHUP_DATE !== null) assertDailyCatchup(CATCHUP_DATE, CATCHUP_AUTHORIZATION);
- if (ledgerUsed() >= DAILY_ACTIVATION_CAP) throw new Error('Daily activation cap reached during run');
+ const activeCeiling = CATCHUP_DATE !== null
+ ? Math.min(DAILY_ACTIVATION_CAP, CATCHUP_AUTHORIZATION.starting_daily_used + CATCHUP_AUTHORIZATION.max_additional)
+ : DAILY_ACTIVATION_CAP;
+ if (ledgerUsed() >= activeCeiling) throw new Error('Daily activation allowance reached during run');
const ar = await gqlRetry(ACTIVATE, { id: n.id });
const aue = ar.json?.data?.productUpdate?.userErrors;
if (!confirmedActivation(ar, n.id)) {
diff --git a/test/activation-allowance.test.js b/test/activation-allowance.test.js
index 68cf9fd..98d7489 100644
--- a/test/activation-allowance.test.js
+++ b/test/activation-allowance.test.js
@@ -12,11 +12,12 @@ test('normal scheduled runs retain the21/hour cap', () => {
});
test('explicit current-day catch-up can use remaining daily allowance', () => {
const result = activationAllowance(catchup());
- assert.equal(result.cap, 463); assert.equal(result.mode, 'daily-catchup');
+ assert.equal(result.cap, 462); assert.equal(result.mode, 'daily-catchup');
assert.equal(activationAllowance(catchup({ requested: 1 })).cap, 1);
});
test('retries cannot exceed500 total activations', () => {
- assert.equal(activationAllowance(catchup({ dailyUsed: 499 })).cap, 1);
+ assert.equal(activationAllowance(catchup({ dailyUsed: 498 })).cap, 1);
+ assert.equal(activationAllowance(catchup({ dailyUsed: 499 })).cap, 0);
assert.equal(activationAllowance(catchup({ dailyUsed: 500 })).cap, 0);
assert.equal(activationAllowance(catchup({ dailyUsed: 501 })).cap, 0);
});
@@ -25,6 +26,7 @@ test('having an authorization file does not enable catch-up for a scheduled invo
});
test('missing, altered, future and expired authorizations fail closed', () => {
for (const change of [{ authorization: null }, { authorization: { ...authorization, max_daily: 501 } },
+ { authorization: { ...authorization, max_additional: 463 } },
{ authorization: { ...authorization, approved_by: 'someone else' } }, { catchupDate: '2026-09-10' },
{ now: new Date('2026-09-10T00:00:00Z') }, { now: new Date('2026-09-08T23:59:59Z') }])
assert.throws(() => activationAllowance(catchup(change)));
← 5e650c1 Add dated daily activation catch-up while retaining the 500
·
back to Dw Daily Catchup 20260909
·
Record catch-up audit exceptions before publication repair 8f77ddc →