@@ -4447,24 +4447,55 @@ TEST(cli_install_plan_receipt_no_mutation_issue388) {
44474447 test_mkdirp(dir);
44484448
44494449 char *json = cbm_build_install_plan_json(tmpdir, "/usr/local/bin/codebase-memory-mcp");
4450- ASSERT_NOT_NULL(json);
4451- ASSERT(strstr(json, "agent.install.plan.v1") != NULL);
4452- ASSERT(strstr(json, "writes_started") != NULL);
4453- ASSERT(strstr(json, "next_safe_command") != NULL);
4454- ASSERT(strstr(json, "cursor") != NULL);
4455- ASSERT(strstr(json, ".cursor/mcp.json") != NULL);
4456- ASSERT(strstr(json, ".codex/config.toml") != NULL);
4450+
4451+ /* WHY the failures are deferred: asserting inline returns before the free
4452+ * and the rmdir below, so every red run leaked the receipt and left a
4453+ * stray /tmp/cli-plan-* directory behind. That makes the next debugging
4454+ * session harder than the failure it is reporting. Record what went wrong,
4455+ * release everything, then fail -- and name the specific marker, because
4456+ * "a marker was missing" costs a reader a bisect that "next_safe_command
4457+ * was missing" does not. */
4458+ const char *missing = NULL;
4459+ if (!json) {
4460+ missing = "receipt was NULL";
4461+ } else {
4462+ static const char *const required[] = {
4463+ "agent.install.plan.v1", "writes_started", "next_safe_command", "cursor",
4464+ ".cursor/mcp.json", ".codex/config.toml",
4465+ };
4466+ for (size_t i = 0; i < sizeof(required) / sizeof(required[0]); i++) {
4467+ if (!strstr(json, required[i])) {
4468+ missing = required[i];
4469+ break;
4470+ }
4471+ }
4472+ }
44574473 free(json);
44584474
44594475 /* Critical: building the plan must NOT have created any config file. */
44604476 char cfg[512];
44614477 struct stat st;
4478+ const char *created = NULL;
44624479 snprintf(cfg, sizeof(cfg), "%s/.cursor/mcp.json", tmpdir);
4463- ASSERT(stat(cfg, &st) != 0); /* must not exist */
4480+ if (stat(cfg, &st) == 0) {
4481+ created = ".cursor/mcp.json";
4482+ }
44644483 snprintf(cfg, sizeof(cfg), "%s/.codex/config.toml", tmpdir);
4465- ASSERT(stat(cfg, &st) != 0); /* must not exist */
4484+ if (!created && stat(cfg, &st) == 0) {
4485+ created = ".codex/config.toml";
4486+ }
44664487
44674488 test_rmdir_r(tmpdir);
4489+
4490+ char reason[256];
4491+ if (missing) {
4492+ snprintf(reason, sizeof(reason), "install plan receipt is missing %s", missing);
4493+ FAIL(reason);
4494+ }
4495+ if (created) {
4496+ snprintf(reason, sizeof(reason), "building an install plan created %s", created);
4497+ FAIL(reason);
4498+ }
44684499 PASS();
44694500}
44704501
0 commit comments