Skip to content

secret_request: masked secret card, value only in the run env (#1531) - #1542

Merged
currentbits merged 3 commits into
mainfrom
coder/1531-secret-request-card-f393ab
Oct 9, 2026
Merged

currentbits merged 3 commits into
mainfrom
coder/1531-secret-request-card-f393ab

Conversation

@currentbits

Copy link
Copy Markdown
Owner

Part of #1531 (overlaps #289).

New coder-threads MCP tool, secret_request({threadId, projectId, name, prompt?}), where name must match ^[A-Z_][A-Z0-9_]*$. Like ask_user, it returns immediately. The thread then shows a masked Secret requested: NAME card with Provide and Decline.

Where the value goes

  • It is kept only in main-process memory (electron/threadSecrets.js), per thread. It never goes into coder-store.json, the transcript, the MCP tool result, logs, or a detail broadcast. Only pendingSecret {id, name, prompt} is stored.
  • It is set as $NAME in the env of the thread's next provider spawns: Claude, Codex app-server, Cursor, Kimi, Muse, OpenCode and generic. For Claude it is part of the warm-process reuse key, so a new secret restarts the warm CLI. That key is only compared in memory and is never logged.
  • On Provide, the transcript gets the event Secret NAME provided, and the next turn starts with "Secret NAME is now available as $NAME".
  • It lasts until the app quits or the thread is archived, settled or deleted (retireAgent).
  • For remote or sandboxed spawns, only the local wrapper's env gets it.

Known limit: if the agent prints $NAME (for example echo $NAME), the value lands in the tool output and the transcript. This PR does not scrub values out of tool output.

Verification

  • New tests: electron/test/secret-request.test.js checks the value is absent from the store file, the transcript and the tool result, and present in the spawned run env. There is also test/secretPrompt.test.tsx.
  • Full electron suite on this branch and on origin/main in the same environment: 12 failures here against 10 on main. The difference is PR and guardrail tests that pass when run alone (37/37). The rest are the existing grok and codex environment failures.
  • Renderer suite: 2884 pass, 0 fail. Typecheck has only the mermaidEngine.ts error that is already on main.

🤖 Generated with Claude Code

Willem and others added 3 commits October 9, 2026 13:24
…store (#1531)

Agents ask for a named secret; the user types it into a masked card. The
value lives in main-process memory (electron/threadSecrets.js) and rides the
env of the thread's next provider spawns. The store, transcript, MCP result
and the next turn only ever see the name. Cleared on archive/settle/delete
and on app restart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ard (#1531)

runAgent (generic provider) now forwards opts.env so the secret reaches it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T12:17:12.986439Z e38e297 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e38e297eca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread electron/ipc-shared.js
Comment on lines +24 to +25
// #1531: a secret request value lives until archive / settle / delete.
threadSecrets.clear(threadId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear secrets from the MCP retirement paths

This cleanup only runs through ipc-shared.retireAgent; the thread_archive and thread_settle handlers in electron/orchServer.js call their own file-local retireAgent, which never clears threadSecrets. Consequently, when an agent archives or settles a thread through the MCP tools, its previously provided secrets remain in memory and are injected again if the thread is reactivated, despite the UI promising that they are gone after archive. Route those handlers through the shared cleanup or explicitly clear the secret map there.

Useful? React with 👍 / 👎.

Comment on lines +487 to +493
pendingSecret: {
id: randomUUID(),
name,
prompt: truncate(String((input && input.prompt) || ""), 500),
askedAt: Date.now(),
},
awaitingInput: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Suppress plan approval while a secret is pending

When a thread in plan mode calls secret_request and has emitted assistant text, notifyRunTerminal subsequently calls maybePersistPlanApproval, which skips persisted questions but not this new pendingSecret. It therefore creates a pendingPlan beside the secret card; after the user provides the secret, answerSecret queues the $NAME notification, but maybeDrainQueued refuses to run it while pendingPlan exists. In this context, Provide does not start the promised next turn until the user also resolves an unrelated plan approval, so maybePersistPlanApproval should treat pendingSecret like pendingQuestion.

Useful? React with 👍 / 👎.

@currentbits
currentbits merged commit 19aa7c8 into main Oct 9, 2026
11 of 12 checks passed
currentbits added a commit that referenced this pull request Oct 9, 2026
…ope table (#1553)

#1545 added a coverage test that every IPC handler is classified exactly
once; #1542 (answerSecret) and #1551 (setFast) landed alongside it
unclassified, so main's electron suite fails. setFast is steer like
setReasoningEffort; answerSecret puts a value into the agent's run env,
so it stays full-only.

Co-authored-by: Willem <willem@willems-mbp.home>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
currentbits pushed a commit that referenced this pull request Oct 19, 2026
…ope table

#1545 added a coverage test that every IPC handler is classified exactly
once; #1542 (answerSecret) and #1551 (setFast) landed alongside it
unclassified, so main's electron suite fails. setFast is steer like
setReasoningEffort; answerSecret puts a value into the agent's run env,
so it stays full-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
currentbits pushed a commit that referenced this pull request Oct 19, 2026
#1545 added the scope table while #1551 (setFast) and #1542
(answerSecret) added channels in parallel, so main's scope-table test
fails. setFast is steer, like setReasoningEffort. answerSecret is full:
a device has no need to plant a secret in a run's env.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
currentbits pushed a commit that referenced this pull request Oct 19, 2026
…t/answerSecret web scopes

#1435: bill a warm Claude process's cost growth, not its running total.
#1436: worker-finished notice tells the orchestrator not to poll thread_status;
saved notices with the old footer still fold.
#1439: build devCoder on first use so importers don't stay alive ~4s.
webScopes: threads:setFast (steer) and threads:answerSecret (full) were
unclassified after #1545 landed alongside #1551 and #1542, failing main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant