Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
repos:
# Code formatting
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.5
rev: v0.16.8
hooks:
- id: ruff
args: [--fix]
Expand All @@ -30,7 +30,7 @@ repos:

# Type checking
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.14.0
rev: v2.3.1
hooks:
- id: mypy
args: [--ignore-missing-imports, --follow-imports=silent]
Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ status: active
# ✅ GOOD — sanitized label, parameterized values, explicit types
from engine.utils.security import sanitize_label


async def query_candidates(driver: GraphDriver, spec: DomainSpec) -> list[dict[str, Any]]:
label = sanitize_label(spec.targetnode)
cypher = f"MATCH (n:{label}) WHERE n.active = $active RETURN n LIMIT $limit"
return await driver.execute_query(cypher, {"active": True, "limit": settings.max_results})


# 🚫 BAD — unsanitized label, hardcoded limit, no type hints
async def query_candidates(driver, spec):
cypher = f"MATCH (n:{spec.targetnode}) WHERE n.active = true RETURN n LIMIT 25"
Expand All @@ -47,6 +49,7 @@ def validate_weights(weights: dict[str, float] | None = None) -> None:
msg = f"Weight sum {sum(weights.values()):.4f} exceeds 1.0 ceiling"
raise ValidationError(msg)


# 🚫 BAD — f-string in raise, implicit Optional, no flag gate
def validate_weights(weights: dict = None):
if weights and sum(weights.values()) > 1.0:
Expand All @@ -57,10 +60,12 @@ def validate_weights(weights: dict = None):
# ✅ GOOD — gate type extends BaseGate, registered in enum
class ProximityGate(BaseGate):
"""Gate that filters by graph distance."""

def compile_where(self, spec: GateSpec, domain: DomainSpec) -> str:
field = sanitize_label(spec.candidateprop)
return f"candidate.{field} <= $max_distance"


# 🚫 BAD — standalone function, no BaseGate, no sanitization
def proximity_gate(spec, domain):
return f"candidate.{spec.candidateprop} <= {spec.threshold}"
Expand Down
1 change: 1 addition & 0 deletions GUARDRAILS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ The following are **absolutely prohibited** throughout the codebase:
```python
# ✅ REQUIRED
from cachetools import TTLCache

_cache: TTLCache = TTLCache(maxsize=1000, ttl=300)

# 🚫 FORBIDDEN
Expand Down
10 changes: 7 additions & 3 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ def test_proximity_gate_compiles_sanitized_label():
domain = make_domain_spec(targetnode="Contact")
gate = ProximityGate()
clause = gate.compile_where(spec, domain)
assert "$max_distance" in clause # parameterized
assert "Contact" not in clause # label not in WHERE
assert "distance" in clause # prop name present
assert "$max_distance" in clause # parameterized
assert "Contact" not in clause # label not in WHERE
assert "distance" in clause # prop name present
```

### Scoring Math Tests
Expand All @@ -69,6 +69,7 @@ def test_lift_formula_clamps_to_bounds():
weight = calc.compute(positive_count=5, total_count=5, base_rate=0.5)
assert 0.1 <= weight <= 2.0


def test_confidence_dampening_reduces_uncertain_weights():
weight_small_sample = calc.compute(positive_count=2, total_count=3, base_rate=0.5)
weight_large_sample = calc.compute(positive_count=200, total_count=300, base_rate=0.5)
Expand Down Expand Up @@ -115,6 +116,7 @@ def test_age_gate_rejected_at_compile_time():
with pytest.raises(ProhibitedFactorError, match="age"):
gate_compiler.compile(spec, domain)


def test_gender_scoring_dimension_blocked():
spec = ScoringDimension(field="gender")
with pytest.raises(ProhibitedFactorError, match="gender"):
Expand Down Expand Up @@ -147,11 +149,13 @@ Contract C-001 through C-024 must all pass before any merge.
# tests/property/test_score_bounds.py
from hypothesis import given, strategies as st


@given(st.floats(min_value=-1000, max_value=1000))
def test_score_always_clamped(raw_score):
result = clamp_score(raw_score)
assert 0.0 <= result <= 1.0


@given(st.dictionaries(st.text(), st.floats(0, 1), min_size=1))
def test_weight_sum_assertion(weights):
assume(sum(weights.values()) <= 1.0)
Expand Down
6 changes: 4 additions & 2 deletions agents/cursor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ class RetrievalSource:
"""Decision engine managing cursor context retrieval order, ensuring cache and memory checks precede repository scans for efficient knowledge access."""

# Key methods:

```

**Lines:** 41-60 in `cursor_retrieval_kernel.py`
Expand Down Expand Up @@ -203,7 +202,6 @@ class AutonomyLevel:
"""Graduated autonomy levels in GMP v2.0."""

# Key methods:

```

**Lines:** 64-70 in `gmp_meta_learning.py`
Expand Down Expand Up @@ -242,15 +240,19 @@ from pydantic import BaseModel
from typing import Optional
from datetime import datetime, timezone


class AgentsCursorRequest(BaseModel):
"""Request model for agents_cursor operations."""

id: str
data: dict
timestamp: datetime
correlation_id: Optional[str] = None


class AgentsCursorResponse(BaseModel):
"""Response model for agents_cursor operations."""

