tribunal-kit 4.2.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/.agent/ARCHITECTURE.md +21 -14
  2. package/.agent/agents/swarm-worker-contracts.md +5 -5
  3. package/.agent/agents/ui-ux-auditor.md +292 -0
  4. package/.agent/rules/GEMINI.md +8 -8
  5. package/.agent/scripts/__pycache__/_colors.cpython-311.pyc +0 -0
  6. package/.agent/scripts/__pycache__/_utils.cpython-311.pyc +0 -0
  7. package/.agent/scripts/__pycache__/case_law_manager.cpython-311.pyc +0 -0
  8. package/.agent/scripts/_colors.js +18 -0
  9. package/.agent/scripts/_utils.js +42 -0
  10. package/.agent/scripts/auto_preview.js +197 -0
  11. package/.agent/scripts/bundle_analyzer.js +290 -0
  12. package/.agent/scripts/case_law_manager.js +684 -0
  13. package/.agent/scripts/checklist.js +266 -0
  14. package/.agent/scripts/colors.js +17 -0
  15. package/.agent/scripts/compress_skills.js +141 -0
  16. package/.agent/scripts/consolidate_skills.js +149 -0
  17. package/.agent/scripts/context_broker.js +609 -0
  18. package/.agent/scripts/deep_compress.js +150 -0
  19. package/.agent/scripts/dependency_analyzer.js +272 -0
  20. package/.agent/scripts/graph_builder.js +199 -0
  21. package/.agent/scripts/graph_zoom.js +154 -0
  22. package/.agent/scripts/inner_loop_validator.js +465 -0
  23. package/.agent/scripts/lint_runner.js +187 -0
  24. package/.agent/scripts/minify_context.js +100 -0
  25. package/.agent/scripts/patch_skills_meta.js +156 -0
  26. package/.agent/scripts/patch_skills_output.js +244 -0
  27. package/.agent/scripts/schema_validator.js +297 -0
  28. package/.agent/scripts/security_scan.js +303 -0
  29. package/.agent/scripts/session_manager.js +276 -0
  30. package/.agent/scripts/skill_evolution.js +644 -0
  31. package/.agent/scripts/skill_integrator.js +313 -0
  32. package/.agent/scripts/strengthen_skills.js +193 -0
  33. package/.agent/scripts/strip_tribunal.js +47 -0
  34. package/.agent/scripts/swarm_dispatcher.js +360 -0
  35. package/.agent/scripts/test_runner.js +193 -0
  36. package/.agent/scripts/utils.js +32 -0
  37. package/.agent/scripts/verify_all.js +256 -0
  38. package/.agent/skills/agent-organizer/SKILL.md +12 -4
  39. package/.agent/skills/agentic-patterns/SKILL.md +12 -4
  40. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +12 -4
  41. package/.agent/skills/api-patterns/SKILL.md +209 -201
  42. package/.agent/skills/api-security-auditor/SKILL.md +12 -4
  43. package/.agent/skills/app-builder/SKILL.md +12 -4
  44. package/.agent/skills/app-builder/templates/SKILL.md +76 -68
  45. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +1 -1
  46. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
  47. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +1 -1
  48. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
  49. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +1 -1
  50. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +1 -1
  51. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +1 -1
  52. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +1 -1
  53. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +1 -1
  54. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +1 -1
  55. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +1 -1
  56. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +1 -1
  57. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +1 -1
  58. package/.agent/skills/appflow-wireframe/SKILL.md +12 -4
  59. package/.agent/skills/architecture/SKILL.md +12 -4
  60. package/.agent/skills/authentication-best-practices/SKILL.md +12 -4
  61. package/.agent/skills/bash-linux/SKILL.md +12 -4
  62. package/.agent/skills/behavioral-modes/SKILL.md +12 -4
  63. package/.agent/skills/brainstorming/SKILL.md +12 -4
  64. package/.agent/skills/building-native-ui/SKILL.md +12 -4
  65. package/.agent/skills/clean-code/SKILL.md +12 -4
  66. package/.agent/skills/code-review-checklist/SKILL.md +12 -4
  67. package/.agent/skills/config-validator/SKILL.md +12 -4
  68. package/.agent/skills/csharp-developer/SKILL.md +12 -4
  69. package/.agent/skills/data-validation-schemas/SKILL.md +290 -282
  70. package/.agent/skills/database-design/SKILL.md +202 -194
  71. package/.agent/skills/deployment-procedures/SKILL.md +12 -4
  72. package/.agent/skills/devops-engineer/SKILL.md +12 -4
  73. package/.agent/skills/devops-incident-responder/SKILL.md +12 -4
  74. package/.agent/skills/doc.md +1 -1
  75. package/.agent/skills/documentation-templates/SKILL.md +12 -4
  76. package/.agent/skills/edge-computing/SKILL.md +12 -4
  77. package/.agent/skills/error-resilience/SKILL.md +390 -382
  78. package/.agent/skills/extract-design-system/SKILL.md +12 -4
  79. package/.agent/skills/framer-motion-expert/SKILL.md +206 -199
  80. package/.agent/skills/frontend-design/SKILL.md +163 -155
  81. package/.agent/skills/game-design-expert/SKILL.md +12 -4
  82. package/.agent/skills/game-engineering-expert/SKILL.md +12 -4
  83. package/.agent/skills/geo-fundamentals/SKILL.md +12 -4
  84. package/.agent/skills/github-operations/SKILL.md +12 -4
  85. package/.agent/skills/gsap-core/SKILL.md +54 -48
  86. package/.agent/skills/gsap-frameworks/SKILL.md +54 -48
  87. package/.agent/skills/gsap-performance/SKILL.md +54 -48
  88. package/.agent/skills/gsap-plugins/SKILL.md +54 -48
  89. package/.agent/skills/gsap-react/SKILL.md +54 -48
  90. package/.agent/skills/gsap-scrolltrigger/SKILL.md +54 -48
  91. package/.agent/skills/gsap-timeline/SKILL.md +54 -48
  92. package/.agent/skills/gsap-utils/SKILL.md +54 -48
  93. package/.agent/skills/i18n-localization/SKILL.md +12 -4
  94. package/.agent/skills/intelligent-routing/SKILL.md +41 -33
  95. package/.agent/skills/knowledge-graph/SKILL.md +36 -0
  96. package/.agent/skills/lint-and-validate/SKILL.md +12 -4
  97. package/.agent/skills/llm-engineering/SKILL.md +12 -4
  98. package/.agent/skills/local-first/SKILL.md +12 -4
  99. package/.agent/skills/mcp-builder/SKILL.md +12 -4
  100. package/.agent/skills/mobile-design/SKILL.md +225 -217
  101. package/.agent/skills/monorepo-management/SKILL.md +296 -288
  102. package/.agent/skills/motion-engineering/SKILL.md +195 -187
  103. package/.agent/skills/nextjs-react-expert/SKILL.md +196 -188
  104. package/.agent/skills/nodejs-best-practices/SKILL.md +12 -4
  105. package/.agent/skills/observability/SKILL.md +12 -4
  106. package/.agent/skills/parallel-agents/SKILL.md +12 -4
  107. package/.agent/skills/performance-profiling/SKILL.md +12 -4
  108. package/.agent/skills/plan-writing/SKILL.md +12 -4
  109. package/.agent/skills/platform-engineer/SKILL.md +12 -4
  110. package/.agent/skills/playwright-best-practices/SKILL.md +12 -4
  111. package/.agent/skills/powershell-windows/SKILL.md +12 -4
  112. package/.agent/skills/project-idioms/SKILL.md +12 -4
  113. package/.agent/skills/python-patterns/SKILL.md +12 -4
  114. package/.agent/skills/python-pro/SKILL.md +285 -277
  115. package/.agent/skills/react-specialist/SKILL.md +239 -231
  116. package/.agent/skills/readme-builder/SKILL.md +12 -4
  117. package/.agent/skills/realtime-patterns/SKILL.md +12 -4
  118. package/.agent/skills/red-team-tactics/SKILL.md +12 -4
  119. package/.agent/skills/rust-pro/SKILL.md +12 -4
  120. package/.agent/skills/seo-fundamentals/SKILL.md +12 -4
  121. package/.agent/skills/server-management/SKILL.md +12 -4
  122. package/.agent/skills/shadcn-ui-expert/SKILL.md +12 -4
  123. package/.agent/skills/skill-creator/SKILL.md +12 -4
  124. package/.agent/skills/sql-pro/SKILL.md +12 -4
  125. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +12 -4
  126. package/.agent/skills/swiftui-expert/SKILL.md +12 -4
  127. package/.agent/skills/systematic-debugging/SKILL.md +12 -4
  128. package/.agent/skills/tailwind-patterns/SKILL.md +12 -4
  129. package/.agent/skills/tdd-workflow/SKILL.md +12 -4
  130. package/.agent/skills/test-result-analyzer/SKILL.md +12 -4
  131. package/.agent/skills/testing-patterns/SKILL.md +12 -4
  132. package/.agent/skills/trend-researcher/SKILL.md +12 -4
  133. package/.agent/skills/typescript-advanced/SKILL.md +297 -289
  134. package/.agent/skills/ui-ux-pro-max/SKILL.md +12 -4
  135. package/.agent/skills/ui-ux-researcher/SKILL.md +12 -4
  136. package/.agent/skills/vue-expert/SKILL.md +237 -229
  137. package/.agent/skills/vulnerability-scanner/SKILL.md +12 -4
  138. package/.agent/skills/web-accessibility-auditor/SKILL.md +12 -4
  139. package/.agent/skills/web-design-guidelines/SKILL.md +12 -4
  140. package/.agent/skills/webapp-testing/SKILL.md +12 -4
  141. package/.agent/skills/whimsy-injector/SKILL.md +12 -4
  142. package/.agent/skills/workflow-optimizer/SKILL.md +12 -4
  143. package/.agent/workflows/audit.md +6 -6
  144. package/.agent/workflows/deploy.md +1 -1
  145. package/.agent/workflows/generate.md +23 -6
  146. package/.agent/workflows/session.md +5 -5
  147. package/.agent/workflows/swarm.md +2 -2
  148. package/README.md +242 -186
  149. package/bin/tribunal-kit.js +297 -57
  150. package/package.json +81 -77
  151. package/scripts/changelog.js +167 -0
  152. package/scripts/sync-version.js +81 -0
  153. package/scripts/validate-payload.js +73 -0
  154. package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
  155. package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
  156. package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
  157. package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
  158. package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
  159. package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
  160. package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
  161. package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
  162. package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
  163. package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
  164. package/.agent/scripts/auto_preview.py +0 -180
  165. package/.agent/scripts/bundle_analyzer.py +0 -259
  166. package/.agent/scripts/case_law_manager.py +0 -755
  167. package/.agent/scripts/checklist.py +0 -209
  168. package/.agent/scripts/compress_skills.py +0 -167
  169. package/.agent/scripts/consolidate_skills.py +0 -173
  170. package/.agent/scripts/deep_compress.py +0 -202
  171. package/.agent/scripts/dependency_analyzer.py +0 -247
  172. package/.agent/scripts/lint_runner.py +0 -188
  173. package/.agent/scripts/minify_context.py +0 -80
  174. package/.agent/scripts/patch_skills_meta.py +0 -177
  175. package/.agent/scripts/patch_skills_output.py +0 -285
  176. package/.agent/scripts/schema_validator.py +0 -279
  177. package/.agent/scripts/security_scan.py +0 -224
  178. package/.agent/scripts/session_manager.py +0 -261
  179. package/.agent/scripts/skill_evolution.py +0 -563
  180. package/.agent/scripts/skill_integrator.py +0 -234
  181. package/.agent/scripts/strengthen_skills.py +0 -220
  182. package/.agent/scripts/strip_tribunal.py +0 -41
  183. package/.agent/scripts/swarm_dispatcher.py +0 -350
  184. package/.agent/scripts/test_runner.py +0 -192
  185. package/.agent/scripts/test_swarm_dispatcher.py +0 -163
  186. package/.agent/scripts/verify_all.py +0 -195
