Skip to content

Installer hardening (borrowed from mnemon review): JSON5-tolerant settings parsing, $HOME collision guard, remove emptied settings file on uninstall #231

Description

@edheltzel

Context

From the 2026-07-13 mnemon competitive review (red-team validated — Recall memory breadcrumb #3984, learning #668). These three install-lifecycle hardening items survived adversarial review as the top 'steal now' tier: small, bounded, no new abstractions, directly serving daily-driver reliability.

Sibling of #112 (closed — doctor --fix config-write robustness) and #124 (open — atomic config-write parity in lib/install-lib.sh). This issue extends that same hardening cluster; implementation should reuse the patterns established there, not duplicate them.

The three items

1. JSON5-tolerant settings parsing

When install/update/doctor read ~/.claude/settings.json (or other host config), tolerate hand-edited files containing // comments and trailing commas by stripping them before parse instead of failing. mnemon reference implementation: internal/setup/settings.go:33-87 (strip comments + trailing commas, then strict parse). Note the tradeoff: comments are lost on write-back — acceptable, but document it.

2. $HOME degenerate-path collision guard

If a project-scoped operation ever runs from $HOME, the apparent project-local .claude/ IS the user-global ~/.claude/ directory. mnemon detects this (internal/setup/claude.go:108-140, collidesWithUserConfig, symlink- and CLAUDE_CONFIG_DIR-aware) and switches hook commands to absolute paths with a printed warning. Audit whether Recall's per-file symlink install has the same degenerate case and add the equivalent guard.

3. Remove emptied settings file on uninstall

When uninstall removes the last Recall-owned entries from a host config file, delete the file rather than leaving {} / empty-array husks. mnemon reference: WriteOrRemoveJSONFile (internal/setup/settings.go:177-185). Cleaner uninstall footprint; only applies to files Recall would otherwise leave semantically empty.

Acceptance criteria

  • Hand-edited settings.json with comments/trailing commas no longer breaks install/update/doctor reads
  • $HOME-collision case detected (or confirmed impossible for Recall's layout, documented why)
  • Uninstall leaves no empty config husks
  • Shared logic lives in lib/install-lib.sh / existing doctor paths per DRY rule — no per-script duplication
  • bash -n passes on touched lifecycle scripts; existing install-lifecycle tests extended

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageMaintainer needs to evaluate this issuerisk:lowwork that is non-ambiguous, no human judgement as `agent:ready`type:featureNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions