# Agent Rules **These rules are MANDATORY and MUST be followed without exception by all agents working on this codebase.** --- ## 1. Entity Versioning MUST Be Automatic > [!CAUTION] > **NON-NEGOTIABLE REQUIREMENT** All versioned entities (Parks, Rides, Companies, etc.) MUST have their version history created **automatically via Django signals**—NEVER manually in views, serializers, or management commands. ### Why This Rule Exists Manual version creation is fragile and error-prone. If any code path modifies a versioned entity without explicitly calling "create version," history is lost forever. Signal-based versioning guarantees that **every single modification** is captured, regardless of where the change originates. ### Required Implementation Pattern ```python # apps/{entity}/signals.py - REQUIRED for all versioned entities from django.db.models.signals import pre_save from django.dispatch import receiver from .models import Park, ParkVersion from .serializers import ParkSerializer @receiver(pre_save, sender=Park) def auto_create_park_version(sender, instance, **kwargs): """ Automatically snapshot the entity BEFORE any modification. This signal fires for ALL save operations, ensuring no history is ever lost. """ if not instance.pk: return # Skip for initial creation try: old_instance = sender.objects.get(pk=instance.pk) ParkVersion.objects.create( park=instance, data=ParkSerializer(old_instance).data, changed_by=getattr(instance, '_changed_by', None), change_summary=getattr(instance, '_change_summary', 'Auto-versioned') ) except sender.DoesNotExist: pass # Edge case: concurrent deletion ``` ### Passing Context to Signals When updating entities, attach metadata to the instance before saving: ```python # In views/serializers - attach context, DON'T create versions manually park._changed_by = request.user park._change_summary = submission_note or "Updated via API" park.save() # Signal handles versioning automatically ``` ### What Is FORBIDDEN The following patterns are **strictly prohibited** and will be flagged as non-compliant: ```python # ❌ FORBIDDEN: Manual version creation in views def update(self, request, slug=None): park = self.get_object() # ... update logic ... ParkVersion.objects.create(park=park, ...) # VIOLATION! park.save() # ❌ FORBIDDEN: Manual version creation in serializers def update(self, instance, validated_data): ParkVersion.objects.create(park=instance, ...) # VIOLATION! return super().update(instance, validated_data) # ❌ FORBIDDEN: Manual version creation in management commands def handle(self, *args, **options): for park in Park.objects.all(): ParkVersion.objects.create(park=park, ...) # VIOLATION! park.status = 'updated' park.save() ``` ### Compliance Checklist For every versioned entity, verify: - [ ] A `pre_save` signal receiver exists in `signals.py` - [ ] The signal is connected in `apps.py` via `ready()` method - [ ] No manual `{Entity}Version.objects.create()` calls exist in views - [ ] No manual `{Entity}Version.objects.create()` calls exist in serializers - [ ] No manual `{Entity}Version.objects.create()` calls exist in management commands --- ## Document Authority This document has the same authority as all other `source_docs/` files. Per the `/comply` workflow, these specifications are **immutable law** and must be enforced immediately upon detection of any violation.