feat(cli): point top-level cli --help at --format json - #2140
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. |
a1d11e7 to
b74c035
Compare
b52df4b to
ca34611
Compare
|
Thank you for improving top-level help. The current diff also changes a daemon timeout test and retries the |
d85fe1d to
618fbca
Compare
CLI_USAGE described outer --json but did not mention tool-level --format json. Add a help-only pointer that tools which accept format support --format tree|json, and distinguish payload JSON from the full MCP envelope. No new flags, env vars, or output-default changes. Fixes DeusData#2102 Signed-off-by: Lowpower <3133734+Lowpower@users.noreply.github.com>
Signed-off-by: Lowpower <3133734+Lowpower@users.noreply.github.com>
fca3371 to
2f557f5
Compare
|
A quick request, because it is costing you time rather than saving it: please do not rebase onto
|
|
Merged — thank you @Lowpower, and thank you for splitting it exactly as asked: the PR is now the help text, one macro in Verified on the merge result with the current Small, and it removes a real point of confusion between |
…ure on Windows
Several processes first-starting together against a runtime directory
that does not exist yet -- test-windows-guards' section_cold_storm, or a
host that launches more than one MCP server on its very first run -- all
observe the final path component absent. One CreateDirectoryW wins; the
others get ERROR_ALREADY_EXISTS. win_private_directory_tree_secure()
treated that as a failure and recorded no validation detail, so every
loser exited with a bare
secure CLI coordination could not be created (endpoint)
The function called right after the walk, win_runtime_directory_secure(),
has always tolerated ERROR_ALREADY_EXISTS for the same directory, and the
POSIX walk tolerates EEXIST at the same point; only the Windows walk in
front of them did not.
Seen four times on 2026-09-21 on unrelated PRs (DeusData#1768 three attempts in
a row, DeusData#2140, DeusData#1999, DeusData#808). The racy lines date from July; the guard
began exercising them on 2026-09-03, when each guard section was given
its own empty CBM_RUNTIME_DIR, so the final component is now absent at
storm time on every run.
The walk now treats ERROR_ALREADY_EXISTS from its own CreateDirectoryW as
"the directory I wanted exists". Nothing is trusted because of that: an
ancestor still goes through win_directory_component_secure(), and the
final component through win_runtime_directory_secure(), which refuses a
non-directory or reparse point and enforces owner and DACL.
Every refusal on this path now names its component and its rule. The
walk reports the Windows error when it can neither create nor inspect a
component, and win_runtime_directory_secure() says whether the path
could not be created, cannot be inspected, exists but is not a directory,
or is a reparse point. One helper owns the wide-to-UTF-8 conversion for
these messages and the existing ancestor message now uses it too, so
src/daemon/ipc.c stays at its memory-core baseline.
Deterministic reproduction, no threads and no timing: a test seam fires
in the walk between "component observed absent" and CreateDirectoryW,
and the test plays the process that wins the creation.
daemon_ipc_windows_private_directory_survives_lost_creation_race
daemon_ipc_windows_private_directory_refuses_and_names_a_planted_file
Verification. macOS arm64 (ASan+UBSan): build clean, daemon_ipc 53 passed
(2 Windows-only skips), daemon_bootstrap 28 passed, lint-memory-core
unchanged (ipc.c stays at 146 raw sites). The two new tests are Windows-only
and have NOT been run locally: the Windows VM was down when this was written,
so the RED run on the seam-only tree and the GREEN run with this fix are
delegated to CI's windows-latest legs (test-windows shards, test-windows-guards)
by an explicit maintainer decision. If the guard suite's cold storm still
fails with this in place, the attribution above is wrong and this reverts.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
… its verdict daemon_bootstrap_fails_fast_when_daemon_dies_at_publication went red on the MSan lane of three PRs that touch no daemon code at all (DeusData#2245, DeusData#2158, DeusData#2140) with tests/test_daemon_bootstrap.c:1116: ASSERT(daemon_named_cause) and green on a rerun of the identical commit. Cause, attributed 2026-09-20. The test forks a real daemon host whose record publication fails with ENOSPC, and asserts that the client names that cause instead of waiting out its 30 s startup deadline. But before it listens, the host SHA-256s its own executable image, and the test runner is ~450 MB: ~3 s natively, 20-32 s under MSan (48 CI samples, median 25.8 s). The spawn override returned as soon as it had forked, so the client's 30 s clock raced the host's hash. On a slow run the deadline fired first, the reaper SIGKILLed a host that had not failed yet, and the log had no listen_failed line to find. Nothing was wrong with the product: with a 28 s artificial delay the client does learn the recorded ENOSPC cause. The spawn override now reaps the forked host before it returns. The host writes its start-failure record and only then releases its lifetime reservation and exits, so "record on disk, reservation released" is a stable state pinned by construction when the client takes its first look -- and that first look is guaranteed: the client's post-spawn wait loop runs at least once even past the deadline, and its first failure check after a spawn is unthrottled. How long the host takes no longer matters. No production code changes; the assertions are unchanged. A regression to the pre-DeusData#1828 behaviour (a client that ignores the record) still fails the unchanged assertions: its message no longer names the failure, the errno and the path. Proof, one build with temporary env-switched instrumentation that is not part of this commit (a sleep in the forked host before it starts, and a switch back to the old fire-and-forget spawn): spawn forked host delayed daemon_bootstrap suite synchronous no 28 passed old (async) 31 s 27 passed, 1 failed: ASSERT(log_read) synchronous 31 s 28 passed The old spawn fails under the delay one assertion earlier than CI did (log_read, not daemon_named_cause): the injected sleep sits before the host opens its log, whereas in CI the host was killed mid-hash with the log already open. Same mechanism -- the client's deadline beating the host -- and the 2026-09-20 attribution reproduced the CI message itself with a delay placed after the log is opened. The final tree, without the instrumentation: daemon_bootstrap 28 passed, three runs in a row. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
What does this PR do?
Help-only discoverability fix for #2102 (direction c only).
Top-level
cli --helpalready described outer--json(the raw MCP result envelope) but did not mention that tools which acceptformatsupport--format tree|json. Habitual CLI users look atcli --helpfirst; per-tool--helpalready documented--format.This PR adds two lines to
CLI_USAGE:--format tree|json(default: tree).--format jsonprints payload JSON; outer--jsonprints the full MCP envelope.No session-wide
--formatflag, noCBM_CLI_FORMATenv var, and no change to output defaults.CBM_CLI_USAGElives insrc/cli/cli.hsotests/test_cli.ccan assert on the same stringrun_cli()prints.Checklist
git commit -s) — required, CI rejects unsigned commitsscripts/test.sh --suites cli— includingcli_usage_points_to_tool_format_json_issue2102)Fixes #2102