frame-problem · diff
git:20260923.7852cb4 to git:20261007.83cf275
107 added, 151 removed. Audit A to A.
---
name: frame-problem
description: "Sense-making before action. Classify problem using Cynefin triangulation (3 tests + decomposition) to route to the right skill chain. Use when: frame, what approach, how should I start, which skill, where to begin, unsure what to do. NOT for known tasks — just do them."
allowed-tools: AskUserQuestion
model: opus
- context: main
argument-hint: <task or problem to frame>
cynefin-domain: confused
cynefin-verb: decompose
---
# Frame
- Sense-make → triangulate → decompose if needed → route. Domain determines agent pattern, not just skill.
+ Sense-make → triangulate → decompose if needed → route. The domain decides the agent pattern, not just the skill.
**Framing:** **$ARGUMENTS**
- ## ⚠️ AskUserQuestion Guard
-
- **CRITICAL**: After EVERY `AskUserQuestion` call, check if answers are empty/blank. Known harness bug in some agentic coding tools: outside their planning mode, `AskUserQuestion`-style prompts can silently return empty answers without showing UI.
-
- **If answers are empty**: DO NOT proceed with assumptions. Instead:
- 1. Output: "⚠️ Questions didn't display (known harness bug outside planning mode)."
- 2. Present the options as a **numbered text list** and ask user to reply with their choice number.
- 3. WAIT for user reply before continuing.
-
- ## 0. Auto-classify (skip if no $ARGUMENTS)
+ ## Mindset
- Read `$ARGUMENTS`. Attempt domain classification using constraint language.
+ - Keep every classification as a hypothesis you test against the user's answers, never a verdict you announce.
+ - Check your own confidence with suspicion. You hold expert knowledge on nearly everything, so every problem looks analysable to you and drifts towards Complicated.
+ - Use what people can observe (history, repeatability, separability) and derive the domain yourself. Self-classification by constraint type is unreliable.
+ - Stop at the handoff. Framing never proposes a fix, a diagnosis or an implementation.
- **If confidence ≥80%**: Propose — but ALWAYS run the Adjacent Domain Challenge before confirming:
+ ## AskUserQuestion Guard
- ```
- 🎯 Auto-classified: [Domain] (constraint: [type])
- → Verb: [probe|analyze|execute|act|decompose]
- → Suggested route: [skill chain]
+ Some agentic harnesses silently return blank answers from `AskUserQuestion` outside their planning mode, with no UI shown. Check the answers after EVERY call.
- ⚖️ Adjacent challenge: What if this is actually [nearest domain]?
- [1-2 sentence argument for why it could be the adjacent domain]
- [Why the original classification still holds — or doesn't]
+ 1. Stop if any answer is empty or blank, and do not proceed on assumptions.
+ 2. Write the notice below, with the options as a numbered text list.
+ 3. Do not continue until the user replies with a number.
- Confirm? [Yes / Re-classify manually]
+ ```text
+ Questions didn't display (known harness bug outside planning mode).
+ Reply with the number of your choice:
+ 1) [option one] 2) [option two] 3) [option three]
```
- **LLM bias warning**: You are systematically biased toward Complicated (you have "expert knowledge" for everything, so you see governing constraints everywhere). When auto-classifying as Complicated, actively look for signs it might be Complex: Would two experts disagree? Is there genuine novelty? Has this specific combination been tried before?
-
- **If confidence <80%** or no $ARGUMENTS: Skip to Step 1 (triangulation).
-
- ## 1. Triangulate (3 tests)
-
- Do NOT ask user to self-classify by constraint type — people systematically misclassify. Instead, ask 3 concrete questions they CAN answer accurately.
-
- **Question Refinement**: If $ARGUMENTS is vague or broad, generate 2-3 clarifying sub-questions to sharpen the problem statement. Present them inline before proceeding.
-
- AskUserQuestion — all applicable questions in one call:
-
- **T1 — "Who's done this before?"** (Keogh Scale)
- - 1️⃣ Everyone on the team knows how → **Clear**
- - 2️⃣ Someone on our team / we have access to expertise → **Complicated**
- - 3️⃣ Someone outside our org has, but not us → **Complex**
- - 4️⃣ Nobody has ever done this → **Complex (near Chaotic)**
- - 5️⃣ Can't even tell what "this" is → **Confused**
-
- **T2 — "Same inputs, same result?"** (Predictability)
- - 🔁 Yes, reliably → **Ordered** (Clear or Complicated)
- - 🎲 Probably not — path-dependent, sensitive to context → **Unordered** (Complex)
- - 💥 No relationship between action and outcome → **Chaotic**
-
- **T3 — "Can you take it apart?"** (Disassembly)
- - 🔧 Yes — independent pieces, reassemble identically → **Complicated max**
- - 🧬 No — entangled, changing parts changes the whole → **Complex min**
- - ➗ Some parts yes, some parts no → **Composite** (→ Step 1.5 decompose)
-
- **Also ask:**
+ ## Procedure
- **Q-Scale** (skip if Chaotic):
- - 🪨 Boulder (multi-step, ambiguous, architectural)
- - 🫧 Pebble (single file, obvious implementation)
- - ❓ Not sure
+ ### Step 0. Auto-classify (skip when $ARGUMENTS is empty)
- **Q-Complicated sub** (only if T1=2 AND T2=ordered):
- - 📈 **Evolving** — system improving, growing capacity → `investigate`
- - 📉 **Degraded** — was working, now failing → `troubleshoot`
- - ↔️ **Both** — improving in one dimension, degrading in another → `investigate` with `troubleshoot` sub-task
+ 1. Read $ARGUMENTS for constraint language: "was working, now failing" signals Degraded, "we think X causes Y" signals a hypothesis, "we need a <thing>" signals a solution-shaped statement.
+ 2. Check your confidence. Below 80%, go to Step 1.
+ 3. Run the Adjacent Domain Challenge before you propose anything, at 80% or above. Use one or two sentences to argue for the nearest neighbouring domain, then say why the original holds or does not.
+ 4. Test for Complex whenever you land on Complicated: would two experts disagree, is the combination genuinely novel, has this exact combination been tried here?
+ 5. Use this shape for the proposal:
- ### Triangulation Logic
+ ```text
+ 🎯 Auto-classified: [Domain] (constraint: [type]) → Verb: [probe|analyze|execute|act|decompose]
+ → Proposed route: [skill chain]
+ ⚖️ Adjacent challenge: what if this is [nearest domain]? [argument, and why the original holds]
+ Confirm? [Yes / Re-classify manually]
+ ```
- **All 3 agree** → High confidence. Classify directly.
+ ### Step 1. Triangulate
- **2 of 3 agree** → Classify by majority. Note the dissenting signal — it may indicate a liminal (boundary) state. Present:
- ```
- 🎯 [Domain] (2/3 tests agree)
- ⚠️ Liminal signal: T[N] suggests [adjacent domain] — [what this means]
- ```
+ Use a single `AskUserQuestion` call for three concrete questions the user can answer accurately. Load `references/triangulation-tests.md` for the exact wording and options.
- **All 3 disagree or T3=composite** → Problem spans multiple domains. Go to Step 1.5.
+ - **T1** asks who has done this before (Keogh scale), and measures whether expertise exists.
+ - **T2** asks whether the same inputs give the same result, and measures predictability.
+ - **T3** asks whether the problem can be taken apart and reassembled, and measures entanglement.
+ - **Q-Scale** asks boulder or pebble. Avoid asking it when the answer to T2 is Chaotic.
+ - **Q-Complicated sub** applies only to T1=Complicated with T2=ordered: Evolving → `investigate`, Degraded → `troubleshoot`, Both → `investigate` with a `troubleshoot` sub-task.
- **Misclassification traps to watch for:**
- - Engineers/experts picking T1=2 + T2=ordered when T3=entangled → likely Complex, not Complicated (expertise bias)
- - Overwhelm picking T2=chaotic when it's actually Complex with enabling constraints → slow down, decompose
- - "Nobody has done this" + "predictable result" = contradiction → decompose, parts are in different domains
+ Write 2-3 clarifying sub-questions first when $ARGUMENTS is vague or broad, and put them in the same call.
- ## 1.5. Decompose (only if tests disagree or problem is composite)
+ Read the answers by majority. Classify with high confidence when all three agree. Use the majority when two of three agree, and report the dissenting test as a liminal signal. Start Step 1.5 when all three disagree or T3 answers composite. Do not let T1 win alone against T2 and T3.
- When triangulation doesn't converge, the problem is too coarse. Snowden's rule: "If you can't agree on it, break it down until you can."
+ ### Step 1.5. Decompose (tests disagree or the problem is composite)
- 1. Break $ARGUMENTS into 2-4 sub-problems
- 2. For each sub-problem, apply the triangulation tests mentally (don't re-ask user — use context)
- 3. Present a **domain map**:
+ Snowden's rule: if you cannot agree on it, break it down until you can.
- ```
- 🧩 Composite problem — sub-parts in different domains:
+ 1. Define 2-4 sub-problems from $ARGUMENTS.
+ 2. Apply the three tests to each sub-problem from context. Do not re-ask the user.
+ 3. Use this domain map shape:
+ ```text
+ 🧩 Composite problem, sub-parts in different domains:
├── [sub-problem 1]: [Domain] → [verb] → [skill]
├── [sub-problem 2]: [Domain] → [verb] → [skill]
- └── [sub-problem 3]: [Domain] → [verb] → [skill]
-
- Suggested sequence: [order based on dependencies + risk]
- Start with [highest-risk/Complex parts first — that's where value and risk concentrate]
+ └── Proposed sequence: [order]
```
- AskUserQuestion: "Does this decomposition match your understanding? Adjust / Confirm / Re-frame"
-
- ## 2. Classify + Route
-
- Map triangulation result → domain → verb → skill chain:
-
- | Domain | Constraint | Verb | Scale | Route | OpenSpec? |
- |--------|-----------|------|-------|-------|-----------|
- | Clear | Rigid | execute | Pebble | Just code it | No |
- | Clear | Rigid | execute | Boulder | `openspec-develop` directly | Yes |
- | Complicated | Governing/Evolving | analyze | Any | `investigate` → `openspec-plan` | Boulder: yes |
- | Complicated | Governing/Degraded | analyze | Any | `troubleshoot` → stabilize → re-frame | No |
- | Complicated | Governing/Both | analyze | Any | `investigate` + `troubleshoot` sub-task | Boulder: yes |
- | Complex | Enabling/no hypothesis | probe | Any | `brainstorm` → `probe` → `openspec-plan` | Yes |
- | Complex | Enabling/has hypothesis | probe | Any | `probe` → sense → `openspec-plan` | Yes |
- | Liminal Comp↔Complex | Mixed | probe+analyze | Any | `probe` first (resolve boundary) → re-frame | No |
- | Chaotic | Absent | act | — | `experiment` → stabilize → `frame-problem` | No |
- | Confused | Unknown | decompose | Any | Step 1.5 if not done, else ask user for more context | — |
- | Composite | Mixed | per sub-problem | Mixed | Parallel/sequential per domain map from 1.5 | Per part |
+ 4. Keep dependency order first: a sub-problem that blocks the others (a failing service) is stabilised before anything else. Start with the Complex parts among independent ones, because probes take longest to return signal.
+ 5. Call `AskUserQuestion` with "Adjust / Confirm / Re-frame" before routing.
- **For single-domain result**, present:
- `🎯 [Domain] → [Verb] → [skill chain] | OpenSpec: [yes/no] | Scale: [boulder/pebble]`
+ ### Step 2. Classify and route
- **For composite result**, present the domain map from Step 1.5 with full routing.
+ | Domain | Verb | Scale | Route | OpenSpec |
+ |---|---|---|---|---|
+ | Clear | execute | Pebble | Just code it | No |
+ | Clear | execute | Boulder | `openspec-develop` directly | Yes |
+ | Complicated, Evolving | analyze | Any | `investigate` → `openspec-plan` | Boulder only |
+ | Complicated, Degraded | analyze | Any | `troubleshoot` → stabilise → re-frame | No |
+ | Complicated, Both | analyze | Any | `investigate` + `troubleshoot` sub-task | Boulder only |
+ | Complex, no hypothesis | probe | Any | `brainstorm` → `probe` → `openspec-plan` | Yes |
+ | Complex, has hypothesis | probe | Any | `probe` → sense → `openspec-plan` | Yes |
+ | Liminal Complicated↔Complex | probe+analyze | Any | `probe` first to resolve the boundary → re-frame | No |
+ | Chaotic | act | none | `experiment` → stabilise → `frame-problem` | No |
+ | Confused | decompose | Any | Step 1.5 if not done, else ask for more context | none |
+ | Composite | per part | Mixed | Follow the domain map from Step 1.5 | Per part |
- ## 3. Handoff
+ Use `🎯 [Domain] → [Verb] → [skill chain] | OpenSpec: [yes/no] | Scale: [boulder/pebble]` for a single-domain result. Use the full domain map for a composite result.
- AskUserQuestion "Proceed?": Start chain / Re-frame / Skip framing.
+ ### Step 3. Handoff
- On confirm → invoke first skill with $ARGUMENTS (or first sub-problem for composite).
+ 1. Use the handoff template that matches the route (see References) and fill in the thinking trail, decisions and accumulated context.
+ 2. Call `AskUserQuestion` with "Start chain / Re-frame / Skip framing".
+ 3. Call the first skill with $ARGUMENTS on confirm, or with the first sub-problem for a composite result.
## When to Use
- - The problem statement is vague, contradictory, or solution-shaped ("we need a microservice").
- - The team disagrees on what the problem actually is or what success looks like.
- - A previous attempt at solving something failed despite correct execution — the framing may have been wrong.
- - You are unsure which skill or approach to apply next (unsure whether to investigate, probe, troubleshoot, or experiment).
- - The scope of a request is unclear: could be a pebble or a boulder, could be one domain or several.
+ - The problem statement is vague, contradictory or solution-shaped ("we need a microservice").
+ - The team disagrees on what the problem is or what success looks like.
+ - A previous attempt failed despite correct execution, so the framing was probably wrong.
+ - You cannot tell whether to investigate, probe, troubleshoot or experiment.
+ - The scope is unclear: pebble or boulder, one domain or several.
## When Not to Use
- - The task is fully specified and unambiguous — just execute it.
- - You already know the Cynefin domain and the next skill to invoke.
- - The problem is a simple bug with a clear reproduction path — go directly to `troubleshoot`.
- - The user has explicitly asked to skip framing and proceed to a named skill.
- - Time is critical and the domain is Chaotic — act first, frame later.
+ - The task is fully specified and unambiguous. Execute it.
+ - You already know the Cynefin domain and the next skill.
+ - The problem is a simple bug with a clear reproduction path. Use `troubleshoot` directly.
+ - The user has explicitly asked to skip framing and go to a named skill.
+ - Time is critical and the domain is Chaotic. Start with action and frame later.
## Anti-Patterns
- - **NEVER frame the problem as a solution** — "We need a microservice" is not a problem statement. **Why:** Solution-framed problems foreclose better options; reframe as "We need to reduce deployment coupling."
- - **NEVER skip domain classification** — Jumping straight to a solution approach without classifying the domain applies the wrong strategy. **Why:** Clear domain problems need best practices; Complex domain problems need probes; mixing these causes failure.
- - **NEVER accept the user's first framing at face value** — Initial problem statements are often symptoms. **Why:** The real constraint or goal is usually one "why?" deeper; accepting the surface framing wastes effort.
- - **NEVER classify as Complicated just because you have knowledge** — LLMs have expert-level knowledge on nearly everything and will over-index on Complicated. **Why:** This systematically bypasses the probe/experiment path that Complex problems require, leading to confident but wrong solutions.
- - **NEVER skip the Adjacent Domain Challenge when auto-classifying** — A single-domain verdict without challenging the nearest boundary is premature. **Why:** Liminal problems handled with the wrong verb (analyze vs. probe) consistently fail at the boundary.
+ - **NEVER frame the problem as a solution.** "We need a microservice" is not a problem statement. **Why:** a solution-framed problem forecloses better options; restate it as a need, such as "reduce deployment coupling".
+ - **NEVER skip domain classification.** **Why:** Clear problems need best practice and Complex problems need probes; applying one to the other fails in production.
+ - **NEVER accept the first framing at face value.** **Why:** the first statement is usually a symptom, and the real constraint sits one "why?" deeper.
+ - **NEVER classify as Complicated just because you have knowledge.** **Why:** fluent expertise bypasses the probe path that Complex problems need, which yields confident but wrong solutions.
+ - **NEVER skip the Adjacent Domain Challenge when auto-classifying.** **Why:** a verdict never tested at the nearest boundary sends liminal problems to the wrong verb (analyse instead of probe), the usual gotcha at that boundary.
+ - **NEVER ask the user to name the constraint type.** **Why:** people misclassify their own situation, so ask the three tests and derive the domain yourself.
+ - **NEVER propose a fix while framing.** **Why:** a solution offered before the domain is settled anchors the chain on one answer and skips the safe-to-fail experiments.
### NEVER let T1 (expertise) alone override a T2/T3 disagreement
**BAD:**
- ```
+
+ ```text
T1: "our team has done this before" -> Complicated
T2: "results vary heavily by customer segment" -> Complex
T3: "entangled, changing one part changes the whole" -> Complex
Verdict: Complicated (T1 wins because "we have expertise")
```
**GOOD:**
- ```
+
+ ```text
T1: Complicated, T2: Complex, T3: Complex -> 2 of 3 agree -> Complex
- Route: probe, with T1 noted as a liminal signal (some governing constraints may exist)
+ Route: probe, with T1 noted as a liminal signal (some governing constraints exist)
```
- **Why:** T1 measures whether expertise exists, not whether the outcome is predictable — expertise bias makes engineers over-select Complicated on T1 even when T2 and T3 both say the problem is genuinely Complex; majority vote across all three tests must decide, never T1 alone.
+ **Why:** T1 measures whether expertise exists, not whether the outcome is predictable. A majority across all three tests decides, never T1 alone.
## Usage Examples
- **Reframing a vague bug report:**
```bash
- # Input: "The dashboard is slow"
- # Skill probes: What is slow? Under what conditions? For which users?
- # Output: "Dashboard queries >10s for accounts with >1000 records (Complicated domain)"
- ```
+ # "The dashboard is slow" -> ask what is slow, for whom, under what load
+ # Reframed: "Queries exceed 10s for accounts with >1000 records" (Complicated, Degraded)
+ # Route: troubleshoot
- **Classifying a new feature request:**
- ```bash
- # Input: "Add AI recommendations to the product page"
- # Skill classifies: Complex domain (unknown user behavior, emergent)
- # Routes to: probe skill for safe-to-fail experiment design
- ```
+ # "Add AI recommendations to the product page" -> unknown user behaviour, emergent
+ # Route: Complex, no hypothesis -> brainstorm -> probe
- **Decomposing a composite problem:**
- ```bash
- # Input: "Migrate our monolith to microservices and fix the checkout bug"
- # Skill decomposes:
- # - Checkout bug: Complicated/Degraded → troubleshoot
- # - Monolith migration: Complex → brainstorm → probe → openspec-plan
- # Routes to: troubleshoot first (lower risk, unblocks Complex work)
+ # "Migrate the monolith and fix the checkout bug" -> composite, T3 = some parts yes, some no
+ # checkout bug: Complicated/Degraded -> troubleshoot FIRST, because it blocks the rest
+ # monolith migration: Complex -> brainstorm -> probe -> openspec-plan
```
+ See `references/worked-examples.md` for full dialogues.
+
## References
- - [Frame → Brainstorm](references/frame-problem-to-brainstorm-llm.md) — handoff template: Complex, no hypothesis → brainstorm
- - [Frame → Probe](references/frame-problem-to-probe-llm.md) — handoff template: Complex, has hypothesis → probe
- - [Frame → Probe (Liminal)](references/frame-problem-to-probe-liminal-llm.md) — handoff template: Liminal Complicated↔Complex → probe
- - [Frame → Investigate](references/frame-problem-to-investigate-llm.md) — handoff template: Complicated, evolving → investigate
- - [Frame → Troubleshoot](references/frame-problem-to-troubleshoot-llm.md) — handoff template: Complicated, degraded → troubleshoot
- - [Frame → Experiment](references/frame-problem-to-experiment-llm.md) — handoff template: Chaotic → experiment
+ - [Triangulation tests](references/triangulation-tests.md): exact question wording, answer mapping and misclassification traps
+ - [Worked examples](references/worked-examples.md): end-to-end framing dialogues, including a composite case
+ - [Frame → Brainstorm](references/frame-problem-to-brainstorm-llm.md): handoff template, Complex with no hypothesis → brainstorm
+ - [Frame → Probe](references/frame-problem-to-probe-llm.md): handoff template, Complex with a hypothesis → probe
+ - [Frame → Probe (Liminal)](references/frame-problem-to-probe-liminal-llm.md): handoff template, Liminal Complicated↔Complex → probe
+ - [Frame → Investigate](references/frame-problem-to-investigate-llm.md): handoff template, Complicated and evolving → investigate
+ - [Frame → Troubleshoot](references/frame-problem-to-troubleshoot-llm.md): handoff template, Complicated and degraded → troubleshoot
+ - [Frame → Experiment](references/frame-problem-to-experiment-llm.md): handoff template, Chaotic → experiment