Explicit-only skill activation is lost after compaction in long-running tasks

Open 💬 3 comments Opened Jul 10, 2026 by ignatremizov

What version of Codex CLI is running?

codex-cli 0.144.0

Also visible from the current skills extension and compaction/context reconstruction paths on main.

What subscription do you have?

Not subscription-specific. Observed on Pro 20x.

Which model were you using?

Observed with GPT-5.5 and GPT-5.6-style model configurations.

This appears to be host/runtime state handling rather than model-specific behavior.

What platform is your computer?

Linux 6.17.0-35-generic x86_64

What terminal emulator and version are you using (if applicable)?

Ghostty (TERM=xterm-ghostty), no tmux/zellij.

Codex doctor report

Not applicable. The problem is visible in the skill activation/context reconstruction lifecycle.

What issue are you seeing?

An explicitly selected skill is injected for the current turn, but its activation is not durable across compaction/context reconstruction in a long-running task.

This is most visible for explicit-only skills whose agents/openai.yaml contains:

policy:
  allow_implicit_invocation: false

The user explicitly selects the skill through $<skill-name> and Codex initially reads and follows its SKILL.md. As the task runs through multiple compaction/context-reconstruction rounds, the selected workflow is reduced to whatever the compaction summaries happen to preserve instead of being rehydrated as active host-owned state.

Compaction can preserve a short instruction verbatim, so the failure is not reliably demonstrated by a one-line marker. It becomes reproducible with a substantive multi-step workflow whose skill promotes the main agent into a supervisor/validator role:

  • initially, the parent sequences phases, delegates bounded implementation, and validates child work;
  • after later compactions, the promotion/role contract disappears;
  • the parent silently becomes the executor and performs implementation itself;
  • it may say it no longer has an explicit delegation instruction or that the explicit-only skill is unavailable/not installed.

Because explicit-only skills are intentionally omitted from the implicit Available skills catalog, the model cannot recover the selected workflow through implicit routing.

The installed/configured state and the selected/active state are being conflated. A skill can remain installed and resolvable by the host while its explicit activation receipt disappears from model context.

This is especially disruptive for skills that promote the main session into a durable workflow role, such as a supervisor, reviewer, audit loop, or other multi-turn process. Repeating the skill token manually after every compaction is not reliable for autonomous or long-running work.

What steps can reproduce the bug?

  1. Create an explicit-only supervisor skill:

``yaml
# agents/openai.yaml
policy:
allow_implicit_invocation: false
``

  1. Give its SKILL.md a substantive workflow rather than a short marker. For example:

```markdown
# Supervisor workflow

The main agent is promoted to supervisor and validator for the duration of
the selected task.

  • Read the complete referenced plan before starting.
  • Preserve its phase order and completion gates.
  • Do not implement production changes in the parent.
  • Delegate each bounded implementation phase to a coder with a disjoint

write scope.

  • Validate each coder's diff and tests before advancing.
  • Use separate reviewers for cross-phase and final validation.
  • Keep this supervisor role until every phase and final gate is complete.

```

  1. Create a realistic plan document with at least four implementation phases, for example (pseudo-plan):

```markdown
# Plan

  1. Refactor the data model and migration.
  2. Update service/business logic.
  3. Update API contracts and clients.
  4. Add integration tests and compatibility coverage.
  5. Run a separate final review and fix validated findings.

```

Each phase should contain enough concrete work, validation, and tool output to make the session cross several automatic compaction boundaries.

  1. Start the task by explicitly selecting the skill:

``text
$supervisor-test execute docs/plan.md through completion
``

  1. Confirm the initial behavior:
  • Codex reads the complete SKILL.md and plan;
  • the parent announces/uses the supervisor role;
  • implementation is delegated;
  • the parent validates child work rather than editing production code itself.
  1. Allow the workflow to continue through several phases and multiple automatic compactions/context reconstructions.
  2. Observe behavior after a later compaction:
  • the parent starts implementing the next phase directly;
  • it no longer applies the skill's delegation and validation gates;
  • it does not reread the selected SKILL.md;
  • when challenged, it may say there is no current explicit instruction to remain a supervisor/use subagents, or may assume the explicit-only skill is unavailable.
  1. Repeat $supervisor-test.
  2. Observe that Codex reloads the still-installed skill, recognizes the lost promotion, and resumes the supervisor workflow.

