Surfaces refactoring opportunities through a deepening lens — modules that hide complexity behind narrow interfaces. Not for renames, extractions, or generic restructuring (use implement). Use when looking for structural improvements, or when the user asks "is this module too shallow?" or "where should we deepen this code?" Produces either a read-only report or a PLAN file with candidates, dependency categories, and proposed deepened modules.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Surfaces refactoring opportunities through a deepening lens — modules that hide complexity behind narrow interfaces. Not for renames, extractions, or generic restructuring (use implement). Use when looking for structural improvements, or when the user asks "is this module too shallow?" or "where should we deepen this code?" Produces either a read-only report or a PLAN file with candidates, dependency categories, and proposed deepened modules.
Refactor-Deepen
Identify shallow modules and propose deepenings that hide complexity behind
narrow, stable interfaces. Vocabulary discipline is load-bearing: drift to
"boundary," "service," "component," or "layer" defeats the entire point.
Contents
Critical Rules
Verification
Quick Reference
Process
Topics
Related Skills
Input: $ARGUMENTS (module path, area, or "scan the repo")
Critical Rules
First Action: Self-Log
Before anything else, log invocation to the project journal:
loaf journal log"skill(refactor-deepen): <module or area>"
Vocabulary Discipline
The source taxonomy is eight terms. Use them verbatim. Do not substitute
"boundary," "service," "component," or "layer" — those words are imprecise
and erode the lens.
Term
One-line cue
Module
A unit of code with a name, a public surface, and hidden internals
Interface
The narrow public surface a module exposes
Implementation
What lives behind the interface
Depth
Ratio of hidden complexity to interface surface (more hidden = deeper)
Seam
A point where the call graph can be cleanly cut and substituted
Adapter
The translation layer between an internal interface and an external concern
Leverage
How much downstream code is simplified per unit of interface
Locality
Whether related concerns live near each other or are scattered
Full semantics live in references/language.md. Read
that file on every invocation before naming anything.
Glossary Integration
The skill pressure-tests glossary terms — it consumes existing entries and
adds new ones when a deepening clearly names a structural module.
Before naming a candidate module, check the glossary:
loaf kb glossary check <term>
Canonical hit → use the existing term verbatim.
Avoided-alias hit → use the canonical replacement, surface the swap to the user.
Unknown → proceed; if the term proves load-bearing, add it (next rule).
When a deepening clearly names a structural module, add it canonically:
Use upsert (high commitment), not propose. A named deepening is not exploratory.
Linear-native mode fails fast on upsert. If the user is in
Linear-native mode, surface the error verbatim and continue without the
glossary write — do not synthesize partial state.
Grilling Protocol
The interview imports the shared
templates/grilling.md template — relentless
interview, walk the decision tree, recommend per question, prefer exploration
when the codebase can answer. Do not re-derive the protocol; follow it.
Interface Design: 3 Unprimed Sub-Agents
When the grilling loop reaches interface design for a candidate, spawn
exactly 3 sub-agents with identical briefs. Do not prime them with
opposing constraints (no "Agent 1 minimal, Agent 2 flexible"). Variety must
emerge from sampling, not manufactured opposition. If the three designs
converge accidentally, the fallback is a 4th agent or a rerun with different
seeds — not introducing priming. See
references/interface-design.md.
Report-Only Mode
Use report-only mode when the user asks for a broad scan, full report,
repository-wide review, or anything intended to feed a later brief/task
workflow rather than immediately persist a PLAN. Report-only mode is also the
fallback when Linear-native mode blocks local PLAN/glossary writes.
Report-only mode still performs the investigation: read context, survey
candidates, check candidate names through loaf kb glossary check, classify
dependencies, and present findings. It must not write .agents/plans/*, must
not invoke loaf kb glossary upsert, and must not offer Codex review because
there is no PLAN artifact to review.
Report-only output should be structured so it can become a brief later:
Scope and evidence read
Candidate modules, ordered by expected leverage
For each candidate: current interface, hidden implementation complexity,
dependency category, locality problem, proposed deepened module, tests that
should survive, and rejected alternatives
Suggested follow-up: "Use this report to draft a brief, then decide whether
to break that brief down into tasks."
Whole-Repo Inventory
For broad scans, inventory source and project-owned docs first. Exclude
generated, vendored, cached, virtualenv, and build output trees unless the user
explicitly asks to inspect them.
generated lock/vendor output and other tool caches
Use rg --files with -g excludes or targeted find commands rather than a
blind recursive listing. If an excluded tree appears relevant, name it as an
assumption and ask before pulling it into context.
Linear-Native Mode: Disable Local Writes
Before writing a PLAN file or mutating the glossary, check the project's
Linear-native flag:
If exit code is 1 (Linear-native enabled), continue in report-only mode and
surface the exact storage constraint once:
Linear-native plan storage unavailable — continuing with a read-only report.
Do not write the PLAN file, do not invoke loaf kb glossary upsert,
and do not call Codex review. Partial state across local PLAN + remote
glossary is an explicit failure mode: do not leave partial local PLAN state
when the remote glossary write is unavailable.
The report is allowed because it is read-only and can feed a later brief.
Termination
If report-only mode is active, terminate with the report in chat and this
closing message:
Report complete. Use this report to draft a brief, then decide whether to
break that brief down into tasks.
If report-only mode is not active and Linear-native is not enabled, the
skill terminates by writing a PLAN file using templates/plan.md at
.agents/plans/<YYYYMMDD-HHMMSS>-<slug>.md, with this exact closing message
(substitute the actual filename you wrote):
Plan saved to .agents/plans/<filename>.md. Workflow handoff is pending
the SPEC/PLAN/TASKS artifact taxonomy spec — for now, decide manually.
Do not recommend implement as the next step. The
handoff design is downstream of a deferred taxonomy spec.
Codex Review (Opt-In, Plugin-Gated)
After the PLAN file is written, check whether the codex plugin is
available in the current harness — i.e. whether the codex:codex-rescue
agent (or the codex:rescue skill) is exposed in this session's available
skills/agents list. Loaf's install-time tool detection discovers external CLIs
like the Codex binary; it does not report Claude-Code-plugin presence
inside the running session. The skill-level ambient-availability check is the
right contract here — what we care about is "can I route a review right now,"
not "is the Codex CLI installed somewhere on this machine." If a future Loaf
surface adds plugin-level detection, this rule can switch to it.
Always make this offer plugin-gated and opt-in. Ask once, verbatim:
Want a Codex review of this deepening before commit?
Wait for an affirmative reply before invoking anything.
Always route an accepted review through the codex:codex-rescue
agent (or the codex:rescue skill if that's what the harness exposes),
passing the PLAN file path and a pointer to
references/deepening.md for vocabulary context.
Never mention Codex if the plugin is absent — proceed straight to the
termination message below.
Never invoke Codex review by default, on a non-affirmative reply, or
on a "skip" — fall through to termination.
Verification
The project journal contains a skill(refactor-deepen): entry as the first action
docs/knowledge/glossary.md, docs/decisions/ADR-*.md, and
docs/ARCHITECTURE.md were read before the candidate list was presented
Every candidate module name was checked via loaf kb glossary check before
being proposed
Output uses the eight source terms verbatim — zero occurrences of
"boundary," "service," "component," or "layer" in their place
Interface Design spawned exactly 3 sub-agents with identical briefs
Whole-repo scans excluded generated/vendor/cache/build trees unless the user
explicitly asked to inspect them
Report-only mode produced a complete read-only report and wrote nothing to
.agents/plans/*
A .agents/plans/<YYYYMMDD-HHMMSS>-*.md file was written with the minimal
shape filled out (skipped iff report-only mode was active)
If Linear-native mode is enabled, the skill continued in report-only mode and
wrote nothing to disk
Codex review offer fires only when the codex plugin is detected, is
worded verbatim, and runs only on an affirmative reply — never by default
Closing message matches the termination template verbatim
PLAN files use the same temporal-record naming as sessions, ideas, drafts,
and councils — write-once snapshots, not sequentially-numbered contracts.
Re-deepening the same module later writes a new file rather than updating
the existing one. The filename is the identity; PLAN frontmatter does not
carry an id field.
Create .agents/plans/ lazily — mkdir -p immediately before the first
plan write, never upfront. The sequential-ID allocation race is gone;
same-second filename collisions remain theoretically possible at scripted
speed but are unlikely at human pace.
propose and stabilize are not used by this skill — they belong to
architecture and exploratory flows.
When to Deepen vs. Leave Alone
Signal
Deepen?
Interface surface ≈ implementation surface
Yes — module is shallow
Callers reach across the interface to internals
Yes — interface is leaky
One module concern is scattered across many files
Yes — locality is poor
Interface is narrow and implementation is large
No — already deep
Module is a thin pass-through to a true-external dependency
No — adapter, by design
Process
Read context. Open docs/knowledge/glossary.md (via loaf kb glossary list), docs/decisions/ADR-*.md, and docs/ARCHITECTURE.md. Read
references/language.md and
references/deepening.md.
Survey candidates. Walk the target module/area. Produce a numbered list
of shallow-module candidates with one-line rationales using the eight terms.
Pick a candidate (with the user) and enter the grilling loop following
templates/grilling.md. Surface canonical terms
inline; challenge drift on contact.
Classify dependencies. For each candidate, classify dependencies by
category (in-process, local-substitutable, ports-and-adapters, true-external)
per references/deepening.md.
Design the interface by spawning 3 unprimed sub-agents per the rules in
references/interface-design.md. Present
all three designs to the user; do not pre-rank.
Check report-only and Linear-native mode. For broad reports, or when the
inline Linear-native check exits 1, continue in report-only mode and skip
steps 7-9.
Write the PLAN to .agents/plans/<YYYYMMDD-HHMMSS>-<slug>.md using
templates/plan.md. The filename timestamp must match
the frontmatter created field. Required sections: candidate, dependency
category, proposed deepened module, what survives in tests, rejected
alternatives.
Mutate the glossary (loaf kb glossary upsert) for any structural
module the PLAN names canonically.
Offer Codex review only if the codex plugin is detected (i.e.
codex:codex-rescue agent or codex:rescue skill is available). Ask
verbatim and wait for an affirmative reply; on accept, route through
codex:codex-rescue with the PLAN file path. On decline, skip, or
plugin absence, fall through silently.