[GH-ISSUE #7693] [Bug] Setup announces cache preparation without resolving a direct-launcher skip #4615

Open
opened 2026-10-31 00:51:23 +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/7693

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

After approving node scripts/rea.mjs setup --client codex --skill=false, the interactive CLI prints ◇ REA package-runner cache · Preparing the pinned package entry. It subsequently prints the successful setup summary and exits 0, without another line resolving that cache operation. The same behavior occurred with --client claude_code.

The corresponding fresh-home commands with --yes --json both return status: "ready" and prewarm: {"status":"skipped","reason":"direct_launcher"}. Thus the human output announces preparation for work that correctly skips, and leaves that operation represented only by its active marker.

These were real public CLI executions with a preload simulating TTY flags because this verification environment has no PTY. The preload does not replace the setup workflow or its progress renderer.

Reproduction

  1. At the source revision below, use the already-built runtime and locked dependencies with Node 24.22.1 on PATH. From the checkout root, execute this script. It creates fresh isolated homes for both clients and controls, places harmless runner fixtures first on PATH, approves the interactive prompts with Enter, checks the relevant output, and deletes its disposable directory.
set -eu
WORK=$(mktemp -d)
NODE_BIN=$(dirname "$(node -p 'process.execPath')")
mkdir -p "$WORK/bin"
for runner in npx npm bun; do
  printf '#!/bin/sh\nprintf "fixture-runner\\n"\n' > "$WORK/bin/$runner"
  chmod +x "$WORK/bin/$runner"
done
cat > "$WORK/tty.cjs" <<'JS'
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 = () => {};
JS
run_rea() {
  case_name=$1
  shift
  trial_home="$WORK/$case_name"
  mkdir -p "$trial_home"
  env -i HOME="$trial_home" DSH_HOME="$trial_home/.dsh" \
    DSH_AGENTS_HOME="$trial_home/.dsh/agents" \
    XDG_CONFIG_HOME="$trial_home/.config" \
    XDG_DATA_HOME="$trial_home/.local/share" \
    XDG_CACHE_HOME="$trial_home/.cache" \
    XDG_STATE_HOME="$trial_home/.local/state" \
    TMPDIR="$trial_home" npm_config_prefix="$trial_home/.npm-global" \
    PATH="$WORK/bin:$NODE_BIN:/usr/bin:/bin:/usr/sbin:/sbin" \
    NO_COLOR=1 TERM=xterm-256color node "$@"
}
for client in codex claude_code; do
  printf '\r' | run_rea "$client-interactive" --require "$WORK/tty.cjs" \
    scripts/rea.mjs setup --client "$client" --skill=false \
    > "$WORK/$client.stdout" 2> "$WORK/$client.stderr"
  run_rea "$client-json" scripts/rea.mjs setup --client "$client" \
    --skill=false --yes --json > "$WORK/$client.json"
done
python3 - "$WORK" <<'PY'
from pathlib import Path
import json,sys,re
s=Path(sys.argv[1])
for client in ['codex','claude_code']:
 text=re.sub(r'\x1b\[[0-?]*[ -/]*[@-~]','',(s/(client+'.stderr')).read_text())
 cache=[line for line in text.splitlines() if 'REA package-runner cache' in line]
 data=json.loads((s/(client+'.json')).read_text())
 print(client, 'cache_lines=',cache,'status=',data['status'],'prewarm=',data['prewarm'])
 assert len(cache)==1 and cache[0].startswith('◇')
 assert data['status']=='ready' and data['prewarm']=={'status':'skipped','reason':'direct_launcher'}
 assert 'Restart ' in text
PY
rm -rf "$WORK"

  1. Both printed results contain exactly one cache line beginning with ◇, alongside a successful JSON control reporting skipped / direct_launcher. Inspecting the complete interactive stderr also showed the client completed and the final restart message, with no settled cache line.

Frequency: four interactive executions reproduced the presentation defect, two per client. Four fresh JSON controls returned the same skipped outcome, two per client. The script above accounts for one pair per client; the other executions used an equivalent isolated subprocess driver.

Expected behavior

The progress output should communicate that cache preparation has finished or was unnecessary before presenting setup as complete. A direct launcher should either omit this inapplicable preparation announcement or resolve it with the actual skipped outcome.

The documented package-runner warm-up is best-effort and concerns pinned package entries. The progress model distinguishes active and settled operations, and its append-only renderer distinguishes their symbols. A final success summary does not identify what happened to the separately announced cache operation. Exact source references appear under evidence below.

Impact and scope

P3: misleading progress text in an otherwise successful setup. Both tested clients received configured results, and every execution exited 0. No setup hang, failed registration, incorrect readiness result, or data loss was observed.

Observed scope is the source-checkout direct launcher on macOS with three simulated TTY streams. Actual global installations, package-runner registrations, real terminals and other platforms were not exercised. No claim about their reproduction frequency is made. The demonstrated automation alternative is the explicit --yes --json path, which accurately reports the skipped outcome.

REA version

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

6.8.0

Source revision: 65f1c447344a423fa2785847dbcea1e9a9e2454a.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1; arm64. TTY flags and raw-mode entry were simulated with the inline preload. No provider analysis or package installation was requested.

Target and artifact context

Setup-only runs, each with a fresh home and no existing client configuration. Harmless npx, npm and bun fixtures prevent real package-manager work if discovered; the tested direct launcher does not require runner-cache materialization.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

The interactive Codex run emitted this sequence on stderr, shortened only by omitting unrelated summary details:

◇  Codex
◆  Codex
◇  REA package-runner cache · Preparing the pinned package entry
◆  What you can do now
...
└  Restart Codex to load REA.

Claude Code emitted the same single cache line and ended with Restart Claude Code to load REA.. Both exited 0. In every complete stderr capture, the cache label occurred once; no later completed, warning, failed or skipped cache line appeared.

Fresh-home structured controls returned:

{"status":"ready","appliedActions":["configured_codex"],"prewarm":{"status":"skipped","reason":"direct_launcher"}}
{"status":"ready","appliedActions":["configured_claude_code"],"prewarm":{"status":"skipped","reason":"direct_launcher"}}

These are selected fields from the actual JSON results. Each client's configuration result was {"status":"configured"}.

At the recorded revision:

  • docs/installation.md:132-138 documents stderr progress and the three-TTY condition; docs/installation.md:1582-1594 explains bounded package-runner cache preparation.
  • src/application/SetupTypes.ts:254-260 defines active/settled progress states; src/cli/interactiveSetup.ts:71-84 implements stable append-only rendering with ◇, ◆, ! and ✗.
  • src/application/Setup.ts:390-427 announces preparation after an approved client registration, then emits a closing progress event only for warmed or failed results.
  • src/application/SetupRegistrationPrewarm.ts:68-95 treats direct launchers as having no runner cache and returns the skipped/direct_launcher result.
  • src/cli/setupCommands.ts:235-245 and src/cli/setupCommands.ts:288 connect this workflow to the public interactive command and final summary.

Typed outcome or recovery expected

Retain the correct structured skipped outcome and successful configuration. The terminal projection should resolve the operation consistently with that outcome, or avoid announcing cache preparation when it does not apply.

Analysis or suspected cause

Source-derived cause: the normal skipped prewarm result has no closing progress branch after an unconditional started event. The following final doctor and success rendering do not revisit that event. The progress type currently has no explicit skipped state; adding one is only one possible repair, and is not required to preserve the existing public result shape.

Additional context

Duplicate searches covered open and closed issues, all PR states, issue comments and the review discussions for PRs #2185 and #7032. No matching report was found.

  • Closed #7027 and merged #7032 concern pinned package installation exceeding the first client startup deadline. Their fix introduced this step. The progress review and reply discuss progress while a cold install actually runs, not the skipped direct-launcher case. This report does not show a regression of the startup-timeout fix.
  • Open #2185 and closed #2164 concern missing noninteractive summaries and dry-run plans. Here interactive setup already prints progress and a success summary; the cache operation's final state is missing.
  • Closed #5105 concerns false Kuna readiness; open #7275 concerns provider capitalization. Neither describes the cache operation state.

Triage assessment

  • Impact level: P3
  • Assessment status: supported
  • Impact basis: Four successful interactive CLI executions left only an active cache marker for a skipped operation. Configurations, readiness and exit status remained successful; the demonstrated defect is presentation only.
  • Workaround status: available
  • Workaround basis: Four fresh --yes --json controls completed setup and reported skipped/direct_launcher accurately, including both tested clients.
Originally created by @coygeek on GitHub (Oct 28, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7693 ### 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 After approving `node scripts/rea.mjs setup --client codex --skill=false`, the interactive CLI prints `◇ REA package-runner cache · Preparing the pinned package entry`. It subsequently prints the successful setup summary and exits 0, without another line resolving that cache operation. The same behavior occurred with `--client claude_code`. The corresponding fresh-home commands with `--yes --json` both return `status: "ready"` and `prewarm: {"status":"skipped","reason":"direct_launcher"}`. Thus the human output announces preparation for work that correctly skips, and leaves that operation represented only by its active marker. These were real public CLI executions with a preload simulating TTY flags because this verification environment has no PTY. The preload does not replace the setup workflow or its progress renderer. ### Reproduction 1. At the source revision below, use the already-built runtime and locked dependencies with Node 24.22.1 on PATH. From the checkout root, execute this script. It creates fresh isolated homes for both clients and controls, places harmless runner fixtures first on PATH, approves the interactive prompts with Enter, checks the relevant output, and deletes its disposable directory. ```sh set -eu WORK=$(mktemp -d) NODE_BIN=$(dirname "$(node -p 'process.execPath')") mkdir -p "$WORK/bin" for runner in npx npm bun; do printf '#!/bin/sh\nprintf "fixture-runner\\n"\n' > "$WORK/bin/$runner" chmod +x "$WORK/bin/$runner" done cat > "$WORK/tty.cjs" <<'JS' 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 = () => {}; JS run_rea() { case_name=$1 shift trial_home="$WORK/$case_name" mkdir -p "$trial_home" env -i HOME="$trial_home" DSH_HOME="$trial_home/.dsh" \ DSH_AGENTS_HOME="$trial_home/.dsh/agents" \ XDG_CONFIG_HOME="$trial_home/.config" \ XDG_DATA_HOME="$trial_home/.local/share" \ XDG_CACHE_HOME="$trial_home/.cache" \ XDG_STATE_HOME="$trial_home/.local/state" \ TMPDIR="$trial_home" npm_config_prefix="$trial_home/.npm-global" \ PATH="$WORK/bin:$NODE_BIN:/usr/bin:/bin:/usr/sbin:/sbin" \ NO_COLOR=1 TERM=xterm-256color node "$@" } for client in codex claude_code; do printf '\r' | run_rea "$client-interactive" --require "$WORK/tty.cjs" \ scripts/rea.mjs setup --client "$client" --skill=false \ > "$WORK/$client.stdout" 2> "$WORK/$client.stderr" run_rea "$client-json" scripts/rea.mjs setup --client "$client" \ --skill=false --yes --json > "$WORK/$client.json" done python3 - "$WORK" <<'PY' from pathlib import Path import json,sys,re s=Path(sys.argv[1]) for client in ['codex','claude_code']: text=re.sub(r'\x1b\[[0-?]*[ -/]*[@-~]','',(s/(client+'.stderr')).read_text()) cache=[line for line in text.splitlines() if 'REA package-runner cache' in line] data=json.loads((s/(client+'.json')).read_text()) print(client, 'cache_lines=',cache,'status=',data['status'],'prewarm=',data['prewarm']) assert len(cache)==1 and cache[0].startswith('◇') assert data['status']=='ready' and data['prewarm']=={'status':'skipped','reason':'direct_launcher'} assert 'Restart ' in text PY rm -rf "$WORK" ``` 2. Both printed results contain exactly one cache line beginning with `◇`, alongside a successful JSON control reporting `skipped` / `direct_launcher`. Inspecting the complete interactive stderr also showed the client completed and the final restart message, with no settled cache line. Frequency: four interactive executions reproduced the presentation defect, two per client. Four fresh JSON controls returned the same skipped outcome, two per client. The script above accounts for one pair per client; the other executions used an equivalent isolated subprocess driver. ### Expected behavior The progress output should communicate that cache preparation has finished or was unnecessary before presenting setup as complete. A direct launcher should either omit this inapplicable preparation announcement or resolve it with the actual skipped outcome. The documented package-runner warm-up is best-effort and concerns pinned package entries. The progress model distinguishes active and settled operations, and its append-only renderer distinguishes their symbols. A final success summary does not identify what happened to the separately announced cache operation. Exact source references appear under evidence below. ### Impact and scope P3: misleading progress text in an otherwise successful setup. Both tested clients received configured results, and every execution exited 0. No setup hang, failed registration, incorrect readiness result, or data loss was observed. Observed scope is the source-checkout direct launcher on macOS with three simulated TTY streams. Actual global installations, package-runner registrations, real terminals and other platforms were not exercised. No claim about their reproduction frequency is made. The demonstrated automation alternative is the explicit `--yes --json` path, which accurately reports the skipped outcome. ### REA version Exact stdout from `node scripts/rea.mjs --version`: ```text 6.8.0 ``` Source revision: `65f1c447344a423fa2785847dbcea1e9a9e2454a`. ### Runtime and platform Node.js `v24.22.1`; macOS `27.0.1`; `arm64`. TTY flags and raw-mode entry were simulated with the inline preload. No provider analysis or package installation was requested. ### Target and artifact context Setup-only runs, each with a fresh home and no existing client configuration. Harmless `npx`, `npm` and `bun` fixtures prevent real package-manager work if discovered; the tested direct launcher does not require runner-cache materialization. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence The interactive Codex run emitted this sequence on stderr, shortened only by omitting unrelated summary details: ```text ◇ Codex ◆ Codex ◇ REA package-runner cache · Preparing the pinned package entry ◆ What you can do now ... └ Restart Codex to load REA. ``` Claude Code emitted the same single cache line and ended with `Restart Claude Code to load REA.`. Both exited 0. In every complete stderr capture, the cache label occurred once; no later completed, warning, failed or skipped cache line appeared. Fresh-home structured controls returned: ```json {"status":"ready","appliedActions":["configured_codex"],"prewarm":{"status":"skipped","reason":"direct_launcher"}} ``` ```json {"status":"ready","appliedActions":["configured_claude_code"],"prewarm":{"status":"skipped","reason":"direct_launcher"}} ``` These are selected fields from the actual JSON results. Each client's configuration result was `{"status":"configured"}`. At the recorded revision: - `docs/installation.md:132-138` documents stderr progress and the three-TTY condition; `docs/installation.md:1582-1594` explains bounded package-runner cache preparation. - `src/application/SetupTypes.ts:254-260` defines active/settled progress states; `src/cli/interactiveSetup.ts:71-84` implements stable append-only rendering with `◇`, `◆`, `!` and `✗`. - `src/application/Setup.ts:390-427` announces preparation after an approved client registration, then emits a closing progress event only for warmed or failed results. - `src/application/SetupRegistrationPrewarm.ts:68-95` treats direct launchers as having no runner cache and returns the skipped/direct_launcher result. - `src/cli/setupCommands.ts:235-245` and `src/cli/setupCommands.ts:288` connect this workflow to the public interactive command and final summary. ### Typed outcome or recovery expected Retain the correct structured skipped outcome and successful configuration. The terminal projection should resolve the operation consistently with that outcome, or avoid announcing cache preparation when it does not apply. ### Analysis or suspected cause Source-derived cause: the normal `skipped` prewarm result has no closing progress branch after an unconditional started event. The following final doctor and success rendering do not revisit that event. The progress type currently has no explicit skipped state; adding one is only one possible repair, and is not required to preserve the existing public result shape. ### Additional context Duplicate searches covered open and closed issues, all PR states, issue comments and the review discussions for PRs #2185 and #7032. No matching report was found. - Closed [#7027](https://github.com/morluto/rea/issues/7027) and merged [#7032](https://github.com/morluto/rea/pull/7032) concern pinned package installation exceeding the first client startup deadline. Their fix introduced this step. The [progress review](https://github.com/morluto/rea/pull/7032#discussion_r4368003350) and [reply](https://github.com/morluto/rea/pull/7032#discussion_r4368035190) discuss progress while a cold install actually runs, not the skipped direct-launcher case. This report does not show a regression of the startup-timeout fix. - Open [#2185](https://github.com/morluto/rea/pull/2185) and closed [#2164](https://github.com/morluto/rea/issues/2164) concern missing noninteractive summaries and dry-run plans. Here interactive setup already prints progress and a success summary; the cache operation's final state is missing. - Closed [#5105](https://github.com/morluto/rea/issues/5105) concerns false Kuna readiness; open [#7275](https://github.com/morluto/rea/issues/7275) concerns provider capitalization. Neither describes the cache operation state. ## Triage assessment - Impact level: P3 - Assessment status: supported - Impact basis: Four successful interactive CLI executions left only an active cache marker for a skipped operation. Configurations, readiness and exit status remained successful; the demonstrated defect is presentation only. - Workaround status: available - Workaround basis: Four fresh `--yes --json` controls completed setup and reported skipped/direct_launcher accurately, including both tested clients.
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#4615
No description provided.