Skip to content

[Bug] Star-prompt agent deferral leaks into every editing session and re-arms on each agent-driven start #879

Description

@lidge-jun

Symptom

The one-time GitHub-star consent prompt is not one-time in practice. In any agent-driven coding session that runs `ocx start` (or `ocx service install`) — e.g. an agent editing this repo and smoke-testing its change — the terminal prints the agent deferral, the agent becomes a persistent relay for `Star lidge-jun/opencodex? Yes / No`, and the question reappears at the top of every subsequent reply, across turns and across unrelated sessions, until the user explicitly answers. Users experience this as the star prompt "showing up during editing, not at install."

Root cause

Three design decisions compound:

  1. The deferral is stateful-by-proxy, not on disk. `src/cli/star-prompt.ts` (`maybeShowStarPrompt`) deliberately leaves the `.star-prompted` marker unwritten for agent-driven runs, so the real prompt survives for a later hand-typed run. But that also means every agent-driven `ocx start` re-prints `printAgentDeferral()` — there is no deferral marker, counter, or cooldown.
  2. The deferral text recruits the agent as an unbounded relay. `printAgentDeferral()` instructs the agent: "Silence is not an answer... put the same Yes/No question at the top of your next reply, unchanged." AGENTS.md repeats the same repeat-forever rule. One `ocx start` inside one tool call therefore hijacks the top of every later reply in that session, and any new session that runs `ocx start` again re-arms it.
  3. Agent PTYs pass the TTY gate. Harnesses run commands in a pseudo-TTY, so `process.stdin.isTTY && process.stdout.isTTY` is true even though no human is watching — the agent path is hit on routine edit/test cycles, not just installs.

Net effect: a one-shot install-time growth prompt becomes an unbounded cross-session nag delivered through agents, and it fires during ordinary bug-fix/editing work that merely smoke-tests `ocx start`.

Evidence

  • `src/cli/star-prompt.ts` — `MARKER = ".star-prompted"`, `printAgentDeferral()` (relay instructions), marker intentionally unwritten on the agent path.
  • `src/cli/agent-driven.ts` — env-based detection (`CODEX_THREAD_ID`, `CODEX_SHELL`, `CLAUDECODE`, ...) matches essentially every agent harness, so the deferral path is the common case for agent runs.
  • Callers: `src/cli/index.ts:317` (`ocx start`), `src/service.ts:2468` (service install).
  • `src/update/notify.ts:135` already treats the marker as a "yield on first run" signal, so any new marker semantics must stay compatible.

Fix directions (keep the core invariant)

The invariant worth keeping: an agent must never answer or auto-dismiss the consent question; only the account owner stars. What should change is the nag bound:

  • Add a separate deferral record (e.g. `.star-deferred` with a timestamp/version) written when the agent path fires, so agent-driven starts re-emit at most once per cooldown window (or once per version) instead of every start.
  • Bound the relay obligation to a single relay per deferral event (ask once in the reply following that session's start), not "repeat at the top of every reply until answered."
  • Alternatively surface the ask once in the dashboard GUI (where the human actually is) and keep agent-driven terminal starts silent.
  • AGENTS.md's relay paragraph must be updated in lockstep with whatever bound is chosen, or the repeat-forever rule persists even after the CLI is fixed.

Regression coverage belongs near `tests/startup-prompt.test.ts` and `tests/agent-driven.test.ts`: second agent-driven start within the cooldown prints nothing; a hand-typed interactive run still shows the real prompt; the marker semantics for `update/notify.ts` are unchanged.

Severity

Medium — no data loss, but it degrades every agent-assisted session in this repository and trains users to dismiss a consent question, which is the opposite of what the consent gate is for.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions