Skill: quochungto/bookforge-architecture-tradeoff-analyzer (version 1.0.0)

--- name: architecture-tradeoff-analyzer description: Systematically analyze trade-offs across quality attribute dimensions for architecture decisions. Use this skill whenever the user is comparing architecture options, weighing competing quality attributes (performance vs scalability, simplicity vs flexibility), making any structural technology decision, evaluating monolith vs distributed, choosing communication patterns, or asking "what are the trade-offs?" — even if they don't explicitly say "trade-off analysis." version: 1.0.0 homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/fundamentals-of-software-architecture/skills/architecture-tradeoff-analyzer metadata: {"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}} status: draft source-books: - id: fundamentals-of-software-architecture title: "Fundamentals of Software Architecture" authors: ["Mark Richards", "Neal Ford"] chapters: [1, 2, 4, 5, 18, 19] tags: [software-architecture, architecture, trade-offs, decision-making, quality-attributes] depends-on: [] # Foundation skill — no dependencies execution: tier: 1 mode: full inputs: - type: none description: "Architecture decision context from the user — what options they're considering and why" tools-required: [Read, Write] tools-optional: [Grep, Glob] mcps-required: [] environment: "Any agent environment. If a codebase exists, can read it for context." --- # Architecture Trade-off Analyzer ## When to Use You're in a situation where an architecture decision needs to be made and there are competing concerns. Typical triggers: - The user is choosing between architecture styles (monolith vs microservices, event-driven vs request-reply) - The user mentions competing quality attributes ("we need it fast AND scalable AND simple") - The user is presenting a single option as "the best" — they haven't analyzed trade-offs yet - The user is stuck in analysis paralysis or decision avoidance - An architecture decision needs to be documented with rationale Before starting, verify: - Is there actually a decision to make? (If the user is just asking for information, explain concepts instead) - Are there at least 2 viable options to compare? (If only one option exists, help identify alternatives first) ## Context ### Required Context (must have before proceeding) - **The decision to make:** What architectural choice is being considered? Ask the user if not stated. - **At least 2 viable options:** You can't analyze trade-offs with only one option. If the user presents just one, help them identify at least one alternative. ### Observable Context (gather from environment if available) - **Codebase structure:** If a project exists, scan for architecture patterns already in use → Look for: directory structure, config files (docker-compose, k8s manifests), service boundaries → If unavailable: treat as greenfield - **Existing architecture docs:** Check for ADRs, architecture diagrams, tech specs → Look for: `docs/`, `architecture/`, `adr/`, `*.adr.md`, README architecture sections → If unavailable: start from the user's verbal description - **Team and operational context:** Team size, deployment frequency, cloud provider, budget constraints → If unavailable: ask the user for the top constraints ### Default Assumptions - If no quality attributes specified → ask the user to pick their top 3 driving concerns - If no team context → assume a small team (3-8 developers) - If no existing architecture → assume greenfield project - If no deployment context → assume cloud-native ## Process ### Step 1: Frame the Decision **ACTION:** Clearly state the architectural decision that needs to be made. Name the competing options. **WHY:** Fuzzy decisions produce fuzzy analysis. "Should we use microservices?" is too vague. "Should our order processing system use microservices or a modular monolith, given that we need independent scaling of the payment module?" is a decision you can actually analyze. Framing also prevents scope creep — the analysis stays focused on THIS decision. **IF** the user hasn't specified options → help them enumerate at least 2-3 viable alternatives before proceeding. ### Step 2: Identify Relevant Quality Attributes **ACTION:** Determine which architecture characteristics (quality attributes) are affected by this decision. Focus on the user's top 3 driving characteristics. **WHY:** Not all quality attributes matter for every decision. Analyzing 15 attributes produces noise. The "Top-3 Rule" from architecture practice says: keep driving characteristics to three maximum. This forces prioritization and makes trade-offs visible. Each additional characteristic you design support for complicates the overall system — like flying a helicopter where every control affects every other control. Common quality attribute categories: - **Operational:** availability, scalability, performance, reliability, elasticity - **Structural:** maintainability, extensibility, modularity, testability, deployability - **Cross-cutting:** security, observability, simplicity, cost, time-to-market For the full taxonomy, see [references/quality-attributes.md](references/quality-attributes.md). **IF** the user says "all of them are important" → push back. Ask: "If you could only optimize for 3, which would they be?" This reveals the real priorities. ### Step 3: Analyze Each Option's Advantages **ACTION:** For each architectural option, list what it does WELL across the identified quality attributes. **WHY:** Start with advantages to build a fair picture. Most teams already lean toward one option — this step validates their intuition and builds confidence that you understand the options before challenging them. ### Step 4: Hunt for the Negatives **ACTION:** For each option, actively search for disadvantages, risks, and hidden costs. This is the critical step. **WHY:** "Programmers know the benefits of everything and the trade-offs of nothing. Architects need to understand both." The natural human bias is to see advantages of the preferred option and disadvantages of alternatives. An architect's core job is to overcome this bias. If you can't articulate the downsides of your chosen approach, you haven't analyzed it deeply enough. If you think there are no trade-offs, you haven't found them yet (First Law, Corollary 1). Probe for: - What gets WORSE when you optimize for the advantages? - What new failure modes does this option introduce? - What operational burden does it create? - What happens when the system scales 10x? - What coupling does this option hide? ### Step 5: Build the Trade-off Matrix **ACTION:** Create a comparison table with options as columns and quality attributes as rows. For each cell, mark whether the option supports (+), hurts (-), or is neutral (=) for that attribute, with a brief justification. **WHY:** A visual matrix makes trade-offs undeniable. When you see that Option A is (+) on scalability but (-) on simplicity and (-) on cost, while Option B is the reverse, the decision becomes a conscious prioritization rather than a gut feeling. This is also the primary artifact stakeholders can review. Format: ``` | Quality Attribute | Option A | Option B | |-------------------|---------------|---------------| | Scalability | + (why) | - (why) | | Simplicity | - (why) | + (why) | | Cost | - (why) | + (why) | | Deployability | + (why) | = (neutral) | ``` ### Step 6: Identify Synergies and Conflicts **ACTION:** Note where quality attributes reinforce each other (synergies) or conflict (tensions) within each option. **WHY:** Trade-offs aren't just between options — they exist WITHIN options too. Security almost always hurts performance. Scalability often conflicts with simplicity. Recognizing these internal tensions prevents surprise later. It also reveals "least worst" opportunities — options where the internal conflicts are most manageable for your specific context. ### Step 7: Apply the "Least Worst" Principle **ACTION:** Recommend an option based on which has the most acceptable set of trade-offs for THIS specific context. Frame as "least worst" not "best." **WHY:** There is no "best" architecture — only trade-offs. The goal is the option whose downsides are most tolerable given the team's constraints, business goals, and risk appetite. Framing as "least worst" sets honest expectations: you're choosing which problems you'd rather have, not eliminating problems. This prevents "Covering Your Assets" — the anti-pattern where architects avoid decisions out of fear of being wrong. **The decision depends on:** deployment environment, business drivers, company culture, budgets, timeframes, developer skill set, and operational maturity. **After stating the recommendation, always include a "Context Sensitivity" analysis:** explicitly state what would change the recommendation. For example: "If the team had 2+ years of microservices experience, we'd recommend Option A instead." This prevents the recommendation from being treated as universal truth — it's context-dependent, and the conditions under which it would flip should be transparent. **Reference named anti-patterns when relevant:** When the analysis reveals a decision-making dysfunction (fear of deciding, repeated debates, lost rationale), name the anti-pattern explicitly: - **Covering Your Assets** — avoiding decisions out of fear of being wrong - **Groundhog Day** — same decisions debated repeatedly because rationale wasn't recorded - **Email-Driven Architecture** — decisions lost because they were communicated only via email, not documented - **Analysis Paralysis** — over-analyzing without deciding (the flip side of Covering Your Assets) Naming the anti-pattern helps teams recognize and break the pattern. ### Step 8: Document the Decision **ACTION:** Produce a Trade-off Analysis Report (see Output format below). If the decision is architecturally significant, also produce an ADR summary. **WHY:** "Why is more important than how" (Second Law). Future developers can look at a system and figure out HOW it's structured. What they can't figure out is WHY those choices were made. Without documentation, teams fall into the "Groundhog Day" anti-pattern — the same decisions get debated repeatedly because nobody recorded the rationale. A decision is architecturally significant if it affects: structure, nonfunctional characteristics, dependencies, interfaces, or construction techniques. ## Inputs - The architectural decision to analyze (from user) - Quality attributes to evaluate (from user, or discovered in Step 2) - Optionally: existing codebase, architecture docs, team context ## Outputs ### Trade-off Analysis Report ```markdown # Trade-off Analysis: {Decision Title} ## Decision {Clear statement of the decision being analyzed} ## Options Considered 1. **{Option A}** — {one-line description} 2. **{Option B}** — {one-line description} 3. **{Option C}** — {if applicable} ## Driving Quality Attributes 1. {Top priority attribute} 2. {Second priority} 3. {Third priority} ## Trade-off Matrix | Quality Attribute | Option A | Option B | Option C | |-------------------|----------|----------|----------| | {Attribute 1} | + reason | - reason | = reason | | {Attribute 2} | - reason | + reason | + reason | | {Attribute 3} | + reason | = reason | - reason | ## Synergies and Conflicts - {Option A}: {attribute X} reinforces {attribute Y} because... - {Option B}: {attribute X} conflicts with {attribute Z} because... ## Recommendation **{Recommended option}** — the least worst choice for this context because: - {Primary justification tied to top driving attribute} - {Secondary justification} - {Acknowledged downsides and why they're acceptable} ## Risks of This Choice | Risk | Likelihood | Impact | Mitigation | |------|-----------|--------|------------| | {Risk 1} | Low/Med/High | Low/Med/High | {Concrete mitigation} | | {Risk 2} | Low/Med/High | Low/Med/High | {Concrete mitigation} | ## Context Sensitivity This recommendation assumes: {key assumptions}. - **If {constraint X changed}** → we'd recommend {Option Y} instead because {reason} - **If {constraint Z changed}** → the trade-off balance shifts toward {Option W} because {reason} ## Architecture Decision Record (if architecturally significant) - **Status:** Proposed - **Context:** {forces at play} - **Decision:** {active voice, with full WHY justification} - **Consequences:** {positive AND negative trade-offs} ``` ## Key Principles - **Everything is a trade-off** — If you think you've found something that isn't, you haven't looked hard enough. This isn't pessimism; it's the foundational reality of architecture that enables honest decision-making. - **Why over how** — Document the reasoning, not just the outcome. Future developers can reverse-engineer how a system works; they can't reverse-engineer why it was built that way. WHY prevents repeated debates. - **Least worst, not best** — Never shoot for the "best" architecture. Aim for the one with the most acceptable set of trade-offs for your specific context. This framing sets honest expectations and prevents decision paralysis. - **Top-3 quality attributes** — Resist the urge to optimize for everything. Each additional quality attribute you support complicates the system. Force stakeholders to choose their top 3 driving characteristics. - **Hunt the negatives** — The value of a trade-off analysis is in the disadvantages you discover, not the advantages. Advantages are easy to see. Disadvantages require deliberate searching. An analysis with no negatives is an incomplete analysis. - **Context is everything** — "It depends" is a valid answer. The same trade-off analysis on the same options will produce different recommendations for different teams, budgets, timelines, and business goals. Never copy an architecture decision from another project without re-analyzing the trade-offs in YOUR context. Always state what would change the recommendation if constraints shifted. - **Name the dysfunction** — When you spot a decision-making anti-pattern (fear of deciding, repeated debates, lost decisions), name it explicitly. Covering Your Assets, Groundhog Day, Email-Driven Architecture, and Analysis Paralysis are common patterns that teams fall into. Naming the pattern is the first step to breaking it. ## Examples **Scenario: Messaging pattern for auction system** Trigger: "Should we use pub/sub topics or point-to-point queues for our bidding system?" Process: Framed decision as topics vs queues for bid distribution. Identified driving attributes: extensibility, security, monitoring. Built matrix showing topics excel at extensibility and decoupling, but queues excel at security (isolated access), heterogeneous contracts (per-consumer formats), and monitoring (per-queue metrics). Identified conflict: extensibility vs security within topics. Output: Recommended queues for the payment and analytics services (security-critical), topics for the bid streaming service (extensibility-critical). Trade-off: accept tighter coupling in exchange for security and monitoring control. **Scenario: Monolith vs microservices for sandwich ordering app** Trigger: "We're building a simple ordering system but customization per franchise is key. Microservices?" Process: Framed as modular monolith vs microkernel. Top 3 attributes: customization, simplicity, cost. Matrix showed both options are acceptable — modular monolith is simpler and cheaper but customization requires explicit override design; microkernel maps naturally to customization (plug-in per franchise) but adds infrastructure complexity. Applied least-worst: for a small team with budget constraints, modular monolith with a customization override endpoint is the least worst — it's simpler, cheaper, and customization can be explicitly designed with fitness functions. Output: Trade-off analysis report + ADR recommending modular monolith with override endpoint. Explicitly documented the trade-off: accepting manual customization management in exchange for simplicity and low cost. **Scenario: Synchronous vs asynchronous for high-scale system** Trigger: "We're redesigning our auction platform. REST everywhere or should we mix in message queues?" Process: Framed as synchronous-default vs async-where-needed. Top 3: reliability, scalability, simplicity. Matrix: sync is simpler and easier to debug but creates cascading failures under load; async scales better and buffers spikes but introduces data synchronization complexity, potential deadlocks, and harder debugging. Applied context: the payment service needs reliability buffering (many auctions ending simultaneously), but the session management service is simple request/response. Output: Recommended mixed approach: synchronous by default (simpler), asynchronous for payment processing and bid capture (reliability-critical, spike-prone). Documented the "use synchronous by default, asynchronous when necessary" principle. ## References - For the full list of quality attributes and their definitions, see [references/quality-attributes.md](references/quality-attributes.md) ## License This skill is licensed under [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/). Source: [BookForge](https://github.com/bookforge-ai/bookforge-skills) — Fundamentals of Software Architecture by Mark Richards, Neal Ford. ## Related BookForge Skills This skill is standalone. Browse more BookForge skills: [bookforge-skills](https://github.com/bookforge-ai/bookforge-skills)

