Skip to main content
ClaudeWave
Skill1.3k estrellas del repoactualizado today

h-frame

h-frame is a problem-framing skill from the HAFT methodology that structures unclear challenges before solution work begins. Use it when facing ambiguous requirements, conflicting priorities, or vague goals by separating observed signals from assumptions, eliminating umbrella terms like "scalable" or "quality," classifying the problem type (optimization, diagnosis, search, or synthesis), and explicitly declaring scope boundaries. This prevents wasted effort on misaligned solutions and ensures reasoning targets the actual problem.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/m0n0x41d/haft /tmp/h-frame && cp -r /tmp/h-frame/internal/cli/skill/h-frame ~/.claude/skills/h-frame
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# h-frame — Frame the problem before solving

You are framing a problem via `mcp__haft__haft_problem(action="frame", ...)`. Problem quality dominates solution quality. Get the frame right; the rest follows.

## Procedure

### Step 0 — Maintenance check (FPF B.3.4 evidence decay)

Before framing a NEW problem, check the most recent kernel response
for `Refresh reminder: N days since last stale scan`. If N > 30,
call `mcp__haft__haft_refresh(action="scan")` first. Stale or
drifted artifacts may already touch the area this new problem
operates in — discovering them after framing wastes the reasoning,
or worse, lets you frame a problem that's already been decided and
just decayed silently.

If the scan surfaces a conflict (stale decision in same module,
unresolved drift on overlapping files) — surface it inline and ask
the operator whether to verify the existing artifact first or
proceed with the new frame anyway. Do not silently re-frame around
obsolete artifacts.

See CLAUDE.md Critical Reminders — maintenance discipline.

### Step 1 — Stabilize the signal (FPF B.4.1)

Before writing anything, separate what the operator OBSERVED from what they ASSUMED. The signal is the anomaly/opportunity/probe; not the diagnosis.

Bad signal: "we need a new queue"
Good signal: "webhook retries hit 15% over baseline 2% since 2026-05-20"

### Step 2 — Detect umbrella words (FPF A.6.P/Q/A)

Scan the signal for umbrella terms: "quality", "service", "scalable", "maintainable", "simple", "stable", "ready", "process", "function", "component". Each needs precision restoration:
- "service is slow" → which service: the OAuth provider, the token endpoint, the session store?
- "quality is bad" → quality of what: maintainability (deps?), performance (p99?), readability (cyclomatic?)?
- "scalable" → scalable in what dimension: throughput? concurrent users? data size?

Ask one clarifying question if needed, or unpack inline with explicit re-statement.

### Step 3 — Classify the problem type (FPF FRAME-05)

One of:
- **optimization** — known-working system, want it better on a known dimension
- **diagnosis** — something's broken, root cause unclear → consider rerouting to h-diagnose
- **search** — need to find something that doesn't exist yet
- **synthesis** — combine existing elements into something new

Pass to kernel as `problem_type` field.

### Step 4 — Declare scope explicitly (FPF FRAME-02)

What's in-scope AND what's out-of-scope. Prevents silent scope inflation downstream.

### Step 5 — Declare acceptance criteria (FPF FRAME-03)

What observable condition signals "solved"? "Better" is not acceptance; "p95 webhook retry rate < 3% measured over 7-day window" is.

**Draft inline — do not delegate authorship back to the operator.** Read the signal carefully, propose a concrete observable acceptance condition based on the metric/behavior most directly tied to the signal. Then surface the draft to the operator with "I'm using this acceptance — edit if it's wrong". Operator review is the gate; operator authorship is not. Asking "what's your acceptance?" instead of drafting one defeats the value of the agent.

### Step 6 — Declare constraints (hard limits)

What no candidate variant may violate. Constraint role per FPF CHR-01.

### Step 7 — Optionally declare optimization targets + observation indicators

- `optimization_targets` (1-3 max) — what to optimize
- `observation_indicators` — watch but do NOT optimize (Anti-Goodhart per FPF CHR-01)

### Step 8 — Set mode based on blast radius (let the floor recommend it)

Don't default to `standard` by reflex. When you know the files the change will
touch, get a risk-proportioned recommendation first:

```
mcp__haft__haft_query(action="ceremony", files=["path/a.go", "db/0007.sql", ...])
```

It returns a recommended mode from path/content + governance signals, with a
deterministic safety floor: a HIGH-risk change (migration/sql, auth/secrets,
public-API, infra, destructive content, low-reversibility governance) is NEVER
recommended tactical, and when it can't tell it asks ONE question instead of
defaulting low. Use the recommendation — you can override it in one step. The
modes:

- `tactical` — reversible <2-week blast radius; minimum ceremony
- `standard` (default) — most architectural decisions
- `deep` — irreversible / security / cross-team / cross-repo; parity_plan required for downstream compare

### Step 9 — Call the kernel

```
mcp__haft__haft_problem(
  action="frame",
  title="<short problem title>",
  signal="<stabilized observation, not assumed cause>",
  problem_type="optimization|diagnosis|search|synthesis",
  acceptance="<observable solved-condition>",
  constraints=["<hard limit 1>", "<hard limit 2>"],
  optimization_targets=["<target 1>"],
  observation_indicators=["<Anti-Goodhart watch 1>"],
  blast_radius="<what systems/teams affected>",
  reversibility="low|medium|high",
  seed_file="<file the framing is about, if any>",
  mode="tactical|standard|deep"
)
```

When the problem is about a concrete file, pass `seed_file`: the response then
appends the artifacts the fused code+reasoning graph ranks nearest it — surfacing
a decision that already governs that code but which keyword recall would miss
(phrased differently). Check it before re-deciding what may already be decided.

### Step 10 — On success

Kernel returns ProblemCard ID (e.g. `prob-20260525-...`). Present to operator with suggested next steps:
- `/h-explore` (or h-diagnose if diagnosis-typed) to generate candidate solutions
- `/h-status` to see this problem in project FPF state
- For richer dimensions later: characterize via `mcp__haft__haft_problem(action="characterize", problem_ref=..., dimensions=[...])`

**Re-grounding discipline (FPF A.7).** When you reference the new
ProblemCard ID in subsequent operator-facing text, pair it with the
problem title or one-line signal — `prob-20260525-abc (cache-invalidation
flakes in schema-migration suite)` not bare `prob-20260525-abc`. Bare IDs
accumulate c