success: bool
result: Optional[dict] = None
error: Optional[str] = None
Expand Down
1 change: 1 addition & 0 deletions agents/cursor/cursor_session_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ async def on_action(
branch: str,
tool_id: str,
args: dict[str, Any],
*,
success: bool = True,
error: str | None = None,
repo_state_hash: str | None = None,
Expand Down
10 changes: 5 additions & 5 deletions agents/cursor/docs/CURSOR-L9-INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ import httpx
from pydantic import BaseModel

# NOT L9 Pattern
import logging # Use structlog instead
import requests # Use httpx instead
import logging # Use structlog instead
import requests # Use httpx instead
```

---
Expand Down Expand Up @@ -215,12 +215,12 @@ When generating code for L9, Cursor MUST follow these patterns from the kernels:

```python
# REQUIRED - Always use these
import structlog # NOT logging
import httpx # NOT requests
import structlog # NOT logging
import httpx # NOT requests
from pydantic import BaseModel # Pydantic v2 (not v1)

# FORBIDDEN - Never use these
import logging # Use structlog instead
import logging # Use structlog instead
import requests # Use httpx instead
```

Expand Down
49 changes: 32 additions & 17 deletions agents/cursor/docs/PRODUCTION-SPEED-PACK.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,21 @@ import logging
router = APIRouter(prefix="/api/v1", tags=["resource"])
logger = logging.getLogger(__name__)


class ResourceCreate(BaseModel):
name: str
description: Optional[str] = None


class ResourceResponse(BaseModel):
id: int
name: str
description: Optional[str]
created_at: str


@router.post("/resources", response_model=ResourceResponse, status_code=201)
async def create_resource(
resource: ResourceCreate,
db = Depends(get_db)
) -> ResourceResponse:
async def create_resource(resource: ResourceCreate, db=Depends(get_db)) -> ResourceResponse:
"""
Create a new resource.

Expand Down Expand Up @@ -209,24 +209,28 @@ def process_order(order):
# Save
db.save(order)


# After
def process_order(order):
validate_order(order)
order.total = calculate_order_total(order)
save_order(order)


def validate_order(order):
if not order.items:
raise ValueError("Empty order")
if order.total < 0:
raise ValueError("Negative total")


def calculate_order_total(order):
TAX_RATE = 0.08
subtotal = sum(item.price * item.quantity for item in order.items)
tax = subtotal * TAX_RATE
return subtotal + tax


def save_order(order):
db.save(order)
```
Expand All @@ -247,27 +251,30 @@ def calculate_shipping(order_type, weight):
elif order_type == "overnight":
return weight * 3.0


# After
class ShippingStrategy:
def calculate(self, weight): pass
def calculate(self, weight):
pass


class StandardShipping(ShippingStrategy):
def calculate(self, weight):
return weight * 0.5


class ExpressShipping(ShippingStrategy):
def calculate(self, weight):
return weight * 1.5


class OvernightShipping(ShippingStrategy):
def calculate(self, weight):
return weight * 3.0

SHIPPING_STRATEGIES = {
"standard": StandardShipping(),
"express": ExpressShipping(),
"overnight": OvernightShipping()
}

SHIPPING_STRATEGIES = {"standard": StandardShipping(), "express": ExpressShipping(), "overnight": OvernightShipping()}


def calculate_shipping(order_type, weight):
strategy = SHIPPING_STRATEGIES.get(order_type)
Expand All @@ -289,10 +296,12 @@ def calculate_discount(total):
return total * 0.1
return 0


# After
DISCOUNT_THRESHOLD = 100
DISCOUNT_RATE = 0.1


def calculate_discount(total):
if total > DISCOUNT_THRESHOLD:
return total * DISCOUNT_RATE
Expand Down Expand Up @@ -334,13 +343,16 @@ for order in orders:
from functools import lru_cache
import redis


# In-memory cache for pure functions
@lru_cache(maxsize=1000)
def expensive_calculation(n: int) -> int:
return sum(i**2 for i in range(n))


# Redis cache for API responses
redis_client = redis.Redis(host='localhost', port=6379)
redis_client = redis.Redis(host="localhost", port=6379)


async def get_user(user_id: int):
cache_key = f"user:{user_id}"
Expand Down Expand Up @@ -409,6 +421,7 @@ from functools import wraps

logger = logging.getLogger(__name__)


def log_execution(func):
@wraps(func)
async def wrapper(*args, **kwargs):
Expand All @@ -420,8 +433,10 @@ def log_execution(func):
except Exception as e:
logger.error(f"{func.__name__} failed: {e}", exc_info=True)
raise

return wrapper


@log_execution
async def process_payment(order_id: int, amount: float):
# Implementation
Expand All @@ -440,12 +455,8 @@ class PaymentError(Exception):
super().__init__(self.message)

def to_dict(self):
return {
"error": self.message,
"order_id": self.order_id,
"amount": self.amount,
"provider": self.provider
}
return {"error": self.message, "order_id": self.order_id, "amount": self.amount, "provider": self.provider}


try:
process_payment(order_id, amount, provider)
Expand All @@ -464,18 +475,21 @@ except PaymentError as e:
# Bad: Race condition
counter = 0


async def increment():
global counter
temp = counter
await asyncio.sleep(0.001)
counter = temp + 1


# Good: Thread-safe
import asyncio

counter_lock = asyncio.Lock()
counter = 0


async def increment():
global counter
async with counter_lock:
Expand All @@ -493,6 +507,7 @@ class DataProcessor:
def add_listener(self, listener):
self.listeners.append(listener)


# Good: Cleanup
class DataProcessor:
def __init__(self):
Expand Down
Loading
Loading