The Constraints-First Framework: Why You Don't Need a Second AI Subscription (And What to Do Instead)
The $20/Month Question
There's a recurring piece of advice circulating in Claude Code circles right now: run OpenAI Codex alongside Claude Code for maximum output. The pitch sounds reasonable — parallel model coverage, redundancy, specialization. In practice, for most business workflows, it's a subscription you don't need.
Scheffel's central argument is blunt: before you pay for a second model, exhaust what the first one can actually do. Most people running dual subscriptions haven't saturated Level 1 or Level 2 of what Claude Code is capable of. They're buying compute they don't need because they haven't structured their prompts, personas, or workflows correctly.
This article unpacks that three-level constraints-first framework — with specific command patterns, failure modes, and the narrow conditions under which a second model actually earns its keep.
Why "More Models = More Output" Is Usually Wrong
The intuition behind running Claude + Codex simultaneously is that two models catch each other's blind spots. But this logic breaks down for a specific reason: the bottleneck in most agentic workflows isn't the model's capability — it's the quality of the instructions given to it.
Think of it this way. If you're getting mediocre output from Claude Code, adding Codex doesn't fix the underlying problem. You now have two models producing mediocre output from poorly structured prompts, at twice the cost. You've scaled the symptom, not solved the root cause.
Scheffel's framework reframes the question: instead of asking "which model should I use?", ask "have I constrained this task correctly?" Constraints — clear scope, explicit persona, defined output format, bounded context — are what drive quality. Not model selection.
Most users are stuck at C and jumping straight to H. That's the $20 waste.
Level 1: Better Prompting — The Cheapest Leverage You Have
The first level of the framework is the most unglamorous and the most underutilized. Scheffel frames it as "better prompting," but what he means is more precise: constraints-first prompt architecture.
The failure mode at Level 1 is what most people do by default — open-ended task delegation. Something like:
Write me a Python script that handles authentication.
This produces generic output because Claude has no constraints to work within. It doesn't know your stack, your security requirements, your error handling preferences, or your output format. It fills the vacuum with defaults.
The constraints-first alternative:
You are working in a FastAPI codebase using PostgreSQL and JWT authentication.
The existing auth module is at /src/auth/. Do not modify any existing files.
Create a new middleware file at /src/auth/rate_limiter.py that:
- Implements per-IP rate limiting using Redis
- Returns 429 with a Retry-After header on breach
- Logs all rate limit events to the existing logger at /src/utils/logger.py
- Includes unit tests in /tests/auth/test_rate_limiter.py
Output ONLY the two files. No explanation. No markdown fencing around the code.
The difference isn't creativity — it's constraint density. Every sentence removes a degree of freedom that Claude would otherwise fill with a guess.
The Four Constraint Dimensions
For any Claude Code task, run through these four dimensions before hitting enter:
| Dimension | Question to Ask | Example Constraint | |-----------|----------------|-------------------| | Scope | What is explicitly in and out of bounds? | "Do not modify files outside /src/auth/" | | Format | What does the output look like exactly? | "Return only the file contents, no explanation" | | Context | What does Claude need to know about your environment? | "We use pytest, not unittest. Redis is on localhost:6379" | | Behavior | How should Claude handle edge cases? | "If you're uncertain about the Redis schema, ask before writing" |
Skipping any of these is where hallucinated imports, wrong file paths, and broken assumptions come from. Not model failure — constraint failure.
The /goal Command as a Constraint Anchor
If you're using Claude Code's /goal command (or equivalent structured session openers), treat it as the place to front-load your constraint stack. The goal isn't just to describe what you want — it's to define the boundaries within which Claude operates for the entire session.
A well-structured /goal block looks like this:
/goal
OBJECTIVE: Refactor the payment processing module to use Stripe's new PaymentIntent API
CONSTRAINT: Existing tests must pass. Do not change function signatures.
CONSTRAINT: All new code must follow the existing typing conventions in /src/types/
CONSTRAINT: No third-party libraries beyond what's in requirements.txt
SUCCESS CRITERIA: All tests green, Stripe dashboard shows PaymentIntents (not Charges)
OUT OF SCOPE: Frontend changes, webhook handling, subscription logic
This anchor persists across the session. Every subsequent command Claude executes gets evaluated against this goal frame. Without it, each task is stateless — Claude optimizes locally instead of globally.
Level 2: Persona Prompting — Behavioral Constraints, Not Just Task Constraints
Level 1 constrains what Claude does. Level 2 constrains how it thinks. This is the layer most power users skip, and it's where significant quality gains are hiding.
Scheffel calls this "persona prompting," but the mechanism is more specific: you're installing a cognitive filter that changes which solutions Claude reaches for first.
The core insight is that Claude Code, without persona constraints, defaults to a kind of averaged engineering behavior — it produces the solution a competent-but-generic developer would write. That's often fine. But for specialized domains — security hardening, performance optimization, legacy system modernization — you want Claude thinking from within a specific discipline, not around it.
What a Persona Actually Does
A persona prompt does three things:
- Shifts the prior on what "good" looks like for this task
- Activates domain-specific heuristics that Claude has from training
- Changes the failure mode handling — a security-focused persona flags things a generic developer persona ignores
Compare these two openers:
Generic:
Review this authentication code and suggest improvements.
Persona-constrained:
You are a senior application security engineer conducting a pre-production security review.
Your primary concern is attack surface reduction and defense-in-depth.
You are NOT optimizing for readability or performance unless they create security implications.
Flag every assumption the code makes about input validity.
Treat all external data as hostile until proven otherwise.
The output from the second prompt will surface timing attacks, injection vectors, and session fixation risks that the first prompt won't touch — not because Claude didn't know about them, but because the generic frame didn't make them salient.
Persona Templates for Common Claude Code Workflows
For code review:
You are a principal engineer at a company where production incidents cost $50K/hour.
Your code review prioritizes: error handling, failure modes, observability gaps.
For every suggestion, explain the failure scenario it prevents.
Do not comment on style unless it causes ambiguity.
For refactoring:
You are a software archaeologist working on a 10-year-old codebase.
Assume nothing is documented correctly. Assume existing behavior is intentional until proven otherwise.
Your constraint: preserve all observable behavior. Improve only internal structure.
Before refactoring any function, state what you believe it currently does and why.
For architecture decisions:
You are a staff engineer presenting three architectural options to a skeptical CTO.
For each option: state the tradeoffs, the failure modes at scale, and the operational burden.
Do not recommend a single answer. Present the decision space clearly.
Flag any assumption that, if wrong, would invalidate your analysis.
Combining Personas with /goal
The most powerful pattern is stacking: use /goal to define the task scope, then open with a persona block that defines the cognitive frame for the session.
/goal
OBJECTIVE: Audit the API layer for security vulnerabilities before Q4 launch
SCOPE: /src/api/ directory only
SUCCESS CRITERIA: Documented findings with severity ratings and remediation steps
---
PERSONA: You are a penetration tester with 10 years in API security.
You approach this with adversarial intent — you are looking for ways to break this system, not ways to improve it.
Every finding must include: vulnerability class, CVSS score estimate, proof-of-concept attack scenario, and recommended fix.
This combination gives Claude both a behavioral anchor (the persona) and a task anchor (the goal). The output quality difference over ad-hoc prompting is substantial — not because the model changed, but because the constraint density did.
Level 3: When a Second Model Actually Earns Its Keep
Scheffel is clear that Level 3 is the exception, not the rule. After genuinely exhausting Levels 1 and 2, there are specific scenarios where a second model provides real value that no amount of prompting can substitute. Understanding the narrow conditions matters — because paying for a second model in a case that Level 2 solves is still money wasted.
The Three Legitimate Cases for a Second Model
Case 1: Genuine domain specialization. Some models are genuinely better at specific tasks — code generation vs. reasoning vs. document analysis. If you've maxed out Claude Code's output on a specific task type and the gap is consistent and costly, a specialized model may be worth it. The test: run the same well-constrained prompt through both models 10 times. If the second model wins consistently on your specific use case, the cost delta is justified.
Case 2: Parallel workload that can't be serialized. If you have genuinely independent tasks that need to run simultaneously — not because you're impatient, but because the workflow design requires true parallelism — a second model subscription enables concurrent agent spawning without rate limiting one conversation. This is a workflow architecture argument, not a quality argument.
Case 3: Verification and adversarial review. Some workflows benefit from having one model generate and a second model critique — not because either is better, but because they make different errors. This is a legitimate use of heterogeneous models in multi-agent setups. The gotcha: this only works if the critic model is actually running different reasoning, not just echoing the generator. This requires careful prompt design to ensure the critic isn't simply agreeing with the first model's output.
The $20 Test
Before adding any subscription, apply this test: Can I achieve 80% of the value by spending 20 minutes improving my prompt and persona stack instead?
If yes — and for most workflows, the answer is yes — the subscription is waste. If no, and you can demonstrate that with actual output comparisons, pay for the second tool.
The Constraints-First Framework as a Daily Protocol
Pulling the levels together into a morning workflow protocol — something you can run as a checklist before any Claude Code session:
Pre-Session Checklist
□ Define /goal with explicit SUCCESS CRITERIA and OUT OF SCOPE sections
□ Write persona block appropriate to the task domain
□ List the four constraint dimensions: Scope, Format, Context, Behavior
□ Identify any assumptions Claude might make that you need to pre-empt
□ Determine if this session requires parallelism (if yes: plan agent spawning, not a second subscription)
During-Session Discipline
□ If output quality degrades: check constraint drift, not model capability
□ If Claude makes wrong assumptions: add that assumption to the constraint stack for next time
□ If you find yourself re-explaining context: your /goal block was incomplete
□ If you're getting generic solutions: your persona needs more cognitive specificity
Post-Session Audit
□ What constraints did you add mid-session? Add them to your template.
□ What did Claude get wrong? Was it a model failure or a constraint failure?
□ Did you use a second model? Was it actually necessary?
□ What prompt patterns worked well? Extract them for reuse.
This audit loop is where the compounding happens. Each session, your constraint library gets richer. The delta between your Claude Code output and a naive user's output grows — not because you have better tools, but because you have better-constrained prompts.
Multi-Agent Orchestration: Applying Constraints-First to Parallel Workflows
Where this framework becomes particularly powerful is in multi-agent setups — and this is where Brian's goal of parallel agent orchestration connects directly to Scheffel's framework.
The failure mode in naive multi-agent orchestration is spawning agents without individual constraint stacks. You get an orchestrator that dispatches vague tasks to agents that fill the vacuum with defaults, producing outputs that don't fit together without manual reconciliation.
The constraints-first approach applied to multi-agent looks like this:
Each spawned agent needs its own /goal equivalent — scoped to its sub-task, with output format constraints designed to be merge-compatible with the other agents' outputs. If you skip this, the orchestrator spends most of its tokens reconciling format mismatches instead of doing higher-order work.
A Concrete Multi-Agent Pattern
Say you're running parallel code review agents across three modules:
Orchestrator goal:
/goal
OBJECTIVE: Security audit of three API modules before deployment
AGENTS: 3 parallel reviewers, one per module
OUTPUT FORMAT: Each agent returns structured JSON: {module, findings: [{severity, description, line_ref, fix}], summary}
MERGE CRITERIA: Findings are deduplicated by line_ref. Severity ratings use CVSS 3.1 scale.
Per-agent constraint stack (templated, instantiated per module):
SCOPE: /src/api/{module_name}/ only — do not reference or analyze other modules
PERSONA: Senior application security engineer, adversarial mindset
OUTPUT: Return only valid JSON matching the orchestrator schema. No prose. No markdown.
ASSUMPTION HANDLING: If you find a cross-module dependency that affects your analysis, note it in the findings with severity "INFO" — do not investigate the dependency directly.
The orchestrator now receives three machine-parseable outputs it can merge without manual intervention. The ASSUMPTION HANDLING instruction prevents agents from scope-creeping into each other's territory, which is the most common failure mode in parallel agent setups.
Failure Modes to Watch
A few gotchas that Scheffel's framework implies but doesn't always name explicitly:
Constraint drift in long sessions. The /goal anchor established at session start degrades as context fills. Claude Code's effective constraint adherence drops in sessions longer than ~50k tokens. Solution: restate the goal block at the midpoint of long sessions, or break sessions into bounded sub-sessions with explicit handoff artifacts.
Persona bleed. Strong persona prompts occasionally cause Claude to refuse tasks it would otherwise handle, because the persona's "professional standards" conflict with the task. A security-focused persona might refuse to write test code that intentionally creates vulnerable endpoints for red team exercises. Solution: explicitly carve out exceptions in the persona definition: "Your persona applies to analysis and review. For test scaffolding, operate without persona constraints."
Over-constraining. The inverse failure mode: too many constraints create contradictions that Claude has to choose between, producing inconsistent output. If you have more than 8-10 constraints in a single block, audit for conflicts and priorities. Constraints need a precedence order when they conflict.
Second-model dependency creep. If you add a second model and it improves output, you'll stop iterating on prompt quality. The second model becomes a crutch that masks a constraint deficit. Periodically re-run your multi-model workflows through Claude Code alone with better-constrained prompts to audit whether the second model is still earning its cost.
The Bottom Line
Scheffel's framework isn't anti-tool — it's pro-leverage. The point isn't that Codex or other models are bad. The point is that most users haven't extracted the full value from the model they already have, and adding a second subscription before doing that work is pure waste.
The discipline is this: before you pay for more compute, pay with more thinking about constraints. The ceiling on single-model, well-constrained Claude Code workflows is higher than most practitioners have tested. Level 1 (constraints-first prompting) and Level 2 (persona prompting) eliminate the majority of use cases where a second model seems necessary.
When you do need Level 3 — parallel architecture, genuine domain specialization, adversarial verification — add it deliberately, with a clear ROI test, and audit it regularly to make sure it's still earning its place.
The practitioners who compound fastest aren't the ones with the most tools. They're the ones who've built the deepest constraint libraries for the tools they have.
Today's One Action
Build your constraints-first session template tonight and use it tomorrow morning.
Take the four constraint dimensions (Scope, Format, Context, Behavior) and the persona framework, and write a reusable template for the two or three Claude Code task types you run most frequently. Structure each template as a /goal block + persona block combination. Tomorrow, open every Claude Code session with the appropriate template instead of ad-hoc prompting.
After three sessions, audit: where did Claude still make wrong assumptions? Add those to the constraint stack. After one week, your templates will be specific enough that session startup time drops, output quality stabilizes, and you'll have a clear-eyed view of whether you actually need a second model subscription — or whether the gap was always in the prompts.