fix(cli): YAML removers answer OK for an absent config, so uninstall no longer refuses - #2059
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. |
|
Thanks — this is right, and I verified it the hard way: with a fake hermes on PATH and a fresh HOME without .hermes/, main's uninstall really does stop with the Hermes error and keeps the binary; your test is red against main's config_yaml_edit.c and green with your change; the merged tree passes config_yaml_edit, cli, activation_transaction, daemon_bootstrap and daemon_frontend (411 cases) plus the end-to-end run. The JSON and TOML removers already behave this way, so this aligns YAML with them. One thing keeps CI red: both Windows shards fail to COMPILE — tests/test_config_yaml_edit.c:1851 calls lstat, and the new TEST body sits outside the #ifndef _WIN32 block while its RUN_TEST is inside one. Wrap the test definition in the same #ifndef _WIN32 / #endif (or drop the lstat assertion), keep the sign-off, and I'll merge on green. |
…no longer refuses `uninstall` failed with rc 1 on any macOS where Hermes is installed: Hermes is detected by its binary on PATH, not by its home, so a HOME without `.hermes/` (every test HOME, and a fresh user's) reached the Hermes uninstall ops with `~/.hermes/config.yaml` absent. The JSON removers already treat a missing config as "nothing to remove"; the YAML removers acquired the lock first, and the lock directory is created beside the target — with the parent directory absent that failed, the adapter recorded error: agent_config agent=Hermes op=pre_llm_hook_uninstall ... (target: does not exist or cannot be inspected) error: agent_config agent=Hermes op=mcp_uninstall ... and uninstall refused to remove the executable and the indexes. This is what made cli_uninstall_quiesces_active_cohort_before_removing_binary_and_index fail on such a machine (7837 passed, 1 failed on a pristine main). All four YAML removers short-circuit on a genuinely absent path and create nothing: lstat + ENOENT on POSIX, and CreateFileW with FILE_FLAG_OPEN_REPARSE_POINT on Windows, mirroring toml_read_file. Opening the reparse point rather than following it keeps a dangling symlink out of the short-circuit on both platforms, so it still reaches the reader and its byte-identical rejection. The regression test covers the four removers and runs on every platform: it asserts "nothing was created" through cbm_path_info_utf8 rather than lstat, so the Windows branch is exercised rather than compiled out. Signed-off-by: David Gil <dgilperez@gmail.com>
e0f37d7 to
3007dbf
Compare
|
Thanks for verifying it that thoroughly - fixed both shards. The test now checks "nothing was created" with cbm_path_info_utf8 instead of lstat, and its RUN_TEST moves out of the #ifndef _WIN32 block, so it runs on Windows too. Wrapping the test would have left the Windows branch untested, and that branch had a bug: GetFileAttributesW follows symlinks, so a dangling symlink counted as absent and skipped the reader, unlike the POSIX branch. It now uses CreateFileW with FILE_FLAG_OPEN_REPARSE_POINT, mirroring toml_read_file. |
|
Merged as a6aea0b — thank you. Uninstall no longer trips over a YAML config that was never written, the test pins it, and the Windows probe correction (open the reparse point instead of following it) was the right call on top of the compile fix I asked for. Much appreciated. |
Problem
codebase-memory-mcp uninstallexits 1 on any macOS where Hermes is installed. Hermes is detected by its binary on PATH (cbm_agent_cli_exists("hermes", ...)), not by its home, so a HOME without.hermes/reaches the Hermes uninstall ops with~/.hermes/config.yamlabsent. The JSON removers already treat a missing config as "nothing to remove" (cbm_json_like_read_documentreturns 1 →CLI_OK). The four YAML removers acquire the lock first, and the lock directory is created beside the target, so with the parent directory absent the lock fails and the adapter records:This is also why
cli_uninstall_quiesces_active_cohort_before_removing_binary_and_indexfails on such a machine: on a pristinemain(2026-09-04) the suite gives7837 passed, 1 failed, 7 skippedhere, with Hermes at~/.local/bin/hermes.Fix
cbm_yaml_remove_mapping_entry,cbm_yaml_remove_owned_mapping_entry,cbm_yaml_remove_mapping_sequence_itemandcbm_yaml_remove_string_list_itemshort-circuit with their OK value on a true ENOENT (lstat, orERROR_FILE_NOT_FOUND/ERROR_PATH_NOT_FOUNDon Windows) and create nothing. A dangling symlink still reaches the reader and keeps its byte-identical rejection (config_yaml_edit_nested_sequence_rejects_symlink_byte_identicallyunchanged).Validation
config_yaml_edit_remove_on_absent_config_is_a_no_opcovers the four removers against a path whose directory does not exist.make -f Makefile.cbm teston macOS arm64 with Hermes installed: all passed, 7 skipped (the previously failingcli_uninstall_quiesces_active_cohort_before_removing_binary_and_indexincluded).