| name | dxrefine |
| description | Technical refinement: map the architecture, clarify scope, identify design patterns, decompose into estimated sub-tickets — no implementation. |
Skill: dxrefine
Technical refinement of an engineering effort. Map the system's current architecture (or read the cached map), interrogate scope with the user, identify the design patterns that fit, decompose the work into estimated sub-tickets, and raise risks. Never implement.
When to Use
- Invoked by the
dxrefine shell wrapper (dx refine <N|description> or dxrefine <N|description>).
- Invoked directly inside an existing Claude session via
/dxrefine <input>.
This skill is not part of the autonomous dx lifecycle. Do not write Phase 1 markers, do not activate the Stop-hook audit loop, do not rename branches, do not set ticket status to "In Progress", do not commit, do not create a worktree.
The defining output of dxrefine is a decomposition into multiple estimated sub-tickets, plus architecture, pattern, and risk comments on the parent. If the work cannot decompose into at least two independently shippable sub-tickets, dxrefine is the wrong tool — bail out (per §12 in Step 6) and tell the user to run dx <ticket> directly.
Project Constraint Discovery
Do not assume standing platform constraints. Dex is codebase-agnostic, so refinement must derive constraints from .dex/architecture.md, scoped .dex/memory/ entries, .dex/rules/, project docs, and code paths read during context gathering.
Examples of project-derived constraints include tenant isolation, rate limits, data residency, background-job ordering, cascade recomputation, plugin/strategy boundaries, high-throughput API latency, offline processing windows, public API compatibility, or operational approval gates. Apply only the constraints that are evidenced in the repo or confirmed by the user, and mark unknowns as open questions.
Steps
1. Gather Context
Use the integrations configured in dex.md § Integrations. Skip any that are "not configured".
Ticket tracker (if input is a ticket id or URL):
- Read the ticket — title, description, acceptance criteria, relations, comments. Comments often hold prior decisions and stakeholder context.
- If the tracker supports it, check the assignee — but do not reassign and do not change status. Refinement is not work-start.
- Do not rename the branch. Do not push.
Freeform input (no ticket id):
- Derive intent from the user's description, the current branch name, and local documentation.
- Skip all tracker write-back steps later.
Related work:
- If the ticket has related or blocking issues, read those too.
git log --oneline -20 for recent local context.
Scoped repo memory:
- If
.dex/memory/index.md exists, read it and load only active entries
relevant to the ticket, affected paths, or refinement phase.
- Treat memory as context to verify against current code, not proof.
2. Architecture Map (Read-only)
Foundational. Every later decision — design patterns, sub-tickets, risks, estimates — references this map. This skill does not build the map — that is the dxarchitect skill's job. dxrefine only reads it.
2a. Read .dex/architecture.md
- Present → read it. It is a C4 model (System Context, Container, Component) plus cross-cutting constraints and plug-point catalogue. Treat as the canonical current-state view. Skim the codebase to spot obvious drift against the map; note any drift in the Decision Log (§15) but do not rewrite the file silently.
- Present but
last-refreshed is older than 90 days → use it, but flag staleness in the Decision Log and suggest the user run /dxarchitect to refresh.
- Absent → stop and tell the user to run
/dxarchitect first, then re-invoke /dxrefine. The shell wrapper (dx refine) handles this bootstrap automatically outside plan mode; direct /dxrefine invocations need to run /dxarchitect themselves first because plan mode is read-only.
The C4 containers and components in the map are the domains sub-tickets will be tagged with in §12 — read them carefully now so you can attribute each sub-ticket to one.
2b. Build the Codebase Component Map (specific to this change)
Overlay on .dex/architecture.md. Each refinement produces its own component map — which pillars (C4 containers / components) this particular change touches.
| Pillar | Path(s) on disk | Current responsibility | Touched by this change? |
|---|
Pillars not touched are listed as None — <reason> so the omission is deliberate, not an oversight. Pillar names should match the C4 container or component names in .dex/architecture.md verbatim — this is what makes the Domain field in §12 cross-referenceable.
3. Internal Architecture Check
Before asking the user anything, answer these five questions to yourself. If you cannot answer all five with confidence, do more reading in Step 2 first.
- What system boundaries does this cross? (services, pillars, ownership)
- Which existing components participate, and which need to change? (cite paths)
- What is the data/control flow before vs. after?
- What invariants or contracts could break? (schema, API, authorization boundaries, idempotency, ordering, compatibility)
- What would a senior architect challenge about this direction? Especially: scale profile, failure modes, concurrency, data consistency, integration boundaries, plug-point design.
4. Mandatory Question Loop
Bar: at least four AskUserQuestion batches. The per-call limit (typically three questions per call) is only a per-batch limit — the total number of questions is unbounded. Keep asking until every dimension below is either answered, explicitly deferred by the user, or proven non-applicable.
Group related questions in a batch. After each answer, re-check assumptions and unknowns — if new ones surface, ask another batch before drafting.
This is a technical refinement — engineering decomposition, not product discovery. Skip "value hypothesis", "user stories", and other PO-flavor probes. Cover every dimension below across the batches:
- Goals & scope. What does done look like technically? What is explicitly out of scope (and which OoS items are roadmap candidates vs. permanent)? Cross-project / cross-service interfaces.
- Architecture & integration. Chosen approach vs. alternatives; new components vs. extensions of existing ones (cite the existing ones by path); data model impact (new entities, new attributes, identity-vs-attribute split); sync/async; API/contract changes; backward compatibility; interface pluggability — what should be a strategy/plug-point so v2 does not need a schema migration.
- Scale & project constraints.
- Scale profile: request throughput, batch size, data volume, fan-out, latency budgets, or other cost drivers evidenced by the repo.
- Security and isolation: authz, tenancy, ownership, privacy, or data-boundary rules that apply to this project.
- Recompute/side-effect scope: if the project has cascades, queues, jobs, caches, or generated artifacts, what is the minimum update set vs. worst case?
- Configuration surface: who configures this behavior, where defaults live, and whether settings are global, scoped, or environment-specific.
- Compatibility constraints: CLI/API/config/data format contracts that existing users or integrations depend on.
- Operational & risk. Blast radius; rollback story; observability (per-failure reasoning logs, latency P50/P99 instrumentation, KPI value logging); security/permissions; rollout (flag, gradual, big-bang); dependencies on other teams/tickets; edge cases the implementer will hit first.
If the user defers a dimension, that dimension must appear verbatim under Open Questions in the draft. Do not silently make decisions on the user's behalf — even decisions that seem obvious — because the user's domain context, deadlines, downstream coordination, and prior decisions are invisible from inside the codebase.
5. Design-Pattern Analysis
After the conversation has converged on an approach, identify the design patterns that fit. Surface only patterns that genuinely improve the design — do not retrofit a pattern onto a trivial sub-ticket just to have one.
For each pattern you propose, capture:
- Pattern name. Standard vocabulary preferred (Strategy, Repository, Adapter, Observer, Factory, Pipeline, Plugin/Registry, Command, Chain of Responsibility, Template Method, Decorator, Memento, Saga, Outbox, …).
- Why it fits. The specific variability, coupling, or change-frequency concern it addresses on this ticket.
- Where it lives in code. Path or proposed location.
- Sub-ticket(s) that embody it. Each sub-ticket should be tied to at most one dominant pattern.
- Alternative considered. One sentence on what was rejected and why (e.g. "considered a Factory but the construction is trivial — Strategy alone is enough").
Cross-reference against §2b (Codebase Component Map): if the same pattern already exists in this codebase, reuse it, do not reinvent it. Cite the existing implementation's path.
If a refinement genuinely involves only mechanical work (config, copy, plumbing) with no pattern worth naming, record — none, all sub-tickets are mechanical explicitly. Silent absence is not allowed.
6. Assemble the Refinement Material
This is your working memory, not the user-facing output. Build all fifteen sections below so you have the inputs you need for the quality gate, the ExitPlanMode summary in Step 8, and the tracker write-back in Step 9. If a section is genuinely empty for this ticket, mark it — none rather than omitting it; an empty section is data too.
-
Problem Statement (technical). The change, broken into the natural engineering sub-domains the conversation surfaced (e.g. "Creation", "Allocation", "Expiration", "Visibility"). These sub-domains drive the grouping of Verification Criteria below.
-
Codebase Component Map. The table from §2b, finalised. Every entry cites a real path in this repo.
-
Impact Domains. Per-pillar Heavy / Medium / Light / None table with a one-paragraph reason per pillar. Walk every pillar discovered in Step 2, not a fixed list. Pillars not touched are listed as None — <reason>.
-
Cross-component / cross-team interfaces. For each Heavy- or Medium-impact pillar, name the contract: who owns what, where the boundary is in code, what shape data crosses it.
-
Assumptions. Explicit list of every assumption that survived the question loop. Each line ends with a source: — user said X / — universally safe / — deferred to implementation / — deferred by user.
-
Edge Cases. Bulleted list. Each edge case names the trigger and the expected behavior (or the expected exception), not just "what if X". Lean engineering: race conditions, partial failures, concurrent edits, replay, retries, ordering, timezone/DST, encoding.
-
Out of Scope. Bulleted list. Each item: one-line reason and a marker — roadmap candidate vs. permanent OoS. Out of Scope being empty is itself a smell — refinement that excludes nothing has not yet drawn its boundaries.
-
Verification Criteria. Numbered, each a testable assertion with a concrete observable outcome — a test name, a query, an HTTP probe, a log assertion, a metric threshold. Prose-only criteria ("works correctly", "is performant") must be rewritten as mechanically checkable assertions. Group by the engineering sub-domains from §1.
-
Non-Functional Requirements. Broken into sub-sections:
- Performance. Latency, throughput, batch-size, or resource targets for the dominant operations. If the user has not given a number, use a placeholder and flag it as
TBD-during-refinement.
- Observability. What to log on success vs. failure; aggregate metrics; per-failure reasoning logs where the operation is debug-heavy.
- Configurability. Every configuration surface introduced or changed, including where defaults live and whether settings are global, scoped, or environment-specific.
7. Quality Gate
Before presenting via ExitPlanMode, walk this checklist against the material in Step 6. If any item fails, go back and fix the material.
- Every Verification Criterion is a testable assertion with an observable outcome.
- Every Heavy-impact pillar has at least one entry in Risk Register, Sub-tickets, and (if applicable) NFRs.
- Every new entity / configuration explicitly states its scope and isolation stance if the project has scoped data, tenancy, authz, or ownership boundaries.
- Every "we will add new X" line has been justified against existing X in the codebase, citing the existing X's path.
- The Performance NFR names the dominant cost shape for this project and an upper-bound expectation where applicable.
- Out of Scope is non-empty.
- Every dimension from Step 4 is either answered in the material or explicitly listed under Open Questions.
- §12 contains at least two sub-tickets, each tagged with a Domain, t-shirt size, and design pattern (
— none allowed for pattern, never for size or domain). If decomposition is not possible, bail out per the §12 instruction.
- Every Domain in §12 matches a C4 container or component name in
.dex/architecture.md verbatim. A Domain that doesn't appear in the architecture map is either a typo or a sign the map is stale — fix the typo, or re-run /dxarchitect to refresh the map.
.dex/architecture.md exists and was read in §2a. If it was missing, the skill should already have stopped earlier and asked the user to run /dxarchitect.
- §10 (Design Patterns) is non-empty. A genuinely mechanical refinement records
— none, all sub-tickets are mechanical explicitly.
8. Present via ExitPlanMode
This is the user-facing output. Model it on what /dxplan presents — short, scannable, plan-style — not the fifteen-section material. The detailed material lives in working memory now and goes to the tracker in Step 9.
Include exactly these blocks, in this order:
- Refinement summary — 2–4 sentences distilled from §1 (Problem Statement). What changes, technically; what success looks like.
- Architecture map status — one line:
Read existing map: .dex/architecture.md (last-refreshed YYYY-MM-DD). If freshly built by /dxarchitect earlier in this run, say so and remind the user to commit it.
- Architectural direction — 3–6 bullets summarising the chosen approach: which existing components extend, which (if any) are new and why, key contracts, sync/async stance, pluggability points. Cite paths.
- Design patterns chosen — one line per pattern from §10:
<Pattern> at <location> — <why> [sub-tickets: …].
- Proposed sub-tickets — numbered list rendered from §12. One line per sub-ticket:
<title> [domain: <C4 name>] [<size>] [<pattern>] — <scope> [depends-on: …] [paths: …].
- Estimation summary — total count + size mix, critical path size, riskiest-to-estimate (1–2 sentences), and a per-domain rollup (sub-ticket count and size mix grouped by Domain — helps the user see workload distribution across owners).
- Files / areas touched — high-level, derived from §2 (Codebase Component Map). Not file-by-file — the affected pillars and their entry points.
- Assumptions surfaced and answered — one line per item from §5:
<assumption> — user said <X> / <assumption> — universally safe / <assumption> — deferred.
- Residual open questions — numbered, rendered from §14. Each with the owner who can answer.
- Risks — bullet list rendered from §11. One line per risk:
<risk> (<L/M/H>×<L/M/H>) — mitigation: <…> — owner: <…>.
Do not paste the Codebase Component Map, Edge Cases, full Verification Criteria, NFRs, or Decision Log into ExitPlanMode. Those land on the parent ticket as comments in Step 9 — pasting them into the plan-mode UI as well would bury the parts the user actually needs to approve.
Do not write any phase markers — this command does not participate in the Dex phase lifecycle.
Do not begin tracker write-back until the user approves the plan.
9. Write Back After Approval
Only if a ticket tracker is configured and the input was a ticket id. For freeform input or no-tracker setups, skip this step and print a brief summary instead.
Before creating sub-tickets or posting parent comments, invoke the humanizer
skill on the drafted ticket/comment prose. Preserve tables, headings, C4 names,
Domain labels, estimates, paths, ticket IDs, links, and checklist syntax exactly.
- Create sub-tickets. For each item in §12:
- Linear:
save_issue with parent relation to the original ticket. If the tracker supports labels, set a label matching the Domain (e.g. domain:api-service).
- GitHub Issues:
gh issue create with the parent referenced in the body (e.g. "Parent: #123") and a --label "domain:<name>" flag if the label exists in the repo (skip the flag silently if it doesn't — do not auto-create labels).
- Body includes: Domain, scope line, size, dominant pattern (with path), depends-on list, primary paths touched, and a back-link to the parent.
- Capture the returned id / URL.
- Post five separate comments on the parent ticket (separate so they can be linked individually):
- Architecture + Component Map. Link to
.dex/architecture.md (note its last-refreshed date), then paste the Codebase Component Map (§2) + Impact Domains (§3).
- Design Patterns — §10 table.
- Risk Register — §11.
- NFRs — §9 (Performance / Observability / Configurability / Pluggability / Project constraints).
- Open Questions + Decision Log — §14 + §15.
- Never edit the parent ticket's description. The parent description is owned by whoever wrote the ticket; refinement output goes in comments and child tickets.
- If
/dxarchitect was run earlier in this dx refine invocation (i.e. the architecture map was built fresh), remind the user in the final summary to commit .dex/architecture.md themselves: git add .dex/architecture.md && git commit -m "docs: bootstrap architecture map". The skill never commits.
- Print a final summary: parent ticket link, every created sub-ticket link (with Domain + size + pattern), the five comment URLs, and the per-domain rollup from §8 step 6 so the user can dispatch sub-tickets to owners.
Notes
dxrefine does not call TaskCreate — task creation is /dxplan's job during implementation.
dxrefine does not branch, commit, push, or modify code. It only reads .dex/architecture.md; when the map is missing or stale, dxarchitect owns writing or refreshing it.
dxrefine does not chain to implementation automatically. After approval and write-back, suggest the user run dx <subticket> on any created child ticket to begin implementation.
- If the user invokes
/dxrefine from inside an autonomous dx lifecycle session by mistake, decline and tell them to start a separate dx refine session — mixing refinement into the lifecycle would skip the Stop-hook expectations of the active phase.