[GH-ISSUE #7320] [Bug] Uninstall guide promises a stop for malformed shared configuration while purge continues #4350

Closed
opened 2026-10-31 00:49:06 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 26, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/7320

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Documentation

Observed behavior

The installation guide says malformed client configuration stops uninstall before anything is removed. In a disposable home with malformed .agents/mcp.json and neither FreeBuff's profile nor ZCode's client directory present, the public uninstall --purge-data --json command instead exits 0 with status: complete. It reports the shared configuration as retained, leaves its bytes unchanged, and removes REA cache and state. This is a documentation mismatch with an intentional shared-storage exception.

Reproduction

Run the following from the baseline source checkout with its locked dependencies and built runtime available, Python 3 installed, and the pinned Node.js on PATH. It invokes the public dispatcher in disposable homes with fresh environments; no agent application or analysis provider is required. The first case reproduced in both independent executions; the controls below also ran successfully.

import json, os, pathlib, shutil, subprocess, tempfile
cli = (pathlib.Path.cwd() / 'scripts/rea.mjs').resolve()
node = pathlib.Path(shutil.which('node')).resolve()
with tempfile.TemporaryDirectory(prefix='rea-uninstall-') as directory:
    for name, malformed, installed, purge in [
        ('shared-absent', True, False, True),
        ('zcode-present', True, True, True),
        ('valid-control', False, False, True),
        ('no-purge', True, False, False),
    ]:
        home = pathlib.Path(directory) / name
        config = home / '.agents/mcp.json'
        config.parent.mkdir(parents=True)
        text = '{ "mcpServers": { "rea": { "command": "npx" } }' if malformed else '{}'
        config.write_text(text)
        markers = [home / '.rea' / part / 'marker' for part in ['cache', 'state']]
        for marker in markers:
            marker.parent.mkdir(parents=True)
            marker.write_text('disposable fixture')
        if installed:
            (home / '.zcode/cli').mkdir(parents=True)
        (home / 'temp').mkdir()
        env = {'PATH': str(node.parent) + os.pathsep + os.defpath,
               'HOME': str(home), 'USERPROFILE': str(home),
               'XDG_CONFIG_HOME': str(home / '.config'),
               'XDG_CACHE_HOME': str(home / '.cache'),
               'XDG_DATA_HOME': str(home / '.local/share'),
               'XDG_STATE_HOME': str(home / '.local/state'),
               'TMPDIR': str(home / 'temp'), 'NO_COLOR': '1'}
        args = [str(node), str(cli), 'uninstall', '--json']
        if purge:
            args.append('--purge-data')
        process = subprocess.run(args, cwd=home, env=env, capture_output=True, text=True, timeout=45)
        result = json.loads(process.stdout)
        freebuff = next(item for item in result['items'] if item['name'] == 'freebuff')
        print(json.dumps({'case': name, 'exit': process.returncode,
                          'status': result['status'], 'freebuff': freebuff['status'],
                          'configuration_unchanged': config.read_text() == text,
                          'cache_exists': markers[0].exists(), 'state_exists': markers[1].exists()}))

Expected behavior

The maintenance guide should accurately explain when malformed shared registration storage stops uninstall and when it is retained while other removals continue, including cache/state deletion with --purge-data. A reader should be able to determine the removal consequences before running the command. The existing shared-storage behavior is deliberate; this report does not request a different uninstall policy.

Impact and scope

A reader relying on the unconditional no-removal promise can invoke purge while expecting the malformed file to block it, then have REA cache and state removed. Only disposable markers were deleted here; no real user data loss, loss of Evidence/captures, or removal outside REA's requested cleanup scope was observed. The tested exception requires absent FreeBuff/ZCode product-discovery directories and malformed shared JSON. The ZCode-present control stops before removal. Omitting --purge-data was verified to preserve cache/state in the same malformed/shared case; it remains an uninstall and may remove REA integrations. Do not use malformed shared configuration as a way to prevent uninstall changes. NOT_ENOUGH_INFO: affected-user frequency and other-platform behavior were not measured.

REA version

Source package 6.8.0 at ace4dbf36e8c8f36a0e192aff9a11484ed428358, using its existing built runtime.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1; darwin arm64. No native agent or analysis engine was used.

Target and artifact context

Synthetic shared MCP JSON and disposable REA cache/state marker files; no analysis target or captured artifact.

Interface

CLI

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

  • Expected source: docs/installation.md:433-454, especially the unconditional malformed/unreadable/unsafe client-configuration stopping rule at lines 440-442. The surrounding custom-cache, repeated-member, and purge-symlink qualifications do not describe the shared-storage exception. docs/client-configuration.md:588-602 explains profile-based discovery without explaining continued purge in this situation.
  • Failure source: the public CLI execution and filesystem checks in the inline reproduction, with results below. The route is src/cli/setupCommands.ts:164-183 to src/application/Uninstall.ts:155-198; shared applicability is decided at lines 462-518, retained parse failures pass preflight at lines 522-535 and 702-748, and continued removal reaches purge at lines 231-250. tests/boundary/filesystem/freebuffClientConfiguration.test.ts:317-347 explicitly expects malformed shared settings not to block unrelated removals.
  • Evidence provenance: observed for public CLI results, unchanged configuration bytes, and marker deletion/preservation; static for the source/test explanation.
  • Local verification: reproduced.
  • Reproduction completeness: complete.

Exact output of the inline reproduction:

{"case": "shared-absent", "exit": 0, "status": "complete", "freebuff": "retained", "configuration_unchanged": true, "cache_exists": false, "state_exists": false}
{"case": "zcode-present", "exit": 1, "status": "failed", "freebuff": "failed", "configuration_unchanged": true, "cache_exists": true, "state_exists": true}
{"case": "valid-control", "exit": 0, "status": "complete", "freebuff": "skipped", "configuration_unchanged": true, "cache_exists": false, "state_exists": false}
{"case": "no-purge", "exit": 0, "status": "complete", "freebuff": "retained", "configuration_unchanged": true, "cache_exists": true, "state_exists": true}

The first case's FreeBuff detail also states: Product applicability could not be established. Shared configuration was retained without blocking other REA removals. Configuration is not valid JSON and was not changed. Repair it, then rerun uninstall. This describes the exception after the removals have occurred.

Additional context

Restoration check, proposed and unexecuted: read the maintenance guidance against these same four results. It should make clear before execution that the absent-product malformed shared file is retained without preventing purge, while the ZCode-present malformed-file case blocks removal. Keep both runtime outcomes and the no-purge data-preservation control intact; a runtime change is not needed to establish documentation accuracy.

Related histories were inspected: #1164 was closed by #1177, which restored stopping for malformed client configurations. The current ZCode-present control still satisfies that contract. The later merged #2736 discussion explicitly describes retaining malformed shared storage without blocking unrelated removals. Closed #6531 concerns omitted current cache locations; open #7207 concerns alternate spellings of the default Kuna cache. Neither reports this documentation mismatch. The open-and-closed issue snapshot, matching full bodies, and these histories contained no exact duplicate.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The inaccurate promise concerns whether a destructive cleanup proceeds: two public CLI executions deleted disposable REA cache/state after the documented stopping condition. This is a bounded documentation consequence with no demonstrated loss outside the requested REA cleanup scope. P3 would understate the effect on a reader's data-preservation decision; severe or irreversible user harm was not established.
  • Workaround status: available
  • Workaround basis: The executed no-purge control retained both cache/state markers with the same malformed shared file. Omit --purge-data when retaining that data is required, and do not invoke uninstall at all if no REA integration changes are desired. Reading the result after a purge is not a preventative workaround.
Originally created by @coygeek on GitHub (Oct 26, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7320 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area Documentation ## Observed behavior The installation guide says malformed client configuration stops uninstall before anything is removed. In a disposable home with malformed `.agents/mcp.json` and neither FreeBuff's profile nor ZCode's client directory present, the public `uninstall --purge-data --json` command instead exits 0 with `status: complete`. It reports the shared configuration as `retained`, leaves its bytes unchanged, and removes REA cache and state. This is a documentation mismatch with an intentional shared-storage exception. ## Reproduction Run the following from the baseline source checkout with its locked dependencies and built runtime available, Python 3 installed, and the pinned Node.js on PATH. It invokes the public dispatcher in disposable homes with fresh environments; no agent application or analysis provider is required. The first case reproduced in both independent executions; the controls below also ran successfully. ```python import json, os, pathlib, shutil, subprocess, tempfile cli = (pathlib.Path.cwd() / 'scripts/rea.mjs').resolve() node = pathlib.Path(shutil.which('node')).resolve() with tempfile.TemporaryDirectory(prefix='rea-uninstall-') as directory: for name, malformed, installed, purge in [ ('shared-absent', True, False, True), ('zcode-present', True, True, True), ('valid-control', False, False, True), ('no-purge', True, False, False), ]: home = pathlib.Path(directory) / name config = home / '.agents/mcp.json' config.parent.mkdir(parents=True) text = '{ "mcpServers": { "rea": { "command": "npx" } }' if malformed else '{}' config.write_text(text) markers = [home / '.rea' / part / 'marker' for part in ['cache', 'state']] for marker in markers: marker.parent.mkdir(parents=True) marker.write_text('disposable fixture') if installed: (home / '.zcode/cli').mkdir(parents=True) (home / 'temp').mkdir() env = {'PATH': str(node.parent) + os.pathsep + os.defpath, 'HOME': str(home), 'USERPROFILE': str(home), 'XDG_CONFIG_HOME': str(home / '.config'), 'XDG_CACHE_HOME': str(home / '.cache'), 'XDG_DATA_HOME': str(home / '.local/share'), 'XDG_STATE_HOME': str(home / '.local/state'), 'TMPDIR': str(home / 'temp'), 'NO_COLOR': '1'} args = [str(node), str(cli), 'uninstall', '--json'] if purge: args.append('--purge-data') process = subprocess.run(args, cwd=home, env=env, capture_output=True, text=True, timeout=45) result = json.loads(process.stdout) freebuff = next(item for item in result['items'] if item['name'] == 'freebuff') print(json.dumps({'case': name, 'exit': process.returncode, 'status': result['status'], 'freebuff': freebuff['status'], 'configuration_unchanged': config.read_text() == text, 'cache_exists': markers[0].exists(), 'state_exists': markers[1].exists()})) ``` ## Expected behavior The maintenance guide should accurately explain when malformed shared registration storage stops uninstall and when it is retained while other removals continue, including cache/state deletion with `--purge-data`. A reader should be able to determine the removal consequences before running the command. The existing shared-storage behavior is deliberate; this report does not request a different uninstall policy. ## Impact and scope A reader relying on the unconditional no-removal promise can invoke purge while expecting the malformed file to block it, then have REA cache and state removed. Only disposable markers were deleted here; no real user data loss, loss of Evidence/captures, or removal outside REA's requested cleanup scope was observed. The tested exception requires absent FreeBuff/ZCode product-discovery directories and malformed shared JSON. The ZCode-present control stops before removal. Omitting `--purge-data` was verified to preserve cache/state in the same malformed/shared case; it remains an uninstall and may remove REA integrations. Do not use malformed shared configuration as a way to prevent uninstall changes. NOT_ENOUGH_INFO: affected-user frequency and other-platform behavior were not measured. ## REA version Source package 6.8.0 at `ace4dbf36e8c8f36a0e192aff9a11484ed428358`, using its existing built runtime. ## Runtime and platform Node.js v24.22.1; macOS 27.0.1; darwin arm64. No native agent or analysis engine was used. ## Target and artifact context Synthetic shared MCP JSON and disposable REA cache/state marker files; no analysis target or captured artifact. ## Interface CLI ## Earliest failure stage Cleanup, cancellation, or lifecycle ## Relevant output or evidence - Expected source: `docs/installation.md:433-454`, especially the unconditional malformed/unreadable/unsafe client-configuration stopping rule at lines 440-442. The surrounding custom-cache, repeated-member, and purge-symlink qualifications do not describe the shared-storage exception. `docs/client-configuration.md:588-602` explains profile-based discovery without explaining continued purge in this situation. - Failure source: the public CLI execution and filesystem checks in the inline reproduction, with results below. The route is `src/cli/setupCommands.ts:164-183` to `src/application/Uninstall.ts:155-198`; shared applicability is decided at lines 462-518, retained parse failures pass preflight at lines 522-535 and 702-748, and continued removal reaches purge at lines 231-250. `tests/boundary/filesystem/freebuffClientConfiguration.test.ts:317-347` explicitly expects malformed shared settings not to block unrelated removals. - Evidence provenance: observed for public CLI results, unchanged configuration bytes, and marker deletion/preservation; static for the source/test explanation. - Local verification: reproduced. - Reproduction completeness: complete. Exact output of the inline reproduction: ```json {"case": "shared-absent", "exit": 0, "status": "complete", "freebuff": "retained", "configuration_unchanged": true, "cache_exists": false, "state_exists": false} {"case": "zcode-present", "exit": 1, "status": "failed", "freebuff": "failed", "configuration_unchanged": true, "cache_exists": true, "state_exists": true} {"case": "valid-control", "exit": 0, "status": "complete", "freebuff": "skipped", "configuration_unchanged": true, "cache_exists": false, "state_exists": false} {"case": "no-purge", "exit": 0, "status": "complete", "freebuff": "retained", "configuration_unchanged": true, "cache_exists": true, "state_exists": true} ``` The first case's FreeBuff detail also states: `Product applicability could not be established. Shared configuration was retained without blocking other REA removals. Configuration is not valid JSON and was not changed. Repair it, then rerun uninstall.` This describes the exception after the removals have occurred. ## Additional context Restoration check, proposed and unexecuted: read the maintenance guidance against these same four results. It should make clear before execution that the absent-product malformed shared file is retained without preventing purge, while the ZCode-present malformed-file case blocks removal. Keep both runtime outcomes and the no-purge data-preservation control intact; a runtime change is not needed to establish documentation accuracy. Related histories were inspected: [#1164](https://github.com/morluto/rea/issues/1164) was closed by [#1177](https://github.com/morluto/rea/pull/1177), which restored stopping for malformed client configurations. The current ZCode-present control still satisfies that contract. The later merged [#2736 discussion](https://github.com/morluto/rea/pull/2736#issuecomment-6147242391) explicitly describes retaining malformed shared storage without blocking unrelated removals. Closed [#6531](https://github.com/morluto/rea/issues/6531) concerns omitted current cache locations; open [#7207](https://github.com/morluto/rea/pull/7207) concerns alternate spellings of the default Kuna cache. Neither reports this documentation mismatch. The open-and-closed issue snapshot, matching full bodies, and these histories contained no exact duplicate. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The inaccurate promise concerns whether a destructive cleanup proceeds: two public CLI executions deleted disposable REA cache/state after the documented stopping condition. This is a bounded documentation consequence with no demonstrated loss outside the requested REA cleanup scope. P3 would understate the effect on a reader's data-preservation decision; severe or irreversible user harm was not established. - Workaround status: available - Workaround basis: The executed no-purge control retained both cache/state markers with the same malformed shared file. Omit `--purge-data` when retaining that data is required, and do not invoke uninstall at all if no REA integration changes are desired. Reading the result after a purge is not a preventative workaround.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4350
No description provided.