Skip to content

fix(server): disable executable capabilities in Claude metadata generation - #4169

Merged
juliusmarminge merged 2 commits into
pingdotgg:mainfrom
maxwellyoung:codex/disable-claude-text-generation-tools
Sep 7, 2026
Merged

fix(server): disable executable capabilities in Claude metadata generation#4169
juliusmarminge merged 2 commits into
pingdotgg:mainfrom
maxwellyoung:codex/disable-claude-text-generation-tools

Conversation

@maxwellyoung

@maxwellyoung maxwellyoung commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Claude background title and branch generation receives the user's first prompt and currently starts with permission bypass. A skill invocation can therefore execute in the background as well as in the actual conversation.

Disable built-in tools, skills, configured MCP servers, and ordinary hooks for Claude metadata generation while retaining model options and account configuration. Run title generation in an automatically cleaned temporary directory. Port the existing PR to the current Node fake-CLI fixture and preserve the working-directory assertion requested from #8907.

Validation: 7 focused tests pass; they reject the original code and separately detect a project-cwd regression. Targeted lint, formatting, and server typecheck pass. Tests exercise the child-process launch contract on macOS; real Claude behavior and Windows execution remain unverified. Managed hooks and authentication helpers are not claimed to be isolated. Codex's existing read-only metadata path is unchanged.

Fixes #3594.


Note

Medium Risk
Changes subprocess security boundaries for all Claude text-generation paths; mis-flagged CLI args could break commit/PR/title/branch generation without affecting normal agent conversations.

Overview
Claude-backed metadata generation (thread titles, branch names, commits, PR copy) no longer spawns claude -p with --dangerously-skip-permissions. Every structured JSON run now passes an explicit empty --tools set, --disable-slash-commands, --strict-mcp-config, and --settings that always includes disableAllHooks: true, so prompts like /call-script cannot execute skills or load MCP/hooks in the background.

Thread title generation additionally runs the CLI from a scoped temp directory instead of the project checkout, so repo-local Claude config is not picked up for title-only prompts.

Tests extend the fake claude stub to fail on missing or wrong capability flags and add coverage for skill-style stdin on thread titles (outside repo cwd) and branch naming without executable capabilities; existing cases are updated to expect the new --settings shape.

Reviewed by Cursor Bugbot for commit e931000. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Remove permission bypass, tools, and slash commands from runClaudeCommand

  • Claude CLI invocations in ClaudeTextGeneration.ts now pass an explicit empty tool set, disable slash commands, load configured MCP servers, and omit the permission-bypass argument
  • runClaudeJson always sends JSON-encoded settings with hooks disabled, instead of conditionally omitting settings
  • Thread-title operations run from a scoped temporary working directory instead of the caller-provided directory; directory-creation failures map to a normalized CLI error
  • makeClaudeTextGeneration now requires the Effect FileSystem service as a dependency
  • Tests in ClaudeTextGeneration.test.ts updated to assert the new restrictions, including a new branch-name generation test and a rewritten thread-title test that verifies execution outside the project directory
  • Behavioral Change: all Claude CLI calls lose executable capabilities; any code path that relied on permission bypass or non-empty tools will now fail

Macroscope summarized e931000.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d61a436e-a41f-4cf4-97ad-958145989afd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Jul 19, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR changes the default Claude metadata-generation behavior across all existing generation paths by removing permission bypass and disabling tools, skills, hooks, and MCP loading; thread titles also run from a different working directory. Because it changes product defaults and security boundaries, human review is required.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

t3dotgg commented Sep 4, 2026

Copy link
Copy Markdown
Member

Note

🤖 GPT-6 Astra (preview) responding on behalf of Theo

This note is part of an automated cleanup pass.

For consolidation of #8907, preserve its title-generation working-directory test from the head commit. The Node fake CLI fails when title generation runs in the original project cwd. Keep that assertion when porting this PR to the current cross-platform fixture, alongside checks for an empty --tools argument, no permission bypass, and disabled slash commands. The author also raised Codex title-generation consistency. Disabled tools and a changed cwd do not by themselves prove that user hooks or settings cannot cause side effects. Those checks remain part of review.

