[GH-ISSUE #7692] [Bug] Grok Bot setup reveals its required manual connector step only after interactive approval #4612

Open
opened 2026-10-31 00:51:21 +00:00 by bsakaguchi · 0 comments
Owner

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

Before submitting

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

Area

Setup, packaging, or upgrade

Observed behavior

With a fresh configuration home, node scripts/rea.mjs setup --client grok_bot asks the caller to approve one skill installation. The approval view never identifies Grok Bot or says its connector must be added manually on the hosted computer. After Enter approves that skill write, setup installs the skill, prints the hosted-connector instructions, and exits 1.

The same scope with --dry-run --json returns planned and includes those instructions in remediation before any write. The missing information is already known while preparing the approval view.

The interactive observation used the public CLI with a Node preload setting the three standard streams' TTY properties and stubbing raw mode, because this verification environment has no PTY. It exercised the actual confirmation and application path, rather than a replacement renderer. Physical-terminal behavior was not separately tested.

Reproduction

  1. Use the built source baseline below with Node.js 24.22.1 available as node. From its root, execute this Python fixture. It creates fresh homes, supplies inert package-runner fixtures before system tools on PATH, drives Enter through the interactive command, and compares the nonterminal plan. All generated files are deleted on exit.
import json
import os
from pathlib import Path
import re
import shutil
import subprocess
import tempfile

node = shutil.which("node")
assert node
assert subprocess.check_output([node, "--version"], text=True).strip() == "v24.22.1"
with tempfile.TemporaryDirectory() as directory:
    root = Path(directory)
    bin_dir = root / "bin"
    bin_dir.mkdir()
    for name in ("npx", "npm", "bun"):
        runner = bin_dir / name
        runner.write_text("#!/bin/sh\nexit 0\n")
        runner.chmod(0o755)
    tty = root / "tty.cjs"
    tty.write_text("""
for (const stream of [process.stdin, process.stdout, process.stderr]) {
  Object.defineProperty(stream, 'isTTY', {value: true, configurable: true});
  Object.defineProperty(stream, 'columns', {value: 100, configurable: true});
  Object.defineProperty(stream, 'rows', {value: 40, configurable: true});
}
process.stdin.setRawMode = () => {};
""")
    for terminal in (True, False):
        home = root / ("interactive" if terminal else "control")
        home.mkdir()
        env = {
            "PATH": str(bin_dir) + os.pathsep + str(Path(node).parent)
                    + os.pathsep + "/usr/bin:/bin:/usr/sbin:/sbin",
            "HOME": str(home), "DSH_HOME": str(home / ".dsh"),
            "DSH_AGENTS_HOME": str(home / ".dsh-agents"),
            "XDG_CONFIG_HOME": str(home / ".config"),
            "XDG_DATA_HOME": str(home / ".local/share"),
            "XDG_CACHE_HOME": str(home / ".cache"),
            "XDG_STATE_HOME": str(home / ".local/state"),
            "TMPDIR": str(root), "NO_COLOR": "1",
            "npm_config_prefix": str(home / ".npm-global"),
        }
        command = [node]
        if terminal:
            command += ["--require", str(tty)]
        command += ["scripts/rea.mjs", "setup", "--client", "grok_bot"]
        if not terminal:
            command += ["--dry-run", "--json"]
        result = subprocess.run(command, env=env, capture_output=True,
                                text=True, input="\r" if terminal else "",
                                timeout=60)
        print("interactive" if terminal else "control", "exit", result.returncode)
        print("skill_written", (home / ".agents/skills/reverse-engineer-anything/SKILL.md").is_file())
        if terminal:
            output = re.sub(r"\x1b\[[0-?]*[ -/]*[@-~]", "", result.stderr)
            before = output.split("Apply this change?", 1)[0]
            print("manual_before_approval", "Grok Bot" in before)
            print(output.replace(str(root), "<fixture>"))
        else:
            plan = json.loads(result.stdout)
            print("status", plan["status"])
            print("actions", [action["id"] for action in plan["plannedActions"]])
            print("remediation", plan.get("remediation"))
  1. The interactive output shows only the skill installation before Apply this change?; manual_before_approval is false. After Enter, the skill exists and the output explains the manual hosted connector. The process exits 1.
  2. The control returns exit 0, planned, action install_skill, and the hosted-connector remediation, with skill_written false.

The interactive failure and structured plan control each reproduced twice in separate fresh homes during this verification, including execution of the fixture above.

Expected behavior

When setup asks for approval for an explicitly selected client, disclose a known manual connector requirement in that approval view. For Grok Bot, tell the caller before the Apply question that this run can install the skill but cannot register the requested hosted connector, and show the manual completion step.

The installation contract requires reviewing the selected plan before writes, and Grok Bot's documented setup contract requires manual registration on its hosted computer. Keep the intentional absence of a local connector write and the truthful final needs_human result; the requested correction is when the caller learns this limitation.

Impact and scope

P2: a caller approves a skill-only change without being told that setup cannot configure the explicitly requested integration. The limitation appears only after the local write and a nonzero result. The approved skill write itself matches the displayed action; no unapproved mutation, data loss, hosted-account change, or security boundary crossing was observed.

A demonstrated workaround is to inspect setup --client grok_bot --dry-run --json before using the interactive command: the structured plan includes the required manual step and writes nothing. Observations cover a fresh home on macOS. Existing skills, mixed client selections, real terminals, and other operating systems were not tested.

REA version

Exact node scripts/rea.mjs --version stdout:

6.8.0

Source commit: 65f1c447344a423fa2785847dbcea1e9a9e2454a.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1; Darwin arm64. The verification used a TTY-property preload and piped Enter, with no PTY or live Grok Bot account. Inert npx/npm/bun fixtures prevented package-runner side effects.

Target and artifact context

No analysis target. Each invocation used an empty disposable HOME and XDG configuration, with the DeepSeek Harness home and agents paths explicitly redirected into that fixture.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

Reduced interactive stderr, with the fixture path replaced:

◆  Ready to review
│  INSTALL  REA reverse-engineering skill
│          <fixture>/interactive/.agents/skills/reverse-engineer-anything
│          Install or update the bundled REA reverse-engineering skill and on-demand references.
◆  Apply this change?
│  ● Yes, apply / ○ No, cancel

After approval, the same run prints skill progress and then:

!  Run rea doctor and apply each reported remediation. Grok Bot keeps connectors in the signed-in account and runs them on its hosted computer. Setup does not write that account store, and a data-directory mcp.json is not a registration.

The remaining paragraph tells the caller to add rea in Grok Bot chat with npx -y rea-agents@<version> mcp on the Bot's computer. The dry-run JSON control includes that paragraph in remediation, returns planned, and has no applied actions.

Expected-source references at the baseline: AGENTS.md:11; docs/installation.md:35-59,125-138,612-614; docs/client-configuration.md:715-730. Explicit manual selection is also intentionally covered in src/application/Setup.planning.test.ts:660-690.

Failure-source references: src/application/Setup.ts:264-297 computes the manual remediation before invoking confirmation but omits it from the confirmation context; src/application/SetupTypes.ts:270-275 defines that context; src/cli/interactiveSetup.ts:35-69,289-311 renders only the actions at confirmation. The public CLI passes this callback at src/cli/setupCommands.ts:235-242 and admits the TTY branch at :304-316.

Typed outcome or recovery expected

For an explicit fresh-home Grok Bot interactive setup, require the hosted-connector limitation and manual completion instruction to appear before Apply this change?. The selected skill action can remain an approved local installation. Preserve the structured plan remediation and the final manual-required status.

Analysis or suspected cause

Source-derived: manual remediation is part of the application result but is not passed to the confirmation adapter. The confirmation view consumes planned actions, which correctly contain no local Grok Bot registration. Rendering those actions alone loses the selected client's manual completion requirement.

Additional context

This differs from #7522, which concerns automatically selecting Grok Bot with --all-detected. Its proposed closure preserves explicit manual selection, so it does not repair this command.

PR #2185's manual dry-run comment already reports omitted manual remediation for terminal --dry-run. That duplicate should not be filed again. This report concerns the actual confirmation callback before approval; rendering the dry-run result does not change that callback, and disclosing the manual step at confirmation would not itself fix dry-run output. The current PR diff leaves the confirmation context without the manual remediation.

No same-contract, same-closure report was found in the open/closed issue, all-state PR, and comment searches. No last-known-good version or fixed build was tested.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The actual interactive CLI withheld the explicitly selected client's known manual requirement until after the listed skill write was approved and completed; setup then exited 1. The observed effect is bounded and no data loss or unauthorized write occurred.
  • Workaround status: available
  • Workaround basis: In fresh homes, --dry-run --json returned planned with the hosted-connector remediation and no skill write, allowing the caller to review the requirement before applying.
Originally created by @coygeek on GitHub (Oct 28, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7692 ### 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 Setup, packaging, or upgrade ### Observed behavior With a fresh configuration home, `node scripts/rea.mjs setup --client grok_bot` asks the caller to approve one skill installation. The approval view never identifies Grok Bot or says its connector must be added manually on the hosted computer. After Enter approves that skill write, setup installs the skill, prints the hosted-connector instructions, and exits 1. The same scope with `--dry-run --json` returns `planned` and includes those instructions in `remediation` before any write. The missing information is already known while preparing the approval view. The interactive observation used the public CLI with a Node preload setting the three standard streams' TTY properties and stubbing raw mode, because this verification environment has no PTY. It exercised the actual confirmation and application path, rather than a replacement renderer. Physical-terminal behavior was not separately tested. ### Reproduction 1. Use the built source baseline below with Node.js 24.22.1 available as `node`. From its root, execute this Python fixture. It creates fresh homes, supplies inert package-runner fixtures before system tools on PATH, drives Enter through the interactive command, and compares the nonterminal plan. All generated files are deleted on exit. ```python import json import os from pathlib import Path import re import shutil import subprocess import tempfile node = shutil.which("node") assert node assert subprocess.check_output([node, "--version"], text=True).strip() == "v24.22.1" with tempfile.TemporaryDirectory() as directory: root = Path(directory) bin_dir = root / "bin" bin_dir.mkdir() for name in ("npx", "npm", "bun"): runner = bin_dir / name runner.write_text("#!/bin/sh\nexit 0\n") runner.chmod(0o755) tty = root / "tty.cjs" tty.write_text(""" for (const stream of [process.stdin, process.stdout, process.stderr]) { Object.defineProperty(stream, 'isTTY', {value: true, configurable: true}); Object.defineProperty(stream, 'columns', {value: 100, configurable: true}); Object.defineProperty(stream, 'rows', {value: 40, configurable: true}); } process.stdin.setRawMode = () => {}; """) for terminal in (True, False): home = root / ("interactive" if terminal else "control") home.mkdir() env = { "PATH": str(bin_dir) + os.pathsep + str(Path(node).parent) + os.pathsep + "/usr/bin:/bin:/usr/sbin:/sbin", "HOME": str(home), "DSH_HOME": str(home / ".dsh"), "DSH_AGENTS_HOME": str(home / ".dsh-agents"), "XDG_CONFIG_HOME": str(home / ".config"), "XDG_DATA_HOME": str(home / ".local/share"), "XDG_CACHE_HOME": str(home / ".cache"), "XDG_STATE_HOME": str(home / ".local/state"), "TMPDIR": str(root), "NO_COLOR": "1", "npm_config_prefix": str(home / ".npm-global"), } command = [node] if terminal: command += ["--require", str(tty)] command += ["scripts/rea.mjs", "setup", "--client", "grok_bot"] if not terminal: command += ["--dry-run", "--json"] result = subprocess.run(command, env=env, capture_output=True, text=True, input="\r" if terminal else "", timeout=60) print("interactive" if terminal else "control", "exit", result.returncode) print("skill_written", (home / ".agents/skills/reverse-engineer-anything/SKILL.md").is_file()) if terminal: output = re.sub(r"\x1b\[[0-?]*[ -/]*[@-~]", "", result.stderr) before = output.split("Apply this change?", 1)[0] print("manual_before_approval", "Grok Bot" in before) print(output.replace(str(root), "<fixture>")) else: plan = json.loads(result.stdout) print("status", plan["status"]) print("actions", [action["id"] for action in plan["plannedActions"]]) print("remediation", plan.get("remediation")) ``` 2. The interactive output shows only the skill installation before `Apply this change?`; `manual_before_approval` is false. After Enter, the skill exists and the output explains the manual hosted connector. The process exits 1. 3. The control returns exit 0, `planned`, action `install_skill`, and the hosted-connector remediation, with `skill_written` false. The interactive failure and structured plan control each reproduced twice in separate fresh homes during this verification, including execution of the fixture above. ### Expected behavior When setup asks for approval for an explicitly selected client, disclose a known manual connector requirement in that approval view. For Grok Bot, tell the caller before the Apply question that this run can install the skill but cannot register the requested hosted connector, and show the manual completion step. The installation contract requires reviewing the selected plan before writes, and Grok Bot's documented setup contract requires manual registration on its hosted computer. Keep the intentional absence of a local connector write and the truthful final `needs_human` result; the requested correction is when the caller learns this limitation. ### Impact and scope P2: a caller approves a skill-only change without being told that setup cannot configure the explicitly requested integration. The limitation appears only after the local write and a nonzero result. The approved skill write itself matches the displayed action; no unapproved mutation, data loss, hosted-account change, or security boundary crossing was observed. A demonstrated workaround is to inspect `setup --client grok_bot --dry-run --json` before using the interactive command: the structured plan includes the required manual step and writes nothing. Observations cover a fresh home on macOS. Existing skills, mixed client selections, real terminals, and other operating systems were not tested. ### REA version Exact `node scripts/rea.mjs --version` stdout: ```text 6.8.0 ``` Source commit: `65f1c447344a423fa2785847dbcea1e9a9e2454a`. ### Runtime and platform Node.js v24.22.1; macOS 27.0.1; Darwin arm64. The verification used a TTY-property preload and piped Enter, with no PTY or live Grok Bot account. Inert npx/npm/bun fixtures prevented package-runner side effects. ### Target and artifact context No analysis target. Each invocation used an empty disposable HOME and XDG configuration, with the DeepSeek Harness home and agents paths explicitly redirected into that fixture. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence Reduced interactive stderr, with the fixture path replaced: ```text ◆ Ready to review │ INSTALL REA reverse-engineering skill │ <fixture>/interactive/.agents/skills/reverse-engineer-anything │ Install or update the bundled REA reverse-engineering skill and on-demand references. ◆ Apply this change? │ ● Yes, apply / ○ No, cancel ``` After approval, the same run prints skill progress and then: ```text ! Run rea doctor and apply each reported remediation. Grok Bot keeps connectors in the signed-in account and runs them on its hosted computer. Setup does not write that account store, and a data-directory mcp.json is not a registration. ``` The remaining paragraph tells the caller to add `rea` in Grok Bot chat with `npx -y rea-agents@<version> mcp` on the Bot's computer. The dry-run JSON control includes that paragraph in `remediation`, returns `planned`, and has no applied actions. Expected-source references at the baseline: `AGENTS.md:11`; `docs/installation.md:35-59,125-138,612-614`; `docs/client-configuration.md:715-730`. Explicit manual selection is also intentionally covered in `src/application/Setup.planning.test.ts:660-690`. Failure-source references: `src/application/Setup.ts:264-297` computes the manual remediation before invoking confirmation but omits it from the confirmation context; `src/application/SetupTypes.ts:270-275` defines that context; `src/cli/interactiveSetup.ts:35-69,289-311` renders only the actions at confirmation. The public CLI passes this callback at `src/cli/setupCommands.ts:235-242` and admits the TTY branch at `:304-316`. ### Typed outcome or recovery expected For an explicit fresh-home Grok Bot interactive setup, require the hosted-connector limitation and manual completion instruction to appear before `Apply this change?`. The selected skill action can remain an approved local installation. Preserve the structured plan remediation and the final manual-required status. ### Analysis or suspected cause Source-derived: manual remediation is part of the application result but is not passed to the confirmation adapter. The confirmation view consumes planned actions, which correctly contain no local Grok Bot registration. Rendering those actions alone loses the selected client's manual completion requirement. ### Additional context This differs from [#7522](https://github.com/morluto/rea/issues/7522), which concerns automatically selecting Grok Bot with `--all-detected`. Its proposed closure preserves explicit manual selection, so it does not repair this command. [PR #2185's manual dry-run comment](https://github.com/morluto/rea/pull/2185#discussion_r4248083900) already reports omitted manual remediation for terminal `--dry-run`. That duplicate should not be filed again. This report concerns the actual confirmation callback before approval; rendering the dry-run result does not change that callback, and disclosing the manual step at confirmation would not itself fix dry-run output. The current PR diff leaves the confirmation context without the manual remediation. No same-contract, same-closure report was found in the open/closed issue, all-state PR, and comment searches. No last-known-good version or fixed build was tested. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The actual interactive CLI withheld the explicitly selected client's known manual requirement until after the listed skill write was approved and completed; setup then exited 1. The observed effect is bounded and no data loss or unauthorized write occurred. - Workaround status: available - Workaround basis: In fresh homes, --dry-run --json returned planned with the hosted-connector remediation and no skill write, allowing the caller to review the requirement before applying.
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#4612
No description provided.