skills/thinking-steel-manning/SKILL.md
Use before rejecting a proposal or when you're inclined to just agree with the user. Build the strongest version of the opposing case first, then engage that — not a weak version.
npx skillsauth add tjboudreaux/cc-thinking-skills thinking-steel-manningInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Steel-manning is the opposite of straw-manning. Instead of attacking the weakest version of an opposing argument, you construct and address the strongest possible version. This leads to better decisions, more productive debates, and deeper understanding of trade-offs.
Core Principle: To truly evaluate an idea, argue against its best form. If you can defeat the strongest version, you've actually learned something.
Decision flow:
Disagreeing with a proposal?
→ Can you state their best argument? → no → STEEL-MAN FIRST
→ Are you attacking a weak version? → yes → CONSTRUCT STRONGER VERSION
→ Have you found the core insight? → no → DIG DEEPER
About to agree with the user's plan?
→ Have you stated the strongest case against it? → no → STEEL-MAN THE OPPOSING VIEW FIRST
This skill is the direct counter to sycophancy — the pull to validate whatever the user proposed. Before endorsing a plan, construct the best case against it; agreement that survives that is worth more than reflexive agreement.
Before rejecting a proposal or when you're inclined to just agree with the user:
Skip for trivial or fully reversible choices where the cost of being wrong is near zero. In an emergency, steel-man the post-incident review, not the live fire.
Before improving, understand:
## Original Proposal
Proposal: "We should rewrite the backend in Rust"
Stated reasons:
- Memory safety
- Better performance
- Modern language
Apparent weaknesses:
- Team doesn't know Rust
- Rewrite is risky
- Current system works
What's the strongest kernel of truth?
## Core Insight
Behind "rewrite in Rust" is:
- Concern about memory-related bugs in production
- Performance problems that are hard to solve in current language
- Technical debt making changes slow
The proposal might be wrong, but the concerns are valid.
Build the best possible case:
## Steel-Manned Argument
"Our memory-safety issues have caused 3 major outages this year,
costing us ~$500K in engineering time and customer trust.
Our performance problems stem from GC pauses that are fundamental
to our current runtime. While a rewrite is risky, the incremental
cost of working around these limitations is growing.
A gradual rewrite of performance-critical paths to Rust would:
- Eliminate a class of bugs (memory safety)
- Solve GC-related latency issues
- Attract engineers who want modern tooling
- Create optionality for high-performance features
The risk can be mitigated by:
- Starting with one isolated service
- Keeping the team small and focused
- Maintaining the old system during transition
- Having clear rollback criteria"
Now engage with the strongest argument:
## Response to Steel-Manned Argument
The strongest case for Rust addresses real problems. However:
Memory safety issues:
- 2 of 3 outages were logic bugs, not memory bugs
- Could be addressed with better testing in current language
- Rust learning curve might introduce new bug classes
Performance:
- GC issues could be addressed with tuning
- Critical path is <5% of codebase
- FFI to native code is an option without full rewrite
The 6-month investment in Rust might be better spent:
- 2 months: Performance profiling and GC tuning
- 2 months: Targeted native extensions for hot paths
- 2 months: Improved testing/monitoring
This addresses the concerns with lower risk.
What's the best answer considering both sides?
## Synthesis
The Rust proposal was right about the problems, less right about the solution.
Agreed:
- Memory safety is a real concern (but smaller than stated)
- Performance needs improvement (but addressable incrementally)
- Technical modernization has value (but not at rewrite cost)
Plan:
1. Address immediate performance with profiling + tuning
2. Build one small service in Rust as learning experiment
3. Evaluate Rust for future services based on learnings
4. Don't rewrite existing system
This takes the best of both positions.
## Design Review: Microservices Proposal
Weak version to avoid:
"They just want to use trendy tech"
Steel-manned version:
"The monolith has become a development bottleneck.
Deploy conflicts are causing delays. Different teams
need different scaling characteristics. The proposal
addresses real coordination problems."
Now address:
"The coordination problems are real, but can we solve them
with modular monolith patterns before taking on distributed
systems complexity?"
## Code Review: Complex Abstraction
Weak critique:
"This is over-engineered"
Steel-manned understanding:
"The author anticipated we'll need to support multiple
backends. This abstraction makes adding new backends
trivial. The complexity exists to serve future flexibility."
Better critique:
"I understand this enables multiple backends. Let's
validate that requirement—if we only ever need one,
the abstraction adds maintenance burden without benefit."
## Team Disagreement: Testing Strategy
Person A: "We need 100% code coverage"
Person B: "Code coverage is a vanity metric"
Steel-man A:
"Coverage ensures we think about edge cases and makes
refactoring safer. Without coverage requirements,
critical paths go untested."
Steel-man B:
"Coverage without quality gives false confidence.
Testing getters/setters wastes time better spent on
integration tests that catch real bugs."
Synthesis:
"Coverage is valuable for complex logic, less valuable
for trivial code. Let's require coverage for business
logic modules, but focus on integration tests for
overall system confidence."
## Validating My Own Decision
My decision: Use NoSQL for this project
Steel-man the opposite:
"SQL has survived 50 years because relational models
work for most data. NoSQL solves problems most projects
don't have. The flexibility of schemaless data becomes
a bug when requirements solidify. Joins are a feature,
not a limitation."
Now: Does my NoSQL choice survive this critique?
- Do I actually need schemaless flexibility?
- Will I regret not having joins?
- Am I solving a problem I don't have?
Signs you're straw-manning instead:
| Straw-Man Sign | Example | Fix | |----------------|---------|-----| | "They just want..." | "They just want to use new tech" | Find the legitimate concern | | Attacking messenger | "They're inexperienced" | Address the argument | | Cherry-picking worst example | "Remember when X failed?" | Consider best examples | | Assuming bad faith | "They don't care about quality" | Assume they want good outcomes | | Ignoring strong points | Skipping their best argument | Address strongest point first |
# Steel-Man Analysis: [Topic]
## Original Position
Who: [Person/group]
Position: [Their stated view]
Stated reasons: [Their explicit arguments]
## Apparent Weaknesses
[What seems wrong at first glance]
## Core Insight
[The legitimate concern or truth behind the position]
## Steel-Manned Version
[The strongest possible formulation of their argument]
"[Write it as if you were advocating for this position]"
## My Response to the Strong Version
[Now address the steel-manned argument]
## What I Learned
[How did steel-manning change my understanding?]
## Synthesis
[Best answer considering both positions]
Daniel Dennett, channeling Anatol Rapoport, offers rules for criticizing:
This is steel-manning as ethical practice.
"He who knows only his own side of the case knows little of that."
You don't truly understand your position until you can argue the opposition's best case. Steel-manning isn't weakness—it's the path to strong positions that can withstand strong criticism.
tools
About to add a feature/layer/process to fix a problem. First ask what to remove instead — subtraction is often more robust than addition. Use for simplification and complexity reduction.
development
Use when stuck between two architecture or API requirements that seem mutually exclusive — name the contradiction precisely, then separate the conflicting states in time, space, or condition.
testing
You need to trace how a system would fail or behave at a scale you can't cheaply test or measure. Use to imagine the scenario and walk the consequence chain step by step.
devops
Use when optimizing latency or throughput in a pipeline and one stage dominates—focus all effort on that single bottleneck, since speeding up the others changes nothing until it's fixed.