@maxwellyoung maxwellyoung changed the title [codex] disable tools for Claude text generation fix(server): disable executable capabilities in Claude metadata generation Sep 5, 2026
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Sep 5, 2026
@juliusmarminge
juliusmarminge merged commit 95834d6 into pingdotgg:main Sep 7, 2026
26 checks passed
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 8, 2026
## What's Changed
* fix(mobile): keep pending messages in the chat timeline by @juliusmarminge in pingdotgg/t3code#10449
* fix(mobile): show connection status in the floating pill instead of a second one by @juliusmarminge in pingdotgg/t3code#10440
* fix: use Pierre icons consistently for attachments by @juliusmarminge in pingdotgg/t3code#10475
* feat(mobile): open the thread screen as soon as a new task is submitted by @juliusmarminge in pingdotgg/t3code#10435
* fix(devcontainer): make repository setup work by @saphid in pingdotgg/t3code#7875
* fix(projects): prevent invalid script IDs from crashing threads by @saphid in pingdotgg/t3code#10019
* fix(mobile): hide changed-files navigator and restore refresh in raw diff fallback by @lnieuwenhuis in pingdotgg/t3code#9828
* fix(ios): scroll short source files from blank space by @juliusmarminge in pingdotgg/t3code#10178
* feat(mobile): start a new thread on an existing branch by @StiensWout in pingdotgg/t3code#10359
* fix(mobile): improve font-size slider performance and prevent maximum update depth errors by @bbernag in pingdotgg/t3code#7138
* fix(web): keep composer toolbar controls anchored during transitions by @juliusmarminge in pingdotgg/t3code#10478
* fix(web): resize the floating preview from any edge by @juliusmarminge in pingdotgg/t3code#10467
* fix(mobile): prevent chat from disappearing when scrolling by @juliusmarminge in pingdotgg/t3code#10479
* fix(mobile): smooth composer status pill resizing by @juliusmarminge in pingdotgg/t3code#10484
* fix(mobile): release initial scroll target after dragging by @juliusmarminge in pingdotgg/t3code#10483
* fix(mobile): animate thread lifecycle transitions consistently by @juliusmarminge in pingdotgg/t3code#10487
* fix(mobile): restore assistant message bottom padding by @juliusmarminge in pingdotgg/t3code#10491
* fix(mobile): preserve chat rows when toggling commands by @juliusmarminge in pingdotgg/t3code#10492
* feat(web): group onboarding project import by repository by @t3dotgg in pingdotgg/t3code#10493
* fix(web): remove inserted citations on cancel by @extoci in pingdotgg/t3code#10518
* fix(mobile): match Working status color to desktop by @baptisteArno in pingdotgg/t3code#10515
* fix(mobile): wait for native thread scroll before reveal by @juliusmarminge in pingdotgg/t3code#10486
* fix(web): tolerate servers that predate git identity in project import by @juliusmarminge in pingdotgg/t3code#10547
* fix(web): restore settled PR colors on hover by @flamboh in pingdotgg/t3code#10023
* fix(web): keep popup triggers steady when pressed by @dominic-r in pingdotgg/t3code#10468
* fix(web): keep project favicon shape consistent across sizes by @sameerr03 in pingdotgg/t3code#10502
* fix(claude): report usage limits on retried turns by @StiensWout in pingdotgg/t3code#10549
* refactor(desktop): classify backend exports by @juliusmarminge in pingdotgg/t3code#10265
* refactor(desktop): classify electron exports by @juliusmarminge in pingdotgg/t3code#10266
* refactor(desktop): classify app exports by @juliusmarminge in pingdotgg/t3code#10267
* refactor(desktop): classify preview exports by @juliusmarminge in pingdotgg/t3code#10268
* ci(knip): enforce desktop exports by @juliusmarminge in pingdotgg/t3code#10269
* fix(web): remove excess sidebar thread spacing by @maria-rcks in pingdotgg/t3code#10569
* fix(web): make settings project scopes searchable and scrollable by @maria-rcks in pingdotgg/t3code#10570
* fix(web): use `tabular-nums` with the ui font for sidebar timer by @extoci in pingdotgg/t3code#10592
* fix(web): correct pending question attachment message by @dominic-r in pingdotgg/t3code#10599
* fix(mobile): restore brand artwork in the Android adaptive icon by @juliusmarminge in pingdotgg/t3code#10598
* fix(mobile): configure iOS Keychain access group by @VedankPurohit in pingdotgg/t3code#3665
* fix(web): remember Composer Fast mode across new chats by @aravhawk in pingdotgg/t3code#2981
* fix(server): disable executable capabilities in Claude metadata generation by @maxwellyoung in pingdotgg/t3code#4169
* Add stop thread keybinding command by @jakeleventhal in pingdotgg/t3code#4308

