fix(env): stop an unreadable environment setting from picking a wrong default - #1880
fix(env): stop an unreadable environment setting from picking a wrong default#1880CaptainMittens wants to merge 1 commit into
Conversation
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
… default
atoi and atol answer 0 for text they cannot read, and 0 is a real setting at
three places in this project. So a typo, a trailing unit such as "30s", or a
stray space silently chose a value nobody asked for, and nothing on screen
said the setting had been dropped.
src/mcp/index_supervisor.c CBM_INDEX_WORKER_TIMEOUT_S
src/cli/hook_augment.c CBM_HOOK_DEADLINE_MS
src/mcp/mcp.c CBM_INDEX_MAX_RESTARTS
CBM_HOOK_DEADLINE_MS was the worst of the three. atoi answered 0, 0 is below
HA_DEADLINE_MIN_MS, and the clamp then handed back 50 ms -- the SHORTEST
deadline the setting allows, for a setting whose only purpose is to give the
hook more room. The comment above that function records a hunt for hook runs
that never finished, 0 of 24 real sessions, which is the exact symptom a
silently-shortened deadline produces.
CBM_INDEX_MAX_RESTARTS lost twice. A typo kept the default of 100, and
CBM_INDEX_MAX_RESTARTS=0 -- which reads as "do not restart" to anybody who
sets it -- also kept 100. The setting did the opposite of the request.
CBM_INDEX_WORKER_TIMEOUT_S fell through to the 15-minute default, so a test
set to give up after 30 seconds hung for 15 minutes with nothing to explain
why.
The fix adds one helper rather than three copies of the same check:
bool cbm_env_long(const char *name, long *out);
It answers true only when the variable is set, is not empty, and reads
cleanly from its first character to its last. It holds no policy -- no
minimum, no maximum, no default -- because the three sites disagree on all
three, and a helper that guessed would be wrong at two of them. The shape is
the one src/main.c:1104 already uses: an end pointer, errno, and a check that
nothing was left over. It also refuses a leading blank, which strtol would
otherwise step over, so " 5" is a slip rather than the number 5.
Each site keeps its own rule:
worker timeout an unreadable value keeps the 15-minute default AND logs
the value it dropped
restart cap 0 now means no restarts; an unreadable value keeps 100
AND logs the value it dropped
hook deadline an unreadable value now yields HA_DEADLINE_DEFAULT_MS,
not the floor. This one stays silent on purpose: the file
includes no log header and writes no stderr, because its
output is hook protocol.
The restart-cap parse was lifted out of a very large function into a named
index_restart_cap(), so it can be read and reached on its own.
Four tests come with the change. The two that pin the user-visible behaviour
were seen failing before the fix:
FAIL tests/test_cli.c:402: ms == 50, expected HOOK_DEADLINE_DEFAULT == 2000
(with "unreadable value \"abc\" gave 50 ms" printed above it)
FAIL tests/test_cli.c:434: cbm_index_restart_cap_for_testing() == 100,
expected 0 == 0
After the fix, TEST_SUITES="platform cli mcp" reports 518 passed, 2 failed.
The full suite reports 7635 passed, 2 failed. Both failures are in
tests/test_cli.c (lines 1826 and 6802), print "error: one or more agent
cleanup operations failed", and reproduce on a clean tree without this
change -- they depend on the coding agents installed on the machine.
make -f Makefile.cbm lint-ci passes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Richter <jrichter5781@gmail.com>
c9fd0a7 to
30dcb62
Compare
|
Same shape as #1922: an input the code cannot read becomes a plausible value, and nothing downstream can tell it from a real one. Here it is
This is one of four from a single scan for siblings of #1875's shape — #1875, #1877, #1880, #1881. Context for the set, and a question about the two still unfiled, is on #1877. |
What this fixes
atoiandatolanswer0for text they cannot read, and0is a realsetting at three places in this project. So a typo, a trailing unit such as
30s, or a stray space silently chose a value nobody asked for — and nothingon screen said the setting had been dropped.
src/cli/hook_augment.cCBM_HOOK_DEADLINE_MSsrc/mcp/mcp.cCBM_INDEX_MAX_RESTARTS=0src/mcp/index_supervisor.cCBM_INDEX_WORKER_TIMEOUT_S1.
CBM_HOOK_DEADLINE_MS— a typo bought the shortest possible deadlineatoianswers0,0is belowHA_DEADLINE_MIN_MS, and the clamp handedback 50 ms — for a setting whose only purpose is to give the hook more
room. The comment directly above that function records a hunt for hook runs
that never finished, 0 of 24 real sessions, which is the exact symptom a
silently-shortened deadline produces.
2.
CBM_INDEX_MAX_RESTARTS— the setting did the opposite of the requestTwo ways to lose. A typo kept the default of 100. And
CBM_INDEX_MAX_RESTARTS=0— which reads as "do not restart" to anybody whosets it — also kept 100.
3.
CBM_INDEX_WORKER_TIMEOUT_S— a 30-second test hung for 15 minutesThe comment above this override says it exists to tighten the timeout for
tests.
atolanswered0for30sor a stray space,0failed the> 0test, and the 15-minute default came back with nothing to explain it.
The fix
One helper, not three copies of the same check:
It answers true only when the variable is set, is not empty, and reads cleanly
from its first character to its last. It holds no policy — no minimum, no
maximum, no default — because the three sites disagree on all three, and a
helper that guessed would be wrong at two of them.
The shape is the one
src/main.c:1104already uses for--port=: an endpointer,
errno, and a check that nothing was left over. It adds one thing ontop — a refusal of a leading blank, because
strtolsteps over blanks of itsown accord, so
" 5"would otherwise read as the number 5. Theclisuitecaught that during this work.
Each site keeps its own rule:
0now means no restarts; unreadable keeps 100 AND logs the dropped valueHA_DEADLINE_DEFAULT_MS(2000), never the floorhook_augment.cstays silent on purpose: it includes no log header and writesno stderr, because its output is hook protocol.
The restart-cap parse was lifted out of a very large function into a named
index_restart_cap(), so it can be read and reached on its own.Tests
Four tests. The two that pin the user-visible behaviour were seen failing
before the fix:
Each carries a positive control first — a good value is still read — so a later
failure points at the unreadable case and not at a reader broken outright.
platform_env_long_reads_a_clean_numbertests/test_platform.cplatform_env_long_refuses_what_it_cannot_readtests/test_platform.ccli_hook_deadline_ignores_an_unreadable_valuetests/test_cli.ccli_index_restart_cap_honours_zero_and_refuses_junktests/test_cli.cTwo
_for_testingwrappers reach the statics, following the convention alreadyused 25 times in
src/cli/cli.h. The deadline wrapper is POSIX-only, matchingthe
#ifndef _WIN32block the function lives in.Checks run
make -f Makefile.cbm test-focused TEST_SUITES="platform cli mcp"518 passed, 2 failed, 6 skippedmake -f Makefile.cbm lint-ci=== CI linters passed ===— exit 0make -f Makefile.cbm cbmmake -f Makefile.cbm test7635 passed, 2 failed, 8 skippedThe two failures are in
tests/test_cli.c(lines 1826 and 6802), printerror: one or more agent cleanup operations failed, and reproduce on a cleantree without this change. They depend on the coding agents installed on the
machine.
How this was found
By scanning for siblings of the parse bug fixed in #1875 — "a parse reports
success while the input stays unread". #1877 fixed the confidence pair from the
same scan. This is the environment-variable group.
Checklist
git commit -s(DCO)make -f Makefile.cbm testrunmake -f Makefile.cbm lint-cirunFixes #1981