briefing · git:20260923.6fb3d9a · 2026-09-23 · sha256 7eef726c270bde84

briefing git:20260923.6fb3d9aA

Immutable. This exact content never changes and is served at /api/v1/blob/7eef726c270bde84.

---
name: briefing
description: Author and migrate Claude Code or Codex subagents that use the `briefing` plugin — the spawn-time hook that pre-loads declared skills into the agent's context. Use this skill when adding `briefing.skills` to an agent's frontmatter or a `# briefing: skills = [...]` comment to an agent's TOML, when refactoring an existing agent away from "MANDATORY: load skill X first" prose, or when debugging why a declared skill is not being resolved.
---

# Authoring agents with `briefing`

`briefing` pre-loads skills into a subagent's context **before its
first turn**. The skill bodies are there the moment the subagent is
spawned — no round-trip to load each one, no chance of the model
"forgetting".

It works in two harnesses, and the difference matters only when you
write the declaration:

| | Claude Code | Codex |
|---|---|---|
| Agent file | `.claude/agents/<name>.md` | `.codex/agents/*.toml` |
| Declaration | `briefing:` frontmatter block | `# briefing:` comment |
| Missing skill | spawn is denied | agent starts, told to abort |

This skill tells you how to write agents that use it correctly, and
how to convert existing agents that were trying to do this with
prompt-stuffed pleas like *"MANDATORY: invoke the brainstorming skill
before doing anything else"*.

## The declaration — Codex

A Codex agent declares its skills in a comment line:

```toml
name = "my_agent"
description = "..."
# briefing: skills = ["getty-perl-core", "getty-perl-moose", "superpowers:brainstorming"]
developer_instructions = """
You are my_agent. Do the thing.
"""
```

**Never write a `[briefing]` table.** Codex deserializes agent files
strictly and ignores the whole agent over an unknown key — the table
form of briefing 0.3.0 now yields ``unknown field `briefing` `` and an
agent that simply does not exist. The comment is invisible to Codex.
One line, outside any multi-line string: a `# briefing:` line inside
`developer_instructions` is prose and is not read.

To migrate an old agent, delete the `[briefing]` table and put its
list into the comment verbatim. The hook still reads a leftover table
where an older Codex lets the agent spawn, and says so in a
`systemMessage`.

**Do not use Codex's own `[[skills.config]]` for this.** That table
means "this skill is visible to the agent", which is not the same as
"preloaded" — `briefing` deliberately leaves it alone so you can say
one without the other.

Note that Codex agent names take underscores, not hyphens. The role
name is the `name` field, not the file name; the hook finds the file
the way Codex does — any `*.toml` under `.codex/agents/` (in any
project directory up to the repo root, or `$CODEX_HOME/agents/`),
including subdirectories, or a role declared in `config.toml` as
`[agents.<name>] config_file = "..."`.

## The frontmatter — Claude Code

A briefing-aware agent declares its required skills under a single
`briefing:` block — not a top-level `skills:` key:

```yaml
---
name: my-agent
description: ...
allowed-tools: Read, Edit, Bash
briefing:
  skills:
    - getty-perl-core
    - getty-perl-moose
    - superpowers:brainstorming
---

You are my-agent. Do the thing.
```

**Always namespace under `briefing:`.** A bare top-level `skills:` is
reserved for Claude Code itself and the hook intentionally ignores it
to avoid future collisions. Flow form (`skills: [a, b, c]`) is also
accepted under the block.

Skill names can be:

- bare (`getty-perl-core`) — resolved against project skills, then user
  skills, then plugin caches.
- namespaced (`superpowers:brainstorming`) — resolved against the
  named plugin's cache directly. Both harnesses use this syntax.

The names are identical in both worlds; only the roots differ. Claude
Code searches `.claude/skills/` and `~/.claude/skills/`; Codex
searches `.codex/skills/` and `.agents/skills/` in every directory
from the working directory up to the repo root, then
`$CODEX_HOME/skills/`, `~/.agents/skills/`, the bundled
`$CODEX_HOME/skills/.system/`, and `/etc/codex/skills/`.
Each side looks exactly where its own harness looks, which is why a
bare name stays portable between them.

## Hard-fail policy

If any declared skill cannot be resolved at spawn time, nothing runs
on a partial briefing. There is no silent degradation. This is
intentional: an agent that needs a skill to do its job correctly
should not run without that skill.

