{
  "id": "python-django",
  "name": "Django product applications",
  "use_cases": [
    "CRUD-heavy SaaS",
    "Internal products and admin tools",
    "Server-rendered business applications"
  ],
  "choose_when": [
    "Accounts, forms, admin and database workflows are central",
    "A cohesive conventional monolith reduces integration decisions"
  ],
  "avoid_when": [
    "Only a small stateless endpoint is needed",
    "The core workload needs a different runtime or hard real-time guarantees"
  ],
  "tools": [
    {
      "job": "Packaging and environments",
      "default": "uv + pyproject.toml + committed uv.lock",
      "alternatives": [
        "Preserve an existing maintained packaging workflow"
      ],
      "reason": "One project entry point for dependencies, Python selection, execution and reproducible sync.",
      "limits": "Pin a compatible Python minor and resolve actual package versions at implementation; do not hand-edit uv.lock. Keep environments and caches in a local development workspace.",
      "source_urls": [
        "https://docs.astral.sh/uv/guides/projects/"
      ]
    },
    {
      "job": "Lint and format",
      "default": "Ruff",
      "alternatives": [
        "Preserve existing configured formatter/linter"
      ],
      "reason": "Fast lint and formatting feedback with one configuration.",
      "limits": "Ruff does not replace static typing, tests, authorization checks or runtime validation.",
      "source_urls": [
        "https://docs.astral.sh/ruff/installation/"
      ]
    },
    {
      "job": "Static typing",
      "default": "mypy + django-stubs plugin",
      "alternatives": [
        "ty for isolated plain-Python modules after validation"
      ],
      "reason": "Django-aware stubs and plugin improve checks around ORM and settings.",
      "limits": "Check the django-stubs compatibility table for the selected Django/Python/mypy combination; plugin imports application settings.",
      "source_urls": [
        "https://github.com/typeddjango/django-stubs",
        "https://mypy.readthedocs.io/en/stable/getting_started.html"
      ]
    },
    {
      "job": "Testing",
      "default": "pytest + pytest-django",
      "alternatives": [
        "Django built-in test runner"
      ],
      "reason": "Database fixtures and Django integration while retaining pytest conventions.",
      "limits": "Set DJANGO_SETTINGS_MODULE; use isolated PostgreSQL tests for constraints and transactions. Unit tests alone miss request and migration behavior.",
      "source_urls": [
        "https://docs.pytest.org/en/stable/getting-started.html",
        "https://pytest-django.readthedocs.io/en/latest/"
      ]
    },
    {
      "job": "Database and migrations",
      "default": "PostgreSQL + Django ORM/migrations + Psycopg",
      "alternatives": [
        "SQLite for low-concurrency local products"
      ],
      "reason": "Use the framework's existing data layer and schema history.",
      "limits": "Review schema/data migrations and query counts; run production-relevant DB tests. Do not introduce SQLAlchemy as a second default ORM.",
      "source_urls": [
        "https://docs.djangoproject.com/en/6.0/topics/migrations/"
      ]
    },
    {
      "job": "Validation",
      "default": "Django Forms/ModelForms plus domain checks and DB constraints",
      "alternatives": [
        "Pydantic at external JSON/tool boundaries"
      ],
      "reason": "Form lifecycle handles submitted values and field errors.",
      "limits": "Model saving is not a substitute for form/domain validation; enforce invariants at the appropriate transaction boundary.",
      "source_urls": [
        "https://docs.djangoproject.com/en/6.0/ref/forms/validation/",
        "https://pydantic.dev/docs/validation/latest/concepts/strict_mode/"
      ]
    },
    {
      "job": "Authentication",
      "default": "Django auth, sessions, permissions and CSRF protection",
      "alternatives": [
        "OIDC integration when an existing identity provider owns login"
      ],
      "reason": "Built-in accounts and session conventions fit browser products.",
      "limits": "Object/tenant permissions still need explicit implementation and tests; do not expose the admin as the product UI by default.",
      "source_urls": [
        "https://docs.djangoproject.com/en/6.0/topics/auth/",
        "https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/"
      ]
    },
    {
      "job": "Background jobs",
      "default": "Celery + a configured durable broker",
      "alternatives": [
        "Django Tasks plus a reviewed production backend",
        "Temporal for durable orchestration"
      ],
      "reason": "Documented Django integration for off-request work.",
      "limits": "Broker required; enqueue after commit, retry only safe effects. Django Tasks built-in backends do not supply production workers or durable queues. Celery is a separate integration, not automatically a django.tasks backend.",
      "source_urls": [
        "https://docs.celeryq.dev/en/stable/django/first-steps-with-django.html",
        "https://docs.celeryq.dev/en/stable/userguide/tasks.html",
        "https://docs.djangoproject.com/en/6.0/topics/tasks/"
      ]
    },
    {
      "job": "Long-running durable agents",
      "default": "Temporal Python SDK when recovery across restarts is required",
      "alternatives": [
        "Celery for independent queued jobs; direct function for bounded work"
      ],
      "reason": "Persisted workflow orchestration and separate worker processes suit retries, pauses and human waits.",
      "limits": "Adds a service and operational cost. Keep external I/O in activities, make side effects idempotent, test replay and cancellation; no end-to-end integration was run.",
      "source_urls": [
        "https://docs.temporal.io/develop/python",
        "https://docs.celeryq.dev/en/stable/userguide/tasks.html"
      ]
    },
    {
      "job": "Deployment",
      "default": "Container or managed Python service; WSGI for sync applications, ASGI when justified",
      "alternatives": [
        "Existing organization deployment platform"
      ],
      "reason": "Use the Django production deployment interface and checklist.",
      "limits": "Choose/pin a compatible application server at implementation; never deploy runserver. Configure secrets, HTTPS, static assets, health checks and backups.",
      "source_urls": [
        "https://docs.djangoproject.com/en/6.0/howto/deployment/",
        "https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/",
        "https://docs.astral.sh/uv/guides/integration/docker/"
      ]
    },
    {
      "job": "Application logging",
      "default": "Python logging with configured handlers",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Shared standard logging captures application and dependency diagnostics",
      "limits": "Configure logging at entry point, redact credentials and add request/job IDs, duration and failure context. Persist logs on the execution platform; metrics/tracing backend is a separate operational choice.",
      "source_urls": [
        "https://docs.python.org/3/library/logging.html"
      ]
    },
    {
      "job": "Bounded external-call retries",
      "default": "Tenacity only for retryable transient failures",
      "alternatives": [
        "Provider SDK retry policy when sufficient"
      ],
      "reason": "Explicit stop/wait/filter rules support controlled retries",
      "limits": "Install tenacity; set attempt/deadline limits, jitter and exception filters. The bare decorator retries forever without delay; do not stack retries with SDK/worker retries or repeat non-idempotent effects without keys.",
      "source_urls": [
        "https://tenacity.readthedocs.io/en/latest/"
      ]
    },
    {
      "job": "Transactional email",
      "default": "django.core.mail + selected SMTP backend",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Built-in mail wrappers and test backends fit account/product messages",
      "limits": "Configure TLS, sender and backend; test HTML/text content and enqueue required delivery. Delivery and bounce monitoring remain provider responsibilities.",
      "source_urls": [
        "https://docs.djangoproject.com/en/6.0/topics/email/"
      ]
    },
    {
      "job": "Uploads and file storage",
      "default": "Django FileField + configured storage backend",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Framework file APIs separate model metadata from storage",
      "limits": "Configure storage for the selected host; validate upload size/type and authorize serving. Local MEDIA_ROOT is unsuitable for unshared ephemeral replicas; choose an external backend when required.",
      "source_urls": [
        "https://docs.djangoproject.com/en/6.0/topics/files/"
      ]
    }
  ],
  "setup_steps": [
    "In a new local source directory in a local development workspace: uv init; choose and pin a supported Python minor, then uv add django 'psycopg[binary]'. Resolve compatible versions and commit uv.lock.",
    "uv add --dev ruff mypy django-stubs pytest pytest-django",
    "uv run django-admin startproject config . ; then uv run python manage.py startapp core",
    "Configure installed apps, PostgreSQL credentials from the environment, auth/session settings, pytest DJANGO_SETTINGS_MODULE and the django-stubs mypy plugin/settings module.",
    "Implement one authorized vertical slice; generate migrations with uv run python manage.py makemigrations, review them, then uv run python manage.py migrate against a disposable development DB.",
    "Add Celery only for actual queued work; configure broker, worker and after-commit enqueueing. Add Temporal only when durable multi-step recovery is required.",
    "Document application server, static asset collection, migration release ordering, worker start/restart and rollback. Run verification below before deployment."
  ],
  "verification_commands": [
    "uv sync --locked",
    "uv run ruff check .",
    "uv run ruff format --check .",
    "uv run mypy core config",
    "uv run pytest",
    "uv run python manage.py check",
    "uv run python manage.py makemigrations --check --dry-run",
    "uv run python manage.py migrate --check",
    "uv run python manage.py check --deploy --settings=config.production"
  ],
  "open_questions": [
    "Which supported Python/Django versions and third-party packages are required?",
    "Which host owns HTTPS, static/media serving and deployment settings?",
    "Which identity, email/storage, broker and job-delivery guarantees are required?"
  ],
  "evidence_status": "documentation-reviewed",
  "sources": [
    {
      "url": "https://docs.astral.sh/uv/guides/projects/",
      "title": "uv projects",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.astral.sh/ruff/installation/",
      "title": "Ruff installation",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/typeddjango/django-stubs",
      "title": "django-stubs",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://mypy.readthedocs.io/en/stable/getting_started.html",
      "title": "mypy getting started",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.pytest.org/en/stable/getting-started.html",
      "title": "pytest getting started",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pytest-django.readthedocs.io/en/latest/",
      "title": "pytest-django",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/topics/migrations/",
      "title": "Django migrations",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/ref/forms/validation/",
      "title": "Django form validation",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://pydantic.dev/docs/validation/latest/concepts/strict_mode/",
      "title": "Pydantic strict mode",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/topics/auth/",
      "title": "Django authentication",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/",
      "title": "Django deployment checklist",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.celeryq.dev/en/stable/django/first-steps-with-django.html",
      "title": "Celery Django integration",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.celeryq.dev/en/stable/userguide/tasks.html",
      "title": "Celery tasks",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/topics/tasks/",
      "title": "Django Tasks",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.temporal.io/develop/python",
      "title": "Temporal Python SDK",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/howto/deployment/",
      "title": "Django deployment",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.astral.sh/uv/guides/integration/docker/",
      "title": "uv Docker",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.python.org/3/library/logging.html",
      "title": "Python logging",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://tenacity.readthedocs.io/en/latest/",
      "title": "Tenacity documentation",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/topics/email/",
      "title": "Django sending email",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.djangoproject.com/en/6.0/topics/files/",
      "title": "Django files",
      "checked_date": "2026-10-10"
    }
  ],
  "title": "Django",
  "language": "Python",
  "group": "Web applications",
  "kind": [
    "web"
  ],
  "ui": "server",
  "host": "server",
  "summary": "Data-heavy products with an ORM, forms, accounts and admin.",
  "shape": "Django · PostgreSQL · uv · pytest",
  "tradeoff": "Interactive clients and long-running jobs require their own interface and worker choices.",
  "research_file": "python.json",
  "reviewed": "2026-10-10",
  "best_practices": [
    "Keep Django's auth, session and CSRF protections. Enforce tenant and object permissions in application operations.",
    "Use forms, domain validation and database constraints together; do not rely on one validation layer.",
    "Commit and rehearse migrations against an isolated database; check deployment settings separately from unit tests.",
    "Choose WSGI or ASGI for the actual workload and operate background workers independently."
  ],
  "research_freshness": {
    "core_guidance_checked_on": "2026-10-13",
    "sources": [
      "https://docs.djangoproject.com/en/stable/intro/install/"
    ],
    "scope": "Core framework roles, current setup/agent documentation and cited-source availability rechecked; not a reimplementation or exhaustive semantic audit of every third-party dependency."
  },
  "guide_url": "/stacks/python-django/",
  "markdown_url": "/stacks/python-django/guide.md",
  "json_url": "/stacks/python-django/record.json",
  "architecture_and_migration": {
    "id": "python-django",
    "version_scope": "Django 6.0 versioned docs; Celery 5.6.3 and Channels 4.3.2 current docs fetched 11 October 2026. The Django 6 Tasks API is version-specific and does not imply an existing Django 5.2 project should upgrade or abandon Celery. Pin actual Python/package versions before qualifying composition.",
    "operating_model": "Django organizes projects into applications, with conventional URL/view/model boundaries and integrated authentication. Recommendation: keep domain operations and permissions reusable across HTTP views, admin actions and workers. Optional Celery and Channels are separate execution/messaging systems rather than core Django features.",
    "architecture": [
      "Django defaults to database autocommit; transaction.atomic defines an explicit transaction boundary. Recommendation: keep transactions around the domain operation and do external delivery after commit through a recoverable design when required.",
      "Django 6 Tasks defines and enqueues tasks but supplies no worker mechanism. A production backend/worker must be evaluated; Celery remains a separate established candidate. Recommendation: do not equate an API-level task declaration with durable execution.",
      "Channels channel layers exchange high-level application events. channels_redis is the official production-supported layer; the in-memory layer cannot communicate across processes. Recommendation: persist business state separately from transient fanout."
    ],
    "developer_workflow": [
      "In a disposable target, django-admin startproject mysite creates the project and python manage.py startapp polls creates an application. Preserve the existing project/application structure when migrating a feature.",
      "Use python manage.py makemigrations to prepare reviewed migration files, python manage.py migrate to apply them and python manage.py showmigrations to inspect recorded state. Recommendation: nominate one deployment migration runner for shared tables.",
      "For a configured Celery application, adapt celery -A tasks worker --loglevel=INFO from the official first-steps recipe, replacing tasks with the actual application module. Broker and optional result backend are separate configuration choices.",
      "Before a production target, adapt python manage.py check --deploy to its production settings as the checklist instructs. Recommendation: exercise real database, session, task worker and Channels topology; the development runserver is not a production deployment."
    ],
    "avoid": [
      "Avoid deploying Django 6 ImmediateBackend/DummyBackend as a substitute for a durable production queue; the Tasks framework requires an external executing backend and documents built-in development/test backends.",
      "Avoid treating transaction.on_commit as durable cross-store delivery: callbacks run after commit and their failures cannot roll back the transaction. Recommendation: use an outbox when lost dispatch after commit is unacceptable.",
      "Avoid using LocMemCache or Channels in-memory layers as shared multi-process state; both are process-local. Avoid using cache-only session storage when eviction/restart logout violates the product contract.",
      "Avoid running two Celery beat schedulers for the same schedule; Celery documents duplicate task production. Recommendation: transfer ownership across frameworks as well as within Celery."
    ],
    "transitions": [
      {
        "capability": "data",
        "existing_contract": "Capture schema, account IDs, database constraints and model/write side effects. Migration history is framework-owned metadata and must be reconciled deliberately when an existing schema changes owner.",
        "coexistence": "Recommendation: retain one domain writer and schema runner; add compatible fields and move one application/domain boundary while old code still reads new records. Use historical models for Django data migrations as documented.",
        "target": "Django models/migrations with explicit transaction.atomic boundaries for related database writes. Recommendation: delay field deletion until the rollback reader retires.",
        "benefits": [
          {
            "benefit": "Recommendation: coherent model and migration ownership makes a domain boundary reviewable.",
            "prerequisites": "Tested schema mapping and explicit writer transfer.",
            "tradeoffs": "Database reversal may be irreversible for data operations; application objects/cache state also need reconciliation."
          }
        ],
        "checks": [
          "Create in each permitted writer and read in both runtimes; compare identifiers, null values, timestamps and constraint failures.",
          "Fail inside transaction.atomic and verify database writes roll back; inspect whether in-memory/cache state requires explicit restoration."
        ],
        "rollback": "Recommendation: restore the old writer while retaining additive fields; rehearse reverse migrations on a disposable copy and reconcile non-reversible data operations.",
        "sources": [
          "https://docs.djangoproject.com/en/6.0/topics/migrations/",
          "https://docs.djangoproject.com/en/6.0/topics/db/transactions/"
        ],
        "id": "data-1"
      },
      {
        "capability": "jobs",
        "existing_contract": "Inventory task names, argument serializer, broker/result backend, retry/acknowledgement policy, periodic schedule and ready/delayed/failed/running work. Django 6 Tasks and Celery payloads are distinct contracts.",
        "coexistence": "Recommendation: keep old consumers for old tasks; isolate new categories and route producers deliberately. Retain the existing scheduler until an explicit one-owner transfer. Qualify any Django Tasks backend separately from the task API.",
        "target": "Celery with a selected broker/optional result backend, or a qualified Django 6 executing backend. Schedule dispatch after database commit; recommendation: add recoverable outbox delivery when a crash can occur before broker acceptance.",
        "benefits": [
          {
            "benefit": "Recommendation: execution can migrate by task category while the old backlog remains executable.",
            "prerequisites": "Qualified payload fixtures, retained consumers and one schedule owner.",
            "tradeoffs": "Two task systems may be operated; a framework API switch does not translate backlog or broker guarantees."
          }
        ],
        "checks": [
          "Capture a task envelope and run it through its intended consumer, including argument conversion and missing-record behavior.",
          "Rollback the domain transaction and verify no dispatch; kill after an external effect and validate replay-safe completion.",
          "Account for delayed/retry/failed/in-flight tasks and confirm one periodic enqueue for each transferred schedule."
        ],
        "rollback": "Recommendation: pause new producers, retain consumers for accepted payloads and reconcile completed effects before switching categories back.",
        "sources": [
          "https://docs.djangoproject.com/en/6.0/topics/tasks/",
          "https://docs.djangoproject.com/en/6.0/topics/db/transactions/",
          "https://docs.celeryq.dev/en/stable/userguide/tasks.html",
          "https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html"
        ],
        "id": "jobs-1"
      },
      {
        "capability": "identity",
        "existing_contract": "Record authentication backend, user mapping, session engine/cookie name, serializer, expiry and revocation. Django database, cached_db, cache-only and signed-cookie sessions have different persistence/failure behavior.",
        "coexistence": "Recommendation: retain a shared identity authority or qualified exchange; do not treat Redis key sharing as session-format compatibility. Keep every resource permission enforced in the target view/operation.",
        "target": "Django authentication with a selected session backend. cached_db writes through to database/cache and reads the database on cache misses; recommendation: prefer it over cache-only sessions when eviction logout is unacceptable.",
        "benefits": [
          {
            "benefit": "Recommendation: a durable session authority can preserve access through cache eviction.",
            "prerequisites": "Configured database sessions, compatible account mapping and tested revocation.",
            "tradeoffs": "Write-through caching adds operations; cookie continuity across runtimes still requires a decoder/exchange or planned reauthentication."
          }
        ],
        "checks": [
          "Login in the old system, access the Django feature, then logout/expire/revoke and verify both deny unauthorized operations.",
          "Evict the selected session cache and confirm behavior matches the chosen engine; test another tenant’s identifier with a valid login."
        ],
        "rollback": "Recommendation: preserve previous identity/session contracts through the rollback window and retain revocation state during traffic reversal.",
        "sources": [
          "https://docs.djangoproject.com/en/6.0/topics/http/sessions/",
          "https://docs.djangoproject.com/en/6.0/topics/auth/default/"
        ],
        "id": "identity-1"
      },
      {
        "capability": "realtime",
        "existing_contract": "Capture WebSocket protocol, group/event names, authentication and required missed-event behavior. Channels channel layers carry application-level events, not a universal client protocol.",
        "coexistence": "Recommendation: keep old client endpoints, bridge versioned domain events and route room/user cohorts including reconnects. Designate one committed-change publisher; use the configured shared layer for multiple processes.",
        "target": "Channels with channels_redis when using the documented official production channel layer. Recommendation: reconstruct/replay from persistent domain state when missed broadcasts matter.",
        "benefits": [
          {
            "benefit": "Recommendation: a shared channel layer enables cross-process fanout.",
            "prerequisites": "Configured Redis layer, matching consumers/events and authorized subscriptions.",
            "tradeoffs": "Redis remains operated; transient fanout alone does not provide durable business-message recovery."
          }
        ],
        "checks": [
          "Connect subscribers to separate processes and verify one committed change reaches both authorized groups.",
          "Restart/disconnect during an event and verify reconnect obtains missing domain state; revoke access and confirm rejected subscriptions."
        ],
        "rollback": "Recommendation: retain the previous endpoint/event envelope and route cohorts back including their reconnects; avoid replaying already-applied effects.",
        "sources": [
          "https://channels.readthedocs.io/en/stable/topics/channel_layers.html"
        ],
        "id": "realtime-1"
      },
      {
        "capability": "cache",
        "existing_contract": "Inventory key versions/prefixes, serializers, TTLs and invalidation, separating disposable values from session/coordination ownership. Django local-memory cache is per-process even though it is thread-safe.",
        "coexistence": "Recommendation: use separate namespaces for changed representations and invalidate both old/new readers. Retain shared storage for cross-process requirements; move only reconstructible local data to LocMemCache.",
        "target": "A deliberately selected Django cache backend with configured timeout/key version. Recommendation: use local caches only where node/process staleness is accepted and rebuilding is safe.",
        "benefits": [
          {
            "benefit": "Recommendation: reconstructible caching can change independently of domain writes.",
            "prerequisites": "Defined staleness, invalidation and data ownership.",
            "tradeoffs": "Per-process caches duplicate state; sensitive filesystem cache locations/serialization require care as the docs explain."
          }
        ],
        "checks": [
          "Warm two processes, commit a source update and verify both readers meet the stated staleness policy.",
          "Restart or empty only the dedicated cache and verify reconstruction; session/permission correctness must remain intact."
        ],
        "rollback": "Recommendation: restore old namespace/backend routing and repopulate from authoritative data without treating cache contents as business records.",
        "sources": [
          "https://docs.djangoproject.com/en/6.0/topics/cache/",
          "https://docs.djangoproject.com/en/6.0/topics/db/transactions/"
        ],
        "id": "cache-1"
      },
      {
        "capability": "operations",
        "existing_contract": "List production application server, settings/secrets, migrations, static/media handling, Celery worker/beat and Channels processes. Celery requires only one scheduler for a schedule at a time.",
        "coexistence": "Recommendation: keep both process inventories and one named migration/schedule owner during coexistence. Define promotion thresholds for outcomes, queue age and denied access rather than promoting from a clean startup alone.",
        "target": "An explicitly configured deployment following Django’s checklist, plus independently supervised selected workers and scheduler. Recommendation: document restored database/session/queue consistency.",
        "benefits": [
          {
            "benefit": "Recommendation: production checks and role ownership make recovery responsibilities visible.",
            "prerequisites": "Actual production settings and a rehearsed restore/restart.",
            "tradeoffs": "check --deploy detects configuration issues, not end-to-end job, permission or restore correctness."
          }
        ],
        "checks": [
          "Run the deployment checks against intended settings and exercise an authorized/denied request after a disposable restore.",
          "Stop a worker and verify queued work is visible; restart it, then verify one scheduler and intended recovery behavior."
        ],
        "rollback": "Recommendation: restore old routing/settings and schedule ownership explicitly; preserve accepted tasks and reconcile effects before replay.",
        "sources": [
          "https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/",
          "https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html"
        ],
        "id": "operations-1"
      }
    ],
    "sources": [
      {
        "url": "https://docs.djangoproject.com/en/6.0/intro/tutorial01/",
        "title": "Django first application",
        "claim": "Project/application generator commands and development server boundary."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/topics/migrations/",
        "title": "Django Migrations",
        "claim": "Migration commands, history, data migrations and reversibility."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/topics/db/transactions/",
        "title": "Django Transactions",
        "claim": "Autocommit, atomic, on_commit timing/failure and application-state rollback limitations."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/topics/tasks/",
        "title": "Django 6 Tasks",
        "claim": "Task API, no built-in worker, backend requirements, argument conversion and commit timing."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/topics/http/sessions/",
        "title": "Django Sessions",
        "claim": "Database/cache/cached_db/cookie choices, persistence, eviction and serialization."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/topics/auth/default/",
        "title": "Django Authentication",
        "claim": "Authentication, login/logout and permissions."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/topics/cache/",
        "title": "Django Cache",
        "claim": "Backend setup, key versions, per-process local memory and filesystem security concerns."
      },
      {
        "url": "https://channels.readthedocs.io/en/stable/topics/channel_layers.html",
        "title": "Channels Channel Layers",
        "claim": "Official production channels_redis and lack of cross-process delivery in memory."
      },
      {
        "url": "https://docs.celeryq.dev/en/stable/userguide/tasks.html",
        "title": "Celery Tasks",
        "claim": "Task naming/serialization, retries, acknowledgement and idempotency concerns."
      },
      {
        "url": "https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html",
        "title": "Celery Periodic Tasks",
        "claim": "Single scheduler ownership, schedule timezone and overlap concerns."
      },
      {
        "url": "https://docs.celeryq.dev/en/stable/getting-started/first-steps-with-celery.html",
        "title": "Celery First Steps",
        "claim": "Worker command and distinction between broker and result backend."
      },
      {
        "url": "https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/",
        "title": "Django Deployment Checklist",
        "claim": "Production settings, check --deploy and deployment responsibilities."
      }
    ],
    "reviewed_at": "2026-10-11",
    "evidence": "documentation-reviewed"
  },
  "rewrite_url": "/rewrite/guide.md",
  "migration_contracts_url": "/rewrite/contracts.json",
  "agent_workflow": [
    "Read README, dependency manifests, lockfiles, runtime pins and the maintained project workflow before changing anything. Preserve an existing stack unless reconsidering it is part of the request.",
    "Use this guide to select tools by requirement. Resolve compatible versions from official and installed-version documentation; record the actual lockfile and runtime versions.",
    "Create a plan for schema changes, identity, authorization, external effects and deployment. A library choice does not complete its integration.",
    "Run relevant checks after configuration. Exercise the real interface, failure paths and packaged artifact on the intended target. Report commands, versions, results and untested behavior.",
    "On failure, retain the command and diagnostic, fix the failing prerequisite and resume there. Do not regenerate over existing work or suppress failures to make a check green."
  ],
  "selection": {
    "native_ui": false,
    "static_hosting": false,
    "offline_client_candidate": false
  },
  "coverage_note": "Tools are curated starting points for this application role. Exact versions, integrations and offline behavior require project-specific qualification."
}
