计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
technology-adoption【效率与协作】Maps concrete project requirements to specific technology recommendations using domain-driven decision matrices, adoption risk scoring, and phased rollout strategies for selecting and leveraging technologies effectively.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: technology-adoption description: Maps concrete project requirements to specific technology recommendations using domain-driven decision matrices, adoption risk scoring, and phased rollout strategies for selecting and leveraging technologies effectively. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: coding triggers: technology adoption, tech stack choice, how do i choose technology, select framework for my project, pick the right tool, technology decision, framework recommendation, technology leverage framework for my project archetypes:
Maps concrete project requirements to specific technology recommendations using domain-driven decision matrices, adoption risk scoring, and phased rollout strategies. This skill helps teams choose technologies that match their actual needs (not hype) and then leverage them effectively by working with the ecosystem rather than against it.
Use this skill when:
framework-utilization instead to focus on integrationframework-utilization for thatExtract 3-5 concrete requirements from project context. Each requirement must be measurable and falsifiable. Vague requirements produce vague technology choices.
Bad (vague): "The app needs to be fast" Good (constrained): "Page load time under 2 seconds on a mid-range mobile device (4G connection) with at least 500ms of JavaScript processing time available."
Bad: "Needs good developer experience" Good: "A new graduate-level engineer should be able to add a CRUD endpoint in under 30 minutes using only official documentation."
Required requirement categories (pick the top 3-5 that apply):
Checkpoint: Each requirement must have a numeric threshold. If you cannot write a test that validates it, the requirement is not yet concrete enough.
Translate each requirement into the specific technical capabilities needed from the technology. This bridges business needs and technical evaluation.
Example mapping for a real-time analytics dashboard:
Requirement: "Dashboard must refresh data every 5 seconds with <500ms latency"
→ Capability: Native WebSocket or Server-Sent Events support
→ Capability: Efficient state management for frequent updates
→ Capability: Data serialization optimized for small, frequent payloads
Requirement: "Team of 3 engineers with React experience, no GraphQL knowledge"
→ Capability: Strong React integration (or built-in frontend framework)
→ Capability: Auto-generated client SDK from backend types
→ Capability: Documentation quality that substitutes for expert training
Checkpoint: Every capability must be verifiable in the framework's documentation or source code. If you cannot confirm it exists, score the candidate lower regardless of its reputation.
For each candidate technology, compute an adoption risk score across four dimensions. Then calculate a weighted fit score against your requirements.
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class Requirement:
name: str
weight: float # 0.0 - 1.0, must sum to 1.0
threshold: str
measurable: bool
@dataclass
class TechnologyCandidate:
name: str
version: str = ""
description: str = ""
@dataclass
class AdoptionRiskScore:
"""Structured risk assessment for adopting a new technology."""
maturity_score: int # 1-5: established vs bleeding edge
team_fit_score: int # 1-5: how well it matches team skills/patterns
ecosystem_health: int # 1-5: active development, community, docs quality
lock_in_risk: int # 5 = low risk (easy to remove), 1 = high risk (deeply coupled)
@property
def average_score(self) -> float:
return (self.maturity_score + self.team_fit_score +
self.ecosystem_health + self.lock_in_risk) / 4.0
@property
def risk_level(self) -> str:
avg = self.average_score
if avg >= 4.5:
return "LOW"
if avg >= 3.5:
return "MODERATE"
if avg >= 2.5:
return "ELEVATED"
return "HIGH"
class TechnologyDecisionEngine:
"""Maps requirements to technology recommendations with risk scoring."""
def __init__(self, requirements: list[Requirement]):
total_weight = sum(r.weight for r in requirements)
if abs(total_weight - 1.0) > 1e-9:
raise ValueError(f"Requirements weights must sum to 1.0, got {total_weight:.4f}")
self.requirements = {r.name: r for r in requirements}
def score_candidate(
self,
candidate: TechnologyCandidate,
capability_scores: dict[str, int], # requirement_name -> 1-10
adoption_risk: AdoptionRiskScore,
) -> dict:
"""Compute weighted fit and return full evaluation for a candidate."""
fit_score = sum(
self.requirements[name].weight * (score / 10)
for name, score in capability_scores.items()
if name in self.requirements
) * 10 # Normalize to 0-10 scale
return {
"candidate": candidate.name,
"version": candidate.version,
"weighted_fit": round(fit_score, 2),
"adoption_risk": adoption_risk.risk_level,
"adoption_risk_score": round(adoption_risk.average_score, 2),
"capability_breakdown": capability_scores,
}
def rank_candidates(self, evaluations: list[dict]) -> list[dict]:
"""Sort candidates by fit score (descending), then risk level."""
risk_order = {"LOW": 0, "MODERATE": 1, "ELEVATED": 2, "HIGH": 3}
return sorted(
evaluations,
key=lambda e: (-e["weighted_fit"], risk_order.get(e["adoption_risk"], 99)),
)
Checkpoint: Cross-validate the decision matrix with at least one team member who was not involved in building it. Discrepancies in scores reveal unclear requirements or biased assumptions.
Every technology recommendation must be backed by evidence that it works in production for similar use cases. This is where reputation meets reality.
Evidence sources to consult (in priority order):
Red flags that should trigger immediate reconsideration:
Technology adoption is a process, not an event. Define explicit milestones and exit criteria at each phase.
Phase 1 — Technical Spike (1-2 weeks):
Phase 2 — Prototype (2-4 weeks):
Phase 3 — Limited Pilot (1-3 months):
Phase 4 — Full Adoption (ongoing):
from dataclasses import dataclass
from datetime import date, timedelta
@dataclass
class RolloutMilestone:
name: str
duration_days: int
exit_criteria: list[str]
rollback_action: str # What to do if criteria are not met
def plan_adoption_rollout(
project_name: str,
technology_name: str,
team_size: int,
criticality: str = "medium", # low | medium | high
) -> list[RolloutMilestone]:
"""Generate a phased rollout plan based on project characteristics."""
timeframes = {
"low": {"spike": 5, "prototype": 10, "pilot": 14},
"medium": {"spike": 7, "prototype": 14, "pilot": 30},
"high": {"spike": 10, "prototype": 21, "pilot": 60},
}
t = timeframes.get(criticality, timeframes["medium"])
return [
RolloutMilestone(
name="Technical Spike",
duration_days=t["spike"],
exit_criteria=[
f"Core technical challenge resolved (documented with code examples)",
"Documentation evaluated and gaps identified",
f"Team of {team_size} engineers can build a minimal working example independently",
],
rollback_action="Revert to previous technology; spike artifacts archived as reference",
),
RolloutMilestone(
name="Prototype",
duration_days=t["prototype"],
exit_criteria=[
"Full deployment pipeline operational (CI/CD, monitoring, logging)",
f"Average development time per feature under 2 hours for team of {team_size}",
"Production error rate below 1% in prototype environment",
],
rollback_action="Discard prototype; conduct post-mortem on adoption blockers",
),
RolloutMilestone(
name="Limited Pilot",
duration_days=t["pilot"],
exit_criteria=[
"Production error rate below 0.5% over full pilot period",
f"Average bug fix time under 4 hours for team of {team_size}",
"At least 80% of engineering team reports neutral or positive experience in survey",
"Monitoring and alerting coverage exceeds 90% of critical paths",
],
rollback_action="Revert pilot feature; document specific issues that prevented successful adoption",
),
]
Every technology has a core set of patterns that deliver disproportionate value. Learning these first prevents wasting time on edge cases. Then identify the ecosystem's extension mechanisms (plugins, middleware, hooks) and evaluate which ones deserve investment.
Framework-specific pattern libraries by category:
Web Frameworks:
- Routing conventions and middleware ordering
- Data validation and serialization patterns
- Authentication/authorization flow (session vs. token-based)
- Error handling middleware and custom error pages
- Database connection pooling and query optimization
Data Processing:
- Pipeline composition and transformation patterns
- Memory management for large datasets (chunking, streaming)
- Parallel processing and distributed execution
- Schema validation and evolution strategies
Infrastructure/DevOps:
- Configuration management (secrets, environments, feature flags)
- Health check patterns and readiness probes
- Graceful shutdown and connection draining
- Observability integration (metrics, tracing, logging format)
Checkpoint: Before committing to any framework-specific pattern, verify it aligns with your team's existing architectural conventions. Fighting the framework's defaults is expensive; working with them delivers compounding returns.
Generates a structured decision document that captures requirements, analysis, and recommendation.
from datetime import date
def generate_tech_decision_document(
project_name: str,
requirements: dict[str, str],
candidates_evaluated: list[dict],
recommended_candidate: str,
reasoning: list[str],
risks: list[str] = None,
reviewers: list[str] = None,
) -> str:
"""Generate a technology decision document suitable for team review and archival."""
lines = [
f"# Technology Decision: {project_name}",
"",
f"**Date:** {date.today().isoformat()} ",
f"**Recommended Technology:** {recommended_candidate} ",
*(f"**Reviewers:** {', '.join(reviewers)}" if reviewers else ""),
"",
"---",
"",
"## Requirements",
]
for name, description in requirements.items():
lines.append(f"- **{name}:** {description}")
lines.extend(["", "## Candidates Evaluated"])
for candidate in candidates_evaluated:
name = candidate["candidate"]
fit = candidate.get("weighted_fit", "N/A")
risk = candidate.get("adoption_risk", "N/A")
version = candidate.get("version", "")
lines.append(f"- `{name}` ({version}) — Fit: {fit}/10, Risk: {risk}")
lines.extend([
"",
"## Recommendation",
f"We recommend adopting **{recommended_candidate}** because:",
])
for reason in reasoning:
lines.append(f"1. {reason}")
if risks:
lines.extend(["", "## Known Risks"])
for risk in risks:
lines.append(f"- {risk}")
lines.extend([
"",
f"**Next Steps:** Proceed to Technical Spike phase with exit criteria defined in rollout plan.",
])
return "\n".join(lines) + "\n"
Checks whether a technology's ecosystem is healthy enough for production use.
import json
def assess_ecosystem_health(
package_name: str,
registry_data: dict, # From npm/PyPI/Cargo/Maven API
github_data: dict = None,
) -> dict:
"""Evaluate ecosystem health from available package metadata and GitHub data."""
score = 0
issues = []
warnings = []
# Check recent activity (last 90 days)
last_published = registry_data.get("last_published", "")
if last_published:
from datetime import datetime, timedelta
last_date = datetime.fromisoformat(last_published.replace("Z", "+00:00"))
days_since = (datetime.now(datetime.UTC) - last_date).days
if days_since <= 30:
score += 25 # Very active
elif days_since <= 90:
score += 15 # Moderately active
elif days_since <= 365:
score += 5 # Slow but still maintained
warnings.append(f"No published update in {days_since} days")
else:
issues.append(f"Package appears abandoned ({days_since} days since last publish)")
# Check download trend (last 4 weeks vs previous 4 weeks)
downloads_current = registry_data.get("downloads_last_4weeks", 0)
downloads_previous = registry_data.get("downloads_previous_4weeks", 0)
if downloads_previous > 0:
growth_rate = (downloads_current - downloads_previous) / downloads_previous
if growth_rate >= 0.10:
score += 25 # Growing ecosystem
elif growth_rate >= 0.0:
score += 15 # Stable
elif growth_rate >= -0.20:
score += 5 # Declining slowly
warnings.append(f"Download volume declining {abs(growth_rate * 100):.0f}%")
else:
issues.append(f"Ecosystem declining rapidly ({abs(growth_rate * 100):.0f}% drop)")
if github_data:
# Check contributor diversity (bus factor proxy)
contributors = github_data.get("total_contributors", 0)
recent_commits_90d = github_data.get("commits_last_90_days", 0)
if contributors >= 10:
score += 25 # Healthy contributor base
elif contributors >= 3:
score += 15 # Moderate
warnings.append(f"Only {contributors} contributors — bus factor risk")
else:
issues.append(f"Single-maintainer risk with only {contributors} contributors")
if recent_commits_90d > 20:
score += 25
elif recent_commits_90d > 5:
score += 15
else:
warnings.append(f"Low commit activity: {recent_commits_90d} commits in 90 days")
return {
"package": package_name,
"health_score": min(100, score),
"issues": issues,
"warnings": warnings,
"verdict": (
"ADOPT" if not issues and len(warnings) <= 1 else
"ADOPT_WITH_CAUTION" if not issues else
"HIGH_RISK"
),
}
When this skill is active, produce:
| Skill | Purpose |
|---|---|
framework-selection | Structured weighted scoring methodology used within this skill's decision matrix step |
framework-utilization | Integration patterns for leveraging a selected framework's capabilities in your codebase |
software-architecture | Evaluates architectural patterns that influence which technologies fit the overall system design |
hexagonal-architecture | Designs abstraction layers around adopted technologies to minimize coupling and future migration costs |
Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.
Building a customer-facing API service requiring 5,000 requests/second with <100ms P95 latency. Team of 5 engineers with strong Python experience (Django production history), no Go or Rust background. Budget for managed services is limited. Must ship first version in 8 weeks.
| Requirement | Weight | Measurable Definition |
|---|---|---|
| Performance throughput | 0.25 | Sustained 5,000 req/s with P95 < 100ms on single container |
| Team velocity | 0.20 | Feature development rate matches or exceeds Django baseline |
| Time to production MVP | 0.15 | Working API deployable within 8 weeks from project kickoff |
| Operational simplicity | 0.15 | Can be monitored with basic HTTP metrics and structured logging |
| Ecosystem for domain needs | 0.10 | Rich set of validation, serialization, and authentication packages |
# Example evaluation results from TechnologyDecisionEngine
candidates = [
{
"candidate": "FastAPI",
"version": "0.115+",
"weighted_fit": 8.4,
"adoption_risk": "LOW",
"adoption_risk_score": 4.25,
"capability_breakdown": {
"Performance throughput": 9,
"Team velocity": 7,
"Time to production MVP": 9,
"Operational simplicity": 8,
"Ecosystem for domain needs": 7,
},
},
{
"candidate": "Django REST Framework",
"version": "4.3+",
"weighted_fit": 7.1,
"adoption_risk": "LOW",
"adoption_risk_score": 4.50,
"capability_breakdown": {
"Performance throughput": 6,
"Team velocity": 9,
"Time to production MVP": 8,
"Operational simplicity": 9,
"Ecosystem for domain needs": 9,
},
},
{
"candidate": "Go + Gin",
"version": "1.23+",
"weighted_fit": 7.8,
"adoption_risk": "ELEVATED",
"adoption_risk_score": 2.75,
"capability_breakdown": {
"Performance throughput": 10,
"Team velocity": 4,
"Time to production MVP": 5,
"Operational simplicity": 8,
"Ecosystem for domain needs": 6,
},
},
]
# Ranked by fit score, then risk level:
ranked = TechnologyDecisionEngine.rank_candidates(candidates)
# Result: FastAPI (8.4) > Go/Gin (7.8) > Django REST (7.1)
rollout = plan_adoption_rollout(
project_name="Customer API Service",
technology_name="FastAPI",
team_size=5,
criticality="medium",
)
# Output:
# Phase 1: Technical Spike (7 days)
# - Exit: Core performance challenge resolved with documented code
# - Rollback: Revert to Django REST; archive spike artifacts
# Phase 2: Prototype (14 days)
# - Exit: Full CI/CD pipeline + <1% error rate in prototype
# - Rollback: Post-mortem on adoption blockers
# Phase 3: Limited Pilot (30 days)
# - Exit: <0.5% error rate, <4hr bug fix time, 80% team satisfaction
# - Rollback: Revert pilot feature; document specific issues
Depends() — FastAPI's built-in DI system handles auth, database sessions, and configuration cleanlystructlog or equivalent for production-grade observabilityAvoid premature investment in: advanced WebSocket patterns, custom middleware chains, or the full plugin system — these add complexity without proportional value in a standard API service.