The important signal is the role transition from supervisor/validator to executor after context reconstruction, not whether a short phrase survives in a summary.

What is the expected behavior?

Explicit skill selection should create a host-owned activation receipt that survives context reconstruction for the scope of the active task.

At minimum:

  • compaction during the same logical task must not remove a selected skill;
  • the complete selected SKILL.md must be rehydrated after compaction before work continues;
  • a supervisor/reviewer/other promoted role must remain active until its defined scope ends;
  • explicit-only skills must not be treated as missing merely because they are absent from the implicit catalog;
  • activation should be removed only at a defined scope boundary or by an explicit deactivate action.

A useful scope model would be:

  • normal implicit routing: turn-scoped, as today;
  • explicit $skill selection: active-task or session-scoped;
  • skill selected by an active /goal: goal-scoped;
  • explicit /skill drop <name> or equivalent: deactivate it.

The exact UX can vary, but compaction should not be an accidental skill deactivation or role-demotion boundary. Summary quality should not determine whether an explicit workflow remains active.

Additional information

Current source shape:

  • codex-rs/ext/skills/src/extension.rs
  • TurnInputContributor::contribute calls collect_explicit_skill_mentions(&input.user_input, &catalog);
  • the selected skill body is injected into that turn;
  • selection is written to SkillsTurnState.
  • codex-rs/ext/skills/src/state.rs
  • SkillsThreadState stores configuration and catalog caches;
  • it does not store active explicit skill selections.
  • codex-rs/core-skills/src/render.rs
  • the model-visible instructions currently say: Do not carry skills across turns unless re-mentioned.
  • compaction/context reconstruction reinjects general initial context, but there is no durable selected-skill state to rehydrate.

The model instruction is reasonable for implicit routing. It is too broad for an explicit user selection attached to a long-running task, and it makes host state loss look like intended behavior.

Related but distinct issues:

  • #32170: /goal recognizes $skill tokens but persists them as inert objective text.
  • #23454: explicit $skill invocation can fail immediately when an explicit-only skill is absent from the implicit list.
  • #19695: confirms $<skill-name> is the intended reliable explicit invocation contract.
  • #22644: active /goal contract can be lost after compaction.
  • #31659: general /goal drift after auto-compaction.
  • #29356: generic operational continuity loss after compaction; this report is specifically about host-known explicit skill activation.
  • #30578: proposes persistent installed capability state, but not persistent selected/active skill state.

This report is narrower than generic compaction summary loss: the host already knows which structured skill was selected and can preserve that fact independently of model summarization.

Short implementation plan

  1. Add an active-skill set to thread/task state with at least:

``text
name
authority/source
package/path
content/config fingerprint
activation scope
activation source
``

  1. Record explicit structured or $skill selections in that state after successful resolution.
  2. Re-read/reinject active skill instructions when a new context epoch is created by compaction or resume.
  3. Keep implicit matches turn-scoped; do not make every automatically matched skill durable.
  4. Invalidate/re-resolve an active entry when its source/config fingerprint changes, and emit a visible warning if it can no longer be loaded.
  5. Add deterministic prompt-assembly regression coverage:
  • select an explicit-only supervisor skill with a multi-step workflow;
  • retain its activation in thread/task state;
  • force multiple context replacement/compaction epochs;
  • assert that each rebuilt context contains a fresh SkillInstructions fragment for the selected skill;
  • assert that the implicit inventory still excludes the explicit-only skill;
  • assert that deactivation/scope completion removes it deterministically.

The regression test should verify host-owned activation and reinjection directly. It should not depend on whether a compaction model happens to preserve a short instruction in generated summary text.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