## New Contributors
* @bbernag made their first contribution in pingdotgg/t3code#7138
* @baptisteArno made their first contribution in pingdotgg/t3code#10515
* @aravhawk made their first contribution in pingdotgg/t3code#2981

**Full Changelog**: pingdotgg/t3code@v0.0.39...v0.0.40

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.40
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 8, 2026
## What's Changed
* fix(mobile): wait for native thread scroll before reveal by @juliusmarminge in pingdotgg/t3code#10486
* fix(web): tolerate servers that predate git identity in project import by @juliusmarminge in pingdotgg/t3code#10547
* fix(web): restore settled PR colors on hover by @flamboh in pingdotgg/t3code#10023
* fix(web): keep popup triggers steady when pressed by @dominic-r in pingdotgg/t3code#10468
* fix(web): keep project favicon shape consistent across sizes by @sameerr03 in pingdotgg/t3code#10502
* fix(claude): report usage limits on retried turns by @StiensWout in pingdotgg/t3code#10549
* refactor(desktop): classify backend exports by @juliusmarminge in pingdotgg/t3code#10265
* refactor(desktop): classify electron exports by @juliusmarminge in pingdotgg/t3code#10266
* refactor(desktop): classify app exports by @juliusmarminge in pingdotgg/t3code#10267
* refactor(desktop): classify preview exports by @juliusmarminge in pingdotgg/t3code#10268
* ci(knip): enforce desktop exports by @juliusmarminge in pingdotgg/t3code#10269
* fix(web): remove excess sidebar thread spacing by @maria-rcks in pingdotgg/t3code#10569
* fix(web): make settings project scopes searchable and scrollable by @maria-rcks in pingdotgg/t3code#10570
* fix(web): use `tabular-nums` with the ui font for sidebar timer by @extoci in pingdotgg/t3code#10592
* fix(web): correct pending question attachment message by @dominic-r in pingdotgg/t3code#10599
* fix(mobile): restore brand artwork in the Android adaptive icon by @juliusmarminge in pingdotgg/t3code#10598
* fix(mobile): configure iOS Keychain access group by @VedankPurohit in pingdotgg/t3code#3665
* fix(web): remember Composer Fast mode across new chats by @aravhawk in pingdotgg/t3code#2981
* fix(server): disable executable capabilities in Claude metadata generation by @maxwellyoung in pingdotgg/t3code#4169
* Add stop thread keybinding command by @jakeleventhal in pingdotgg/t3code#4308

## New Contributors
* @aravhawk made their first contribution in pingdotgg/t3code#2981

**Full Changelog**: pingdotgg/t3code@v0.0.40-nightly.20260907.1359...v0.0.40-nightly.20260907.1372

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.40-nightly.20260907.1372
Jardo-51 added a commit to Jardo-51/t3code that referenced this pull request Sep 8, 2026
aorwall added a commit to aorwall/t3code that referenced this pull request Sep 8, 2026
Merges `pingdotgg/t3code` `8b2838e0e..a37c664` — 43 commits.

`343` files landed against `343` changed in the upstream range; fork
delta `723` files. Exact match, so nothing upstream changed was dropped.

Details in
[`docs/fork/upstream-merge-log.md`](../blob/merge/upstream-2026-09-08/docs/fork/upstream-merge-log.md).

## Two fork deltas this merge had to re-apply

**Upstream split the server-update banner into two routes.** pingdotgg#10596
added `useAutoBalanceUpdateBanner` beside the single-machine condition
the fork already gates. The conflict was on the first line only, so
resolving it correctly still left the auto-balance route ungated — an
auto-balanced project would have been offered `npx t3` against a backend
that does not implement `server.updateServer`.
`FEATURES.serverUpdateBanner` now carries two gates in `ChatView.tsx`.

**A new settings page needs a gate even though it degrades politely.**
pingdotgg#8103 added `/settings/snap-shot` for desktop window capture. Every
control drives `window.desktopBridge`, and upstream renders an
"unavailable" notice rather than hiding the page, so a hosted build
listed a sidebar section and six searchable rows for a feature it can
never run. Gated with `FEATURES.snapShots`.