@@ -1,281 +1,281 @@
1
- ---
2
- name: python-pro
3
- description: Python 3.12+ specialist. FastAPI, Pydantic v2, asyncio, modern types, pytest. Use when building Python APIs, data pipelines, automation, or any Python code.
4
- allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 3.1.0
6
- last-updated: 2026-04-06
7
- ---
8
-
9
- # Python 3.12+ — Dense Reference
10
-
11
- ## Hallucination Traps (Read First)
12
- - ❌ `from typing import List, Dict, Optional, Union` → ✅ `list[str]`, `dict[k,v]`, `X | None`, `X | Y` (Python 3.10+)
13
- - ❌ `user.dict()` / `user.json()` / `UserCreate.parse_obj()` → ✅ Pydantic v2: `model_dump()`, `model_dump_json()`, `model_validate()`
14
- - ❌ Pydantic `class Config: orm_mode = True` → ✅ `model_config = {"from_attributes": True}`
15
- - ❌ `@validator` / `@root_validator` → ✅ `@field_validator` / `@model_validator`
16
- - ❌ `@app.on_event("startup")` → ✅ `lifespan` context manager (deprecated)
17
- - ❌ `import requests` in async code → ✅ `httpx.AsyncClient()` (requests BLOCKS the event loop)
18
- - ❌ `asyncio.run()` inside running loop → ✅ `await` directly or use `loop.create_task()`
19
- - ❌ `except Exception as e: pass` → ✅ always log or re-raise
20
-
21
- ---
22
-
23
- ## Type System (3.12+)
24
-
25
- ```python
26
- # Built-in generics (3.9+) — no typing imports needed for basic types
27
- def process(items: list[str]) -> dict[str, int]: ...
28
- def find(user_id: int) -> User | None: ... # 3.10+ union
29
- def parse(raw: str) -> int | float | None: ...
30
-
31
- # Generic syntax (3.12+)
32
- def first[T](items: list[T]) -> T | None:
33
- return items[0] if items else None
34
- type Point = tuple[float, float] # 3.12+ type alias
35
-
36
- # Protocol (structural typing — duck typing with types)
37
- from typing import Protocol, runtime_checkable
38
- @runtime_checkable
39
- class Renderable(Protocol):
40
- def render(self) -> str: ...
41
-
42
- # TypedDict — typed dict with optional keys
43
- from typing import TypedDict, NotRequired
44
- class UserPayload(TypedDict):
45
- name: str; email: str
46
- age: NotRequired[int] # optional key
47
-
48
- # ParamSpec — preserve signatures in decorators
49
- from typing import TypeVar, ParamSpec
50
- from collections.abc import Callable
51
- T = TypeVar("T"); P = ParamSpec("P")
52
- def with_logging(func: Callable[P, T]) -> Callable[P, T]:
53
- def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
54
- result = func(*args, **kwargs)
55
- return result
56
- return wrapper
57
- ```
58
-
59
- ---
60
-
61
- ## Pydantic v2
62
-
63
- ```python
64
- from pydantic import BaseModel, Field, field_validator, model_validator
65
- from enum import Enum
66
-
67
- class Role(str, Enum):
68
- ADMIN = "admin"; USER = "user"
69
-
70
- class UserCreate(BaseModel):
71
- name: str = Field(..., min_length=2, max_length=100)
72
- email: str = Field(..., pattern=r"^[\w.-]+@[\w.-]+\.\w+$")
73
- age: int = Field(..., ge=13, le=120)
74
- role: Role = Role.USER
75
- tags: list[str] = Field(default_factory=list)
76
-
77
- @field_validator("name")
78
- @classmethod
79
- def name_titlecase(cls, v: str) -> str:
80
- if not v[0].isupper(): raise ValueError("Name must start with uppercase")
81
- return v.strip()
82
-
83
- @model_validator(mode="after")
84
- def check_admin_age(self) -> "UserCreate":
85
- if self.role == Role.ADMIN and self.age < 18:
86
- raise ValueError("Admins must be 18+")
87
- return self
88
-
89
- class UserResponse(BaseModel):
90
- id: int; name: str; email: str
91
- model_config = {"from_attributes": True} # ORM mode (was orm_mode=True in v1)
92
-
93
- # Serialization
94
- user.model_dump() # ✅ (was .dict())
95
- user.model_dump_json() # ✅ (was .json())
96
- user.model_dump(exclude={"password"}, mode="json")
97
- UserCreate.model_validate({"name": "Alice", "email": "a@b.com", "age": 30}) # ✅ (was parse_obj)
98
- UserCreate.model_validate_json('{"name": "Bob", ...}')
99
- ```
100
-
101
- ---
102
-
103
- ## FastAPI
104
-
105
- ```python
106
- from fastapi import FastAPI, HTTPException, Depends, Query, Path, status
107
- from contextlib import asynccontextmanager
108
-
109
- @asynccontextmanager
110
- async def lifespan(app: FastAPI):
111
- await init_db(); await redis.connect() # startup
112
- yield
113
- await redis.close() # shutdown
114
-
115
- app = FastAPI(title="My API", version="1.0.0", lifespan=lifespan)
116
-
117
- # CORS — never "*" in production
118
- from fastapi.middleware.cors import CORSMiddleware
119
- app.add_middleware(CORSMiddleware,
120
- allow_origins=["https://myapp.com"], # ❌ NEVER ["*"]
121
- allow_credentials=True, allow_methods=["GET","POST","PUT","DELETE"], allow_headers=["*"])
122
-
123
- # Routes
124
- @app.get("/users", response_model=list[UserResponse])
125
- async def list_users(skip: int = Query(0, ge=0), limit: int = Query(20, le=100)) -> list[UserResponse]:
126
- return await db.execute(select(User).offset(skip).limit(limit))
127
-
128
- @app.post("/users", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
129
- async def create_user(payload: UserCreate) -> UserResponse:
130
- user = User(**payload.model_dump())
131
- db.add(user); await db.commit(); await db.refresh(user)
132
- return user
133
-
134
- # Dependency Injection
135
- async def get_db() -> AsyncGenerator[AsyncSession, None]:
136
- async with async_session() as session:
137
- try: yield session
138
- finally: await session.close()
139
-
140
- async def get_current_user(token: str = Depends(oauth2_scheme), db: AsyncSession = Depends(get_db)) -> User:
141
- payload = decode_jwt(token)
142
- user = await db.get(User, payload["sub"])
143
- if not user: raise HTTPException(status_code=401, detail="Invalid credentials")
144
- return user
145
-
146
- def require_role(role: Role):
147
- async def checker(user: User = Depends(get_current_user)) -> User:
148
- if user.role != role: raise HTTPException(status_code=403, detail="Forbidden")
149
- return user
150
- return checker
151
-
152
- # Background Tasks
153
- from fastapi import BackgroundTasks
154
- @app.post("/orders")
155
- async def create_order(order: OrderCreate, bg: BackgroundTasks) -> OrderResponse:
156
- result = await save_order(order)
157
- bg.add_task(send_email, result.email)
158
- return result
159
-
160
- # Exception handlers
161
- from fastapi.responses import JSONResponse
162
- @app.exception_handler(AppError)
163
- async def app_error(request: Request, exc: AppError) -> JSONResponse:
164
- return JSONResponse(status_code=exc.status_code, content={"error": exc.message})
165
- ```
166
-
167
- ---
168
-
169
- ## Async Patterns
170
-
171
- ```python
172
- import asyncio, httpx
173
-
174
- # Parallel calls — await all simultaneously
175
- async def fetch_all() -> tuple:
176
- async with httpx.AsyncClient() as client:
177
- users, posts = await asyncio.gather(
178
- client.get("/users"), client.get("/posts")
179
- )
180
- return users.json(), posts.json()
181
-
182
- # Timeout
183
- async with asyncio.timeout(5.0): # 3.11+ (was asyncio.wait_for)
184
- result = await slow_operation()
185
-
186
- # Semaphore — limit concurrent ops
187
- sem = asyncio.Semaphore(10)
188
- async def limited_fetch(url: str) -> dict:
189
- async with sem:
190
- async with httpx.AsyncClient() as client:
191
- return (await client.get(url)).json()
192
-
193
- # Producer-Consumer
194
- async def producer(q: asyncio.Queue[str]):
195
- for item in data: await q.put(item)
196
- await q.put(None) # sentinel
197
-
198
- async def consumer(q: asyncio.Queue[str]):
199
- while (item := await q.get()) is not None:
200
- await process(item)
201
- q.task_done()
202
- ```
203
-
204
- ---
205
-
206
- ## Error Handling
207
-
208
- ```python
209
- # NEVER silently swallow exceptions
210
- try: result = await risky_op()
211
- except SpecificError as e: logger.error("Failed: %s", e); raise
212
- except Exception: logger.exception("Unexpected"); raise
213
-
214
- # Custom exceptions with context
215
- class ServiceError(Exception):
216
- def __init__(self, msg: str, code: int = 500, context: dict | None = None):
217
- super().__init__(msg)
218
- self.code = code; self.context = context or {}
219
-
220
- # Context managers for cleanup
221
- from contextlib import asynccontextmanager
222
- @asynccontextmanager
223
- async def managed_connection():
224
- conn = await db.connect()
225
- try: yield conn
226
- finally: await conn.close()
227
- ```
228
-
229
- ---
230
-
231
- ## Testing (pytest)
232
-
233
- ```python
234
- import pytest
235
- from httpx import AsyncClient, ASGITransport
236
-
237
- @pytest.fixture
238
- async def client():
239
- async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as c:
240
- yield c
241
-
242
- @pytest.mark.anyio
243
- async def test_create_user(client: AsyncClient):
244
- r = await client.post("/users", json={"name": "Alice", "email": "a@b.com", "age": 25})
245
- assert r.status_code == 201
246
- assert r.json()["name"] == "Alice"
247
-
248
- # Fixtures with factories (avoid fixtures that return complex data directly)
249
- @pytest.fixture
250
- def make_user(db_session):
251
- async def _make(name="Alice", role="user"):
252
- return await User.create(db=db_session, name=name, role=role)
253
- return _make
254
- ```
255
-
256
- ---
257
-
258
- ## Project Structure
259
-
260
- ```
261
- my-api/
262
- ├── app/
263
- │ ├── main.py # FastAPI app + lifespan
264
- │ ├── models/ # SQLAlchemy ORM models
265
- │ ├── schemas/ # Pydantic request/response models
266
- │ ├── routers/ # APIRouter groups
267
- │ ├── services/ # Business logic (no FastAPI imports)
268
- │ ├── dependencies.py # Shared Depends() callables
269
- │ └── config.py # Settings via pydantic-settings
270
- ├── tests/
271
- ├── alembic/ # Migrations
272
- └── pyproject.toml
273
- ```
1
+ ---
2
+ name: python-pro
3
+ description: Python 3.12+ specialist. FastAPI, Pydantic v2, asyncio, modern types, pytest. Use when building Python APIs, data pipelines, automation, or any Python code.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep
5
+ version: 3.1.0
6
+ last-updated: 2026-04-06
7
+ ---
8
+
9
+ # Python 3.12+ — Dense Reference
10
+
11
+ ## Hallucination Traps (Read First)
12
+ - ❌ `from typing import List, Dict, Optional, Union` → ✅ `list[str]`, `dict[k,v]`, `X | None`, `X | Y` (Python 3.10+)
13
+ - ❌ `user.dict()` / `user.json()` / `UserCreate.parse_obj()` → ✅ Pydantic v2: `model_dump()`, `model_dump_json()`, `model_validate()`
14
+ - ❌ Pydantic `class Config: orm_mode = True` → ✅ `model_config = {"from_attributes": True}`
15
+ - ❌ `@validator` / `@root_validator` → ✅ `@field_validator` / `@model_validator`
16
+ - ❌ `@app.on_event("startup")` → ✅ `lifespan` context manager (deprecated)
17
+ - ❌ `import requests` in async code → ✅ `httpx.AsyncClient()` (requests BLOCKS the event loop)
18
+ - ❌ `asyncio.run()` inside running loop → ✅ `await` directly or use `loop.create_task()`
19
+ - ❌ `except Exception as e: pass` → ✅ always log or re-raise
20
+
21
+ ---
22
+
23
+ ## Type System (3.12+)
24
+
25
+ ```python
26
+ # Built-in generics (3.9+) — no typing imports needed for basic types
27
+ def process(items: list[str]) -> dict[str, int]: ...
28
+ def find(user_id: int) -> User | None: ... # 3.10+ union
29
+ def parse(raw: str) -> int | float | None: ...
30
+
31
+ # Generic syntax (3.12+)
32
+ def first[T](items: list[T]) -> T | None:
33
+ return items[0] if items else None
34
+ type Point = tuple[float, float] # 3.12+ type alias
35
+
36
+ # Protocol (structural typing — duck typing with types)
37
+ from typing import Protocol, runtime_checkable
38
+ @runtime_checkable
39
+ class Renderable(Protocol):
40
+ def render(self) -> str: ...
41
+
42
+ # TypedDict — typed dict with optional keys
43
+ from typing import TypedDict, NotRequired
44
+ class UserPayload(TypedDict):
45
+ name: str; email: str
46
+ age: NotRequired[int] # optional key
47
+
48
+ # ParamSpec — preserve signatures in decorators
49
+ from typing import TypeVar, ParamSpec
50
+ from collections.abc import Callable
51
+ T = TypeVar("T"); P = ParamSpec("P")
52
+ def with_logging(func: Callable[P, T]) -> Callable[P, T]:
53
+ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
54
+ result = func(*args, **kwargs)
55
+ return result
56
+ return wrapper
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Pydantic v2
62
+
63
+ ```python
64
+ from pydantic import BaseModel, Field, field_validator, model_validator
65
+ from enum import Enum
66
+
67
+ class Role(str, Enum):
68
+ ADMIN = "admin"; USER = "user"
69
+
70
+ class UserCreate(BaseModel):
71
+ name: str = Field(..., min_length=2, max_length=100)
72
+ email: str = Field(..., pattern=r"^[\w.-]+@[\w.-]+\.\w+$")
73
+ age: int = Field(..., ge=13, le=120)
74
+ role: Role = Role.USER
75
+ tags: list[str] = Field(default_factory=list)
76
+
77
+ @field_validator("name")
78
+ @classmethod
79
+ def name_titlecase(cls, v: str) -> str:
80
+ if not v[0].isupper(): raise ValueError("Name must start with uppercase")
81
+ return v.strip()
82
+
83
+ @model_validator(mode="after")
84
+ def check_admin_age(self) -> "UserCreate":
85
+ if self.role == Role.ADMIN and self.age < 18:
86
+ raise ValueError("Admins must be 18+")
87
+ return self
88
+
89
+ class UserResponse(BaseModel):
90
+ id: int; name: str; email: str
91
+ model_config = {"from_attributes": True} # ORM mode (was orm_mode=True in v1)
92
+
93
+ # Serialization
94
+ user.model_dump() # ✅ (was .dict())
95
+ user.model_dump_json() # ✅ (was .json())
96
+ user.model_dump(exclude={"password"}, mode="json")
97
+ UserCreate.model_validate({"name": "Alice", "email": "a@b.com", "age": 30}) # ✅ (was parse_obj)
98
+ UserCreate.model_validate_json('{"name": "Bob", ...}')
99
+ ```
100
+
101
+ ---
102
+
103
+ ## FastAPI
104
+
105
+ ```python
106
+ from fastapi import FastAPI, HTTPException, Depends, Query, Path, status
107
+ from contextlib import asynccontextmanager
108
+
109
+ @asynccontextmanager
110
+ async def lifespan(app: FastAPI):
111
+ await init_db(); await redis.connect() # startup
112
+ yield
113
+ await redis.close() # shutdown
114
+
115
+ app = FastAPI(title="My API", version="1.0.0", lifespan=lifespan)
116
+
117
+ # CORS — never "*" in production
118
+ from fastapi.middleware.cors import CORSMiddleware
119
+ app.add_middleware(CORSMiddleware,
120
+ allow_origins=["https://myapp.com"], # ❌ NEVER ["*"]
121
+ allow_credentials=True, allow_methods=["GET","POST","PUT","DELETE"], allow_headers=["*"])
122
+
123
+ # Routes
124
+ @app.get("/users", response_model=list[UserResponse])
125
+ async def list_users(skip: int = Query(0, ge=0), limit: int = Query(20, le=100)) -> list[UserResponse]:
126
+ return await db.execute(select(User).offset(skip).limit(limit))
127
+
128
+ @app.post("/users", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
129
+ async def create_user(payload: UserCreate) -> UserResponse:
130
+ user = User(**payload.model_dump())
131
+ db.add(user); await db.commit(); await db.refresh(user)
132
+ return user
133
+
134
+ # Dependency Injection
135
+ async def get_db() -> AsyncGenerator[AsyncSession, None]:
136
+ async with async_session() as session:
137
+ try: yield session
138
+ finally: await session.close()
139
+
140
+ async def get_current_user(token: str = Depends(oauth2_scheme), db: AsyncSession = Depends(get_db)) -> User:
141
+ payload = decode_jwt(token)
142
+ user = await db.get(User, payload["sub"])
143
+ if not user: raise HTTPException(status_code=401, detail="Invalid credentials")
144
+ return user
145
+
146
+ def require_role(role: Role):
147
+ async def checker(user: User = Depends(get_current_user)) -> User:
148
+ if user.role != role: raise HTTPException(status_code=403, detail="Forbidden")
149
+ return user
150
+ return checker
151
+
152
+ # Background Tasks
153
+ from fastapi import BackgroundTasks
154
+ @app.post("/orders")
155
+ async def create_order(order: OrderCreate, bg: BackgroundTasks) -> OrderResponse:
156
+ result = await save_order(order)
157
+ bg.add_task(send_email, result.email)
158
+ return result
159
+
160
+ # Exception handlers
161
+ from fastapi.responses import JSONResponse
162
+ @app.exception_handler(AppError)
163
+ async def app_error(request: Request, exc: AppError) -> JSONResponse:
164
+ return JSONResponse(status_code=exc.status_code, content={"error": exc.message})
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Async Patterns
170
+
171
+ ```python
172
+ import asyncio, httpx
173
+
174
+ # Parallel calls — await all simultaneously
175
+ async def fetch_all() -> tuple:
176
+ async with httpx.AsyncClient() as client:
177
+ users, posts = await asyncio.gather(
178
+ client.get("/users"), client.get("/posts")
179
+ )
180
+ return users.json(), posts.json()
181
+
182
+ # Timeout
183
+ async with asyncio.timeout(5.0): # 3.11+ (was asyncio.wait_for)
184
+ result = await slow_operation()
185
+
186
+ # Semaphore — limit concurrent ops
187
+ sem = asyncio.Semaphore(10)
188
+ async def limited_fetch(url: str) -> dict:
189
+ async with sem:
190
+ async with httpx.AsyncClient() as client:
191
+ return (await client.get(url)).json()
192
+
193
+ # Producer-Consumer
194
+ async def producer(q: asyncio.Queue[str]):
195
+ for item in data: await q.put(item)
196
+ await q.put(None) # sentinel
197
+
198
+ async def consumer(q: asyncio.Queue[str]):
199
+ while (item := await q.get()) is not None:
200
+ await process(item)
201
+ q.task_done()
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Error Handling
207
+
208
+ ```python
209
+ # NEVER silently swallow exceptions
210
+ try: result = await risky_op()
211
+ except SpecificError as e: logger.error("Failed: %s", e); raise
212
+ except Exception: logger.exception("Unexpected"); raise
213
+
214
+ # Custom exceptions with context
215
+ class ServiceError(Exception):
216
+ def __init__(self, msg: str, code: int = 500, context: dict | None = None):
217
+ super().__init__(msg)
218
+ self.code = code; self.context = context or {}
219
+
220
+ # Context managers for cleanup
221
+ from contextlib import asynccontextmanager
222
+ @asynccontextmanager
223
+ async def managed_connection():
224
+ conn = await db.connect()
225
+ try: yield conn
226
+ finally: await conn.close()
227
+ ```
228
+
229
+ ---
230
+
231
+ ## Testing (pytest)
232
+
233
+ ```python
234
+ import pytest
235
+ from httpx import AsyncClient, ASGITransport
236
+
237
+ @pytest.fixture
238
+ async def client():
239
+ async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as c:
240
+ yield c
241
+
242
+ @pytest.mark.anyio
243
+ async def test_create_user(client: AsyncClient):
244
+ r = await client.post("/users", json={"name": "Alice", "email": "a@b.com", "age": 25})
245
+ assert r.status_code == 201
246
+ assert r.json()["name"] == "Alice"
274
247
 
248
+ # Fixtures with factories (avoid fixtures that return complex data directly)
249
+ @pytest.fixture
250
+ def make_user(db_session):
251
+ async def _make(name="Alice", role="user"):
252
+ return await User.create(db=db_session, name=name, role=role)
253
+ return _make
254
+ ```
275
255
 
276
256
  ---
277
257
 
278
- ## 🤖 LLM-Specific Traps
258
+ ## Project Structure
259
+
260
+ ```
261
+ my-api/
262
+ ├── app/
263
+ │ ├── main.py # FastAPI app + lifespan
264
+ │ ├── models/ # SQLAlchemy ORM models
265
+ │ ├── schemas/ # Pydantic request/response models
266
+ │ ├── routers/ # APIRouter groups
267
+ │ ├── services/ # Business logic (no FastAPI imports)
268
+ │ ├── dependencies.py # Shared Depends() callables
269
+ │ └── config.py # Settings via pydantic-settings
270
+ ├── tests/
271
+ ├── alembic/ # Migrations
272
+ └── pyproject.toml
273
+ ```
274
+
275
+
276
+ ---
277
+
278
+
279
279
 
280
280
  AI coding assistants often fall into specific bad habits when dealing with this domain. These are strictly forbidden:
281
281
 
@@ -287,7 +287,7 @@ AI coding assistants often fall into specific bad habits when dealing with this
287
287
 
288
288
  ---
289
289
 
290
- ## 🏛️ Tribunal Integration (Anti-Hallucination)
290
+
291
291
 
292
292
  **Slash command: `/review` or `/tribunal-full`**
293
293
  **Active reviewers: `logic-reviewer` · `security-auditor`**
@@ -298,7 +298,7 @@ AI coding assistants often fall into specific bad habits when dealing with this
298
298
  2. **Silent Degradation:** Catching and suppressing errors without logging or handling.
299
299
  3. **Context Amnesia:** Forgetting the user's constraints and offering generic advice instead of tailored solutions.
300
300
 
301
- ### ✅ Pre-Flight Self-Audit
301
+
302
302
 
303
303
  Review these questions before confirming output:
304
304
  ```
@@ -312,4 +312,12 @@ Review these questions before confirming output:
312
312
 
313
313
  **CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
314
314
  - ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
315
- - ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
315
+ - ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
316
+
317
+
318
+ ## Pre-Flight Checklist
319
+ - [ ] Have I reviewed the user's specific constraints and requests?
320
+ - [ ] Have I checked the environment for relevant existing implementations?
321
+
322
+ ## VBC Protocol (Verification-Before-Completion)
323
+ You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.