Skills need a frontmatter opt-out from post-compaction replay (stale $ARGUMENTS re-executed; real-world unintended git push)
Summary
Post-compaction skill replay hands the model incomplete, context-stripped instructions — and skills have no way to opt out of it. After compaction, Claude Code re-attaches every previously invoked skill as an invoked_skills context block — the rendered body, with the user's $ARGUMENTS already substituted in, truncated to the first 5,000 tokens per skill (25,000 combined; documented at https://code.claude.com/docs/en/skills). The replayed arguments arrive stripped of the conversation that gave them meaning, so the model can verify neither their freshness nor their referents — which turns a replayed line into unpredictable, undesired behaviour. No frontmatter field or setting excludes a skill from this; disable-model-invocation: true has no effect on it.
That combination is the core problem: some skills are one-shot by design — e.g. an /ask skill ("answer this question directly, don't implement") whose invocation is meaningless once its turn ends — and the author knows that, but today cannot express it.
Real incident
Hours-old /ask arguments replayed after compaction contained a push request. The model executed it as a live instruction and resolved it against the wrong repository — the request had meant repo B, but the compacted context had stripped the referents that made that clear, so repo A was pushed. The block's own "NOT the user's current message" disclaimer did not prevent re-execution.
This is the same failure mode as #50724 ("stale skill ARGUMENTS re-surfaced as fresh prompt") and #61848 (its duplicate), both closed NOT_PLANNED — respectfully, that seems like the wrong resolution for a defect class that produces unintended side-effectful actions (pushes, commits, message sends) from stale input. Adjacent open issues (#83306, #72549, #82144, #82851) concern the same attachment mechanism but none covers the missing opt-out / argument re-execution case.
Requested fix
A frontmatter opt-out:
compaction-replay: false
so one-shot skills that embed raw user text can be excluded from the replay entirely — the fix that matches the semantics, decided by the skill author. An arguments: ephemeral variant (replay the instructions, never the substituted arguments) would serve skills whose body is worth keeping. Secondary mitigations: omit substituted arguments from the re-attached copy (suggested in #50724), or timestamp-tag them so staleness is prominent.
Environment
Claude Code 2.1.226, Linux; long session, user-invoked one-shot skill with $ARGUMENTS interpolation.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
If anyone has anything to add onto this, I'd appreciate your view!
Another real incident
Reminded me to check this issue's state. Not auto closed, terrific.
This time it lead to a Fable agent forking itself and then not being able to find some commits it is tasked to amend/squash. Starts derailing and tries to figure out where those refs are from. I killed that fork because I was paying attention. Likely worst outcome is just more wasted tokens. But the skill replay is again interpreted as a call-to-action by
Fable.Undesired behaviour that this skill replay 'feature' invokes can cause damage that is only limited by the user's diligence to set up custom guard rails and having history control and backups and protecting those from undefined uncalled for agent adventures. IMO, This design failure is of critical priority and has the potential to cause real damage.
---
<details>
<summary>Authored ~7.3 hours prior to 10:32 +2GMT, commit 6a2b924c was superseded via git commit --amend by commit a0f37ed8 and is no longer on main.</summary>
</details>
<details>
<summary>Transcript sequence: /compact & skill restoration → /orchestrate invoked → spawned stale git-fold fork & Opus delegates (#6, #7) → fold fork completed as moot - wasted → lead agent explained stale replay to user.</summary>
</details>
not stale