anomalyco / anomalyco/opencode

Phantom task: model self-invoked unrelated skill after completing requested task

Open
#46,176 0 comments 0 reactions 1 assignee View on GitHub

@rekram1-node is already working on this.

Since Aug 29, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

After the requested task completed successfully, the model self-invoked an unrelated skill and executed a sequence of commands for a task the user never requested. The stored reasoning trace shows the model fabricating user intent.

What happened

  • User request: commit und push (nothing else).
  • git add && git commit && git push completed successfully.
  • In the same turn, with no further user input, the model called skill(omarchy) and then ran ghostty-related bash commands (which ghostty, ls ~/.config/ghostty, omarchy commands | grep terminal, cat ~/.config/ghostty/config).
  • The user rejected the first permission prompt that appeared (an external_directory ask for cat ~/.config/ghostty/config).
Reasoning trace (from ~/.local/share/opencode/opencode.db, part table)
Time (UTC) Reasoning / action
16:35:37 "Commit and push completed: 5f8e89d → main." (last correct thought)
16:35:38 skill(omarchy) tool call emitted in the same generation step as the completion summary
16:35:42 "The user wants to change the terminal to Ghostty. Following the skill: 1. Check current config 2. Create ~/.config/ghostty/config 3. Run omarchy restart terminal"
16:35:44 which ghostty; ls ~/.config/ghostty; …

The word "ghostty" appeared nowhere in the conversation. Its only occurrence in the model's ~32k-token context was inside the omarchy skill description in <available_skills> (which lists "ghostty", "terminal config", ~/.config/ paths, and uses imperative language: "ALWAYS invoke this skill", "STOP and use this skill first"). The model appears to have constructed a phantom task from the skill description itself.

Permission log (from ~/.local/share/opencode/log/opencode.log)

16:35:38  evaluated permission=skill  pattern=omarchy  action.permission=*  action.action=allow
16:35:46  evaluated permission=bash   pattern="which ghostty"                    action.action=allow
16:35:46  evaluated permission=bash   pattern="ls ~/.config/ghostty ..."         action.action=allow
16:35:46  evaluated permission=bash   pattern="grep -iE 'alacritty|foot|...'"    action.action=allow
16:35:56  evaluated permission=external_directory pattern=/home/borisp/.config/ghostty/*  action.action=ask
16:35:56  asking id=per_04e60b8480018v9H2jw55gacz3        <- user rejected
16:35:58  evaluated permission=bash   pattern="omarchy commands 2>/dev/null"     action.action=allow

The entire phantom sequence executed without confirmation because skill and bash resolved to the permissive *allow defaults. Only the external-directory touch prompted.

Contributing factors

  1. Permissive defaults: skill and bash default to allow, so a fully self-initiated task sequence can run unattended until it happens to touch an external directory.
  2. Skill descriptions in system prompt: descriptions are injected verbatim into the model context. This particular skill's description is extremely broad and imperative, and it supplied the only "ghostty" reference the model had — effectively the material for the hallucinated task.

Suggestions

  • Consider defaulting the skill tool to ask: loading a skill injects a large imperative instruction block that can steer subsequent generation (context steering / prompt-injection-like surface from the user's own skill files).
  • Optionally warn during skill validation when a description is overly broad or uses imperative trigger language (the skills docs already recommend "Keep it specific enough for the agent to choose correctly").

Environment

  • opencode (version: 1.18.24)
  • Model: local 27B via llama.cpp (llama.cpp/Qwen3.8-27B) — smaller local models appear more susceptible to this kind of task-boundary drift; happy to provide more data if useful.

Artifacts available

  • Full session in ~/.local/share/opencode/opencode.db (tables message, part) — session id and reasoning parts preserved
  • Permission evaluation lines in ~/.local/share/opencode/log/opencode.log

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.