path: references/quality-attributes.md
content: # Architecture Quality Attributes Reference

Use this reference when you need the full list of quality attributes for trade-off analysis. Organized by category.

## Operational Characteristics

These affect how the system runs in production.

| Attribute | Definition | Trade-off tension |
|-----------|-----------|-------------------|
| **Availability** | System uptime level (e.g., 99.9%) | Higher availability = more redundancy = higher cost |
| **Continuity** | Disaster recovery capability | Better DR = more infrastructure = higher cost/complexity |
| **Performance** | Response time, throughput, capacity | Better performance often conflicts with security (encryption overhead) and maintainability (optimized code is harder to read) |
| **Recoverability** | Time to recover from failure | Fast recovery = more sophisticated backup/failover = cost |
| **Reliability** | Data integrity, fail-safe behavior | Higher reliability often requires synchronous processing = lower throughput |
| **Robustness** | Error handling, boundary conditions | More robust = more defensive code = slower development velocity |
| **Scalability** | Handle growing load | Better scalability typically requires distributed architecture = more complexity, more cost |
| **Elasticity** | Handle sudden bursts | Elastic systems need auto-scaling infrastructure = cloud cost variability |

## Structural Characteristics

These affect how the codebase is organized and evolved.

| Attribute | Definition | Trade-off tension |
|-----------|-----------|-------------------|
| **Configurability** | End-user customization ease | More configurable = more code paths = harder to test |
| **Extensibility** | Adding new functionality | More extensible = more abstraction = initial complexity overhead |
| **Maintainability** | Ease of changes | Better maintainability often requires more modular architecture = more inter-service communication |
| **Modularity** | Separation of concerns | More modular = more boundaries = more coordination overhead |
| **Testability** | Ease of testing | Better testability requires clean interfaces = more upfront design effort |
| **Deployability** | Ease and frequency of releases | Better deployability often requires microservices or containers = operational complexity |
| **Portability** | Run on multiple platforms | More portable = more abstraction layers = potential performance loss |
| **Upgradeability** | Ease of version upgrades | Easier upgrades = more backward compatibility = code bloat |