Under Claude Code the `Agent` call is **denied** with a clear error.
Under Codex a hook cannot stop a spawn, so the agent starts and
receives — instead of any skills, including the ones that *did*
resolve — an instruction not to attempt the task and to report the
failure. If a Codex subagent comes back saying it was not briefed,
that is this policy working, not a bug.

So: declare skills the agent genuinely depends on. Do not pad the
list "just in case" — every name there becomes a precondition for
the spawn to succeed.

## Anti-pattern: don't enumerate the skills in the body

This is the biggest mistake when migrating existing agents.

The skill bodies are **already in the prompt** by the time the agent
reads its first token. You do not need to — and should not — also
write things like:

```markdown
You have access to the following skills:
- getty-perl-core (for Perl best practices)
- getty-perl-moose (for OO idioms)
- ...

MANDATORY: invoke the brainstorming skill before responding.
```

This is wasted tokens and actively confusing — the model sees the
skill content directly above this block, then sees prose telling it
to "load" something it already has. The framing "you have access to"
is also wrong: the skills aren't *available*, they are *present*.

### What to do instead

Trust the injection. The body of a briefing-aware agent should read
as if the skills are simply part of the agent's working knowledge,
because they are. Write the agent the way you would write a system
prompt for an LLM that already has all the relevant context in its
training data. Briefly orient the agent to its job — not to its
toolbelt.

A good body might be as short as:

```markdown
You are the perl-backend agent. Implement, refactor, and review
backend Perl code in this project. Follow the conventions and
idioms shown in the skills above without restating them.
```

That's it. No "you can use", no "remember to apply", no "MANDATORY".

## Migration recipe

When converting an existing agent that uses prompt-stuffing:

1. **Find every "MANDATORY/REQUIRED/please load" line in the body.**
   Make a list of the skill names those lines reference.
2. **Move those names into `briefing.skills`** under the agent's
   frontmatter. Drop any narrative around them.
3. **Delete every "you have access to / remember to invoke / load
   first" sentence from the body.** The agent doesn't need to be
   told what's in its own context.
4. **Delete any per-skill summaries from the body.** If a skill's
   own description was duplicated into the agent body, that
   duplication is now noise — the SKILL.md frontmatter and body are
   already injected.
5. **Re-read the body cold.** If a sentence only made sense as a
   reminder to load something, cut it. The remaining body should
   describe what the agent *does*, not what it *has*.
6. **Spawn the agent and check the resulting prompt** (e.g. via
   transcript) to confirm the skills are present and the body is
   clean.

## Debugging unresolved skills

If a spawn is denied with `briefing: agent 'X' references unknown
skill(s): Y`:

1. Check spelling. Skill names are case-sensitive directory names.
2. Check the resolution order (project → user → plugin cache).
   The skill must exist as `<base>/skills/<name>/SKILL.md` for some
   base in that order.
3. For namespaced names (`plugin:skill`), the plugin must be
   installed in the local plugin cache —
   `~/.claude/plugins/cache/<plugin>/skills/<skill>/SKILL.md` or a
   nested-owner equivalent.
4. There is no fallback. If you want the skill to be optional,
   it does not belong in `briefing.skills`. Either inline the
   relevant guidance into the agent body, or have the agent invoke
   the `Skill` tool itself for genuinely optional context.

### When nothing happens at all under Codex

An agent that spawns with no briefing *and no error* is usually not a
resolution problem. Codex gates plugin hooks behind a trust prompt,
and until it is granted the hook is skipped silently. Check that
first. Non-interactive runs (`codex exec`) cannot grant trust at all,
so they never brief anything unless started with
`--dangerously-bypass-hook-trust`.

Also confirm the agent file is where Codex looks — under
`.codex/agents/` or `$CODEX_HOME/agents/`, with a `name` that matches
the spawned agent type — and remember that the skill list every
agent sees carries only names and descriptions. An agent quoting a
skill's content is not proof the briefing worked; it may simply have
read the file. To test properly, compare against the same agent with
the `# briefing:` line removed.

If the agent is not offered at all, look for Codex's startup warning
`Ignoring malformed agent role definition` — a leftover `[briefing]`
table produces exactly that.

## What `briefing` does NOT do

- It does not brief the *main* session — only subagent spawns.
- It does not replace the `Skill` tool. Skills the subagent
  discovers it needs *during* its run still go through `Skill`
  normally.
- It does not recursively expand a skill's own `briefing.skills`
  list. Each agent declares what it needs; skills are leaves.
- It does not strip frontmatter from the agent file's body, only
  from injected SKILL.md bodies.