⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
scripts/gen-selfhost-env-reference.ts (lines 119-132) recognizes an env.SOMETHING-style read
via three mechanisms: a literal string, the envString(env, "X") helper, or a call to a helper
registered in PROCESS_ENV_NAME_HELPERS/ENV_NAME_LITERAL_ARG_HELPERS where the env-var name is
passed as a literal argument. It has no case for a same-file wrapper function that forwards its own
name parameter (not a literal) into one of the recognized helpers.
Two real instances of this blind spot exist today:
src/selfhost/queue-common.ts:1096-1098 defines envDurationMs(name, fallback), which calls
parsePositiveIntEnv(name, {...}) with name as a parameter. It's called with 5 real literal env
var names: QUEUE_STARTUP_JITTER_MS (line 712), QUEUE_RECOVERY_JITTER_MS (716),
QUEUE_PROCESSING_TIMEOUT_MS (720), QUEUE_DEAD_LETTER_REVIVE_INTERVAL_MS (742), and
SCHEDULED_ENQUEUE_JITTER_MS (763).
src/selfhost/maintenance-admission.ts:152-157 defines its own local
parsePositiveFloatEnv(name, fallback) wrapper, called at lines 185-188 with
MAINTENANCE_ADMISSION_MAX_HOST_LOAD.
None of these 6 env vars appear in the generated apps/loopover-ui/src/lib/selfhost-env-reference.ts
(confirmed by grep), nor in .env.example (QUEUE_DEAD_LETTER_REVIVE_INTERVAL_MS is mentioned only
in prose docs, never as a settable var listing). These are real, operator-tunable knobs, documented
in their own code comments, that silently never reach the self-host operator reference table — and
because the generator's own helper-detection logic has this blind spot, npm run selfhost:env-reference -- --check can never flag them as stale, no matter how carefully a
contributor regenerates the file. This is the same class of bug already fixed twice for other blind
spots (#6994, #8627, and the globalThis-cast/severity-threshold fix in #8632) — this is the third,
distinct instance (same-file wrapper functions), not a duplicate of either.
Requirements
- Extend
gen-selfhost-env-reference.ts's helper-detection logic to recognize a same-file wrapper
function whose single string parameter is forwarded, unmodified, into an already-recognized
helper (parsePositiveIntEnv, parsePositiveFloatEnv, or the existing literal-arg helpers) —
either by adding envDurationMs and the local parsePositiveFloatEnv pattern to the existing
helper-detection maps, or by generalizing detection to any single-string-param function that
forwards its first argument this way.
- The fix must generalize enough to also catch
maintenance-admission.ts's locally-defined
parsePositiveFloatEnv, not just special-case envDurationMs by name.
Deliverables
All four Deliverables are required in the same PR.
Test Coverage Requirements
scripts/** generator logic and its test file are both measured by codecov/patch (99%+ target).
The new test must exercise the new wrapper-detection code path directly (a fixture module defining
a wrapper function shaped like envDurationMs), not just re-assert already-covered helper patterns.
Expected Outcome
All 6 real, currently-invisible self-host env vars appear in the generated operator-facing
reference table, and the generator's helper-detection logic now generalizes to same-file
parameter-forwarding wrappers, closing this blind-spot category rather than just these 6 instances.
Links & Resources
Context
scripts/gen-selfhost-env-reference.ts(lines 119-132) recognizes anenv.SOMETHING-style readvia three mechanisms: a literal string, the
envString(env, "X")helper, or a call to a helperregistered in
PROCESS_ENV_NAME_HELPERS/ENV_NAME_LITERAL_ARG_HELPERSwhere the env-var name ispassed as a literal argument. It has no case for a same-file wrapper function that forwards its own
nameparameter (not a literal) into one of the recognized helpers.Two real instances of this blind spot exist today:
src/selfhost/queue-common.ts:1096-1098definesenvDurationMs(name, fallback), which callsparsePositiveIntEnv(name, {...})withnameas a parameter. It's called with 5 real literal envvar names:
QUEUE_STARTUP_JITTER_MS(line 712),QUEUE_RECOVERY_JITTER_MS(716),QUEUE_PROCESSING_TIMEOUT_MS(720),QUEUE_DEAD_LETTER_REVIVE_INTERVAL_MS(742), andSCHEDULED_ENQUEUE_JITTER_MS(763).src/selfhost/maintenance-admission.ts:152-157defines its own localparsePositiveFloatEnv(name, fallback)wrapper, called at lines 185-188 withMAINTENANCE_ADMISSION_MAX_HOST_LOAD.None of these 6 env vars appear in the generated
apps/loopover-ui/src/lib/selfhost-env-reference.ts(confirmed by grep), nor in
.env.example(QUEUE_DEAD_LETTER_REVIVE_INTERVAL_MSis mentioned onlyin prose docs, never as a settable var listing). These are real, operator-tunable knobs, documented
in their own code comments, that silently never reach the self-host operator reference table — and
because the generator's own helper-detection logic has this blind spot,
npm run selfhost:env-reference -- --checkcan never flag them as stale, no matter how carefully acontributor regenerates the file. This is the same class of bug already fixed twice for other blind
spots (#6994, #8627, and the globalThis-cast/severity-threshold fix in #8632) — this is the third,
distinct instance (same-file wrapper functions), not a duplicate of either.
Requirements
gen-selfhost-env-reference.ts's helper-detection logic to recognize a same-file wrapperfunction whose single string parameter is forwarded, unmodified, into an already-recognized
helper (
parsePositiveIntEnv,parsePositiveFloatEnv, or the existing literal-arg helpers) —either by adding
envDurationMsand the localparsePositiveFloatEnvpattern to the existinghelper-detection maps, or by generalizing detection to any single-string-param function that
forwards its first argument this way.
maintenance-admission.ts's locally-definedparsePositiveFloatEnv, not just special-caseenvDurationMsby name.Deliverables
collectSelfHostEnvVars()(or the equivalent scan entry point) includesQUEUE_STARTUP_JITTER_MS,QUEUE_RECOVERY_JITTER_MS,QUEUE_PROCESSING_TIMEOUT_MS,QUEUE_DEAD_LETTER_REVIVE_INTERVAL_MS, andSCHEDULED_ENQUEUE_JITTER_MS(currently absent).collectSelfHostEnvVars()includesMAINTENANCE_ADMISSION_MAX_HOST_LOAD(currently absent).apps/loopover-ui/src/lib/selfhost-env-reference.tsis regenerated (npm run selfhost:env-reference) and committed with all 6 new entries present.test/unit/selfhost-env-reference-script.test.ts, using the existing fixturepattern, proving a same-file wrapper function forwarding its
nameparameter intoparsePositiveIntEnv/parsePositiveFloatEnvis now detected.All four Deliverables are required in the same PR.
Test Coverage Requirements
scripts/**generator logic and its test file are both measured bycodecov/patch(99%+ target).The new test must exercise the new wrapper-detection code path directly (a fixture module defining
a wrapper function shaped like
envDurationMs), not just re-assert already-covered helper patterns.Expected Outcome
All 6 real, currently-invisible self-host env vars appear in the generated operator-facing
reference table, and the generator's helper-detection logic now generalizes to same-file
parameter-forwarding wrappers, closing this blind-spot category rather than just these 6 instances.
Links & Resources
scripts/gen-selfhost-env-reference.ts:119-132(helper-detection maps to extend)src/selfhost/queue-common.ts:1096-1098(envDurationMs), lines 712, 716, 720, 742, 763 (callsites)
src/selfhost/maintenance-admission.ts:152-157(localparsePositiveFloatEnv), lines 185-188(call site)
test/unit/selfhost-env-reference-script.test.ts(existing fixture pattern to extend)script — see also the sibling issue for the
for (const name of ARRAY)blind spot found in thesame audit)