## Cross-Cutting Characteristics

These span multiple categories.

| Attribute | Definition | Trade-off tension |
|-----------|-----------|-------------------|
| **Security** | Protection against threats | More security = more encryption/indirection = worse performance |
| **Accessibility** | Support for all users | Better accessibility = more implementation effort = slower delivery |
| **Observability** | Visibility into system behavior | More observability = more instrumentation = slight performance overhead |
| **Simplicity** | Ease of understanding | Simpler systems are easier to maintain but may sacrifice scalability/flexibility |
| **Cost** | Total cost of ownership | Lower cost often means accepting trade-offs in scalability, reliability, or performance |
| **Time-to-market** | Speed of initial delivery | Faster delivery often means accepting technical debt |

## Common Trade-off Pairs

These quality attributes frequently conflict:

| Attribute A | vs | Attribute B | Why they conflict |
|-------------|:---:|-------------|-------------------|
| Performance | vs | Security | Encryption, indirection, and access control add latency |
| Scalability | vs | Simplicity | Distributed systems scale better but are fundamentally more complex |
| Scalability | vs | Cost | More instances, more infrastructure, more operational overhead |
| Maintainability | vs | Performance | Clean, readable code runs slower than hand-optimized code |
| Extensibility | vs | Simplicity | Abstraction layers for future flexibility add current complexity |
| Reliability | vs | Performance | Synchronous processing ensures data integrity but limits throughput |
| Deployability | vs | Simplicity | Independent deployments require service boundaries = more moving parts |
| Time-to-market | vs | Maintainability | Shortcuts speed delivery but create technical debt |


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)