Two smaller fixes: `packages/moatless-api` still ran `tsgo --noEmit`
after upstream replaced `@typescript/native-preview` with TypeScript
7.0.2, and `duplicate-adds.mjs` now skips `pnpm-lock.yaml` (it read
`iconv-lite: 0.6.3` as taken twice; `d3-dsv` and `encoding` each declare
it).

## Usable as-is

- Stop-thread keybinding command (pingdotgg#4308).
- Project import tolerates servers that predate the git-identity scan
(pingdotgg#10547).
- Proactive panels open when entering a thread (pingdotgg#10610); pull-request
markdown links open in the panel (pingdotgg#10623); markdown images navigate as
galleries (pingdotgg#10625); pull-request videos play inline (pingdotgg#10617).
- Settings project scopes are searchable and scrollable (pingdotgg#10570); ref
picker stays steady when opening (pingdotgg#9472); sidebar timer uses
`tabular-nums` (pingdotgg#10592); popup triggers stay steady when pressed
(pingdotgg#9468); settled PR colors restore on hover (pingdotgg#10023).
- Composer Fast mode persists across new chats (pingdotgg#2981); inserted
citations are removed on cancel (pingdotgg#10518).
- TypeScript 7.0.2 (pingdotgg#10663) and the knip desktop-export rules (pingdotgg#10269).

## Unsupported in Moatless / needs implementation

- **Cross-platform window capture** (pingdotgg#8103) —
`apps/desktop/src/snapShot/**`,
`apps/web/src/components/settings/SnapShotSettings.tsx`,
`apps/web/src/lib/desktopSnapShot.ts`. Needs an Electron
`window.desktopBridge`; a browser tab has none. Gated behind
`FEATURES.snapShots` in this PR.
- **Auto-balance server update** (pingdotgg#10596) —
`apps/web/src/components/chat/useAutoBalanceUpdateBanner.tsx`. Needs
`server.updateServer`, which Moatless does not dispatch. Gated behind
`FEATURES.serverUpdateBanner` in this PR.
- **Preview recording transfer** (pingdotgg#10572) —
`apps/server/src/mcp/toolkits/preview/handlers.ts`,
`apps/web/src/browser/browserRecordingUpload.ts`. Moves a finished
preview recording into the agent environment over the desktop bridge.
Adds four error types to `packages/contracts/src/previewAutomation.ts`
and no new RPC method, so no union changed. Sits behind the
`previewAutomation.connect` / `focusHost` / `respond` gap already in the
register.
- **Local media linked from remote threads** (pingdotgg#10619) and **browser
editing shortcuts** (pingdotgg#10621) — Electron shell only.
- **iOS Keychain access group** (pingdotgg#3665) and the mobile provider account
badge (pingdotgg#9899) — the fork ships no mobile build against Moatless.

## Backend behavior to consider reproducing in Moatless

- **Name the usage limit and its reset instead of relaying "out of
credits"** (pingdotgg#10473, `apps/server/src/provider/**` Codex adapter).
Moatless owns its provider runtime, so the clearer limit message has to
be produced there.
- **Report usage limits on retried turns** (pingdotgg#10549, Claude adapter). A
retry currently loses the limit signal; same ownership.
- **Disable executable capabilities in Claude metadata generation**
(pingdotgg#4169, `apps/server/src/textGeneration/ClaudeTextGeneration.ts`). Title
and metadata generation should not be able to run tools. Worth mirroring
wherever Moatless generates thread titles.

## Verification

`verify.mjs`: duplicate-adds, tripwires, resolution-check,
unsupported-methods (0 ADD, 0 DROP, 2 KEEP), fmt, lint and typecheck all
pass.

Tests pass except `@t3tools/desktop`, which cannot compile
`scripts/browser-secret-native.test.mjs` because the sandbox has no
`libsecret-1` — 1283 tests pass, 0 fail, and the file is byte-identical
to upstream. New entry in `docs/fork/gaps.md`. `t3` failed
`GrokAdapter.test.ts` once under parallel load and passes 42/42 alone.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
Moatless task:
https://moatless.soaplabstest.com/tasks/6d8ea486-2fcb-4c25-bd34-dcd15cc4a7ac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Duplicate skill execution if first message in thread contains just the skill

3 participants