Before you upgrade, read the upgrade guide.
A 1.3 pre-release with a security fix; upgrading from 1.3.0rc8 is recommended.
Added
- UI building blocks discovery (ADR-043 D4, #3448).
djust_ai_contextin every format anddjust_ai manifestshare a use-case table, setup and discovery section withdocs/llms.txt,docs/llms-full.txtanddocs/BEST_PRACTICES_AI.md. Context output now uses manifest sections;make ai-ui-section,make check-ai-ui-sectionand a pre-commit hook maintain the generated docs. Covered bypython/djust/tests/test_ai_ui_section_3448.pyandtests/test_generate_ai_ui_section.py.
Changed
- Component-aware
djust newscaffold (ADR-043 D4, #3448). The themed scaffold enablesdjust.componentsanddjust.theming, requestsdjust[components], and uses an{% app_shell %}base template.--barekeeps coredjustand writesDJUST_CONFIG = {"suppress_checks": ["I002"]}; generatedAGENTS.mdfiles point to discovery and audit commands. Missing component dependencies raiseImproperlyConfigurednamingdjust[components]. Behavior change: new projects only; existing projects unaffected. Covered bypython/djust/tests/test_scaffold_flag_projects.pyandpython/djust/tests/test_components_optional_dependencies_3448.py. - CI dependency audits now gate on findings (#3467). The test workflow's security job (on
main, the nightly schedule and manual runs) uses the locked pip-audit gate in place ofsafety, runscargo audit --deny unsoundandnpm audit --audit-level=high, and no longer turns their failures into a passing step. ESLint (--max-warnings 0) now fails both the security job and the pull-request JavaScript job on any error or warning, where it used to print a message and pass.
Fixed
- Rust-engine
{% app_shell %}main wrapper (#3448). Restore the omitteddj-app-shell__mainwrapper so header and content form a column rather than rendering side by side. Only a direct sidebar slot moves to the outer row; nested sidebars are kept, and the main content retains template order. Covered bypython/djust/tests/test_app_shell_rust_engine_3448.py. - Tailwind system check (C011) with prefixed
STATICFILES_DIRS(#3449). A(prefix, path)entry, which Django allows, no longer makes everymanage.pycommand fail withTypeErrorduring system checks; the check now looks forinput.cssandoutput.cssunder the entry's path. Covered byTestC011MissingCompiledCssinpython/tests/test_checks.py.
Security
djust ai inventoryon Windows hands off only to amanage.pywhose own directory holds a project marker (#3454). Windows has no owner or mode bits to check, so the discovered entry point's directory must containpyproject.toml,setup.cfg,setup.py,requirements.txtor.git; otherwise the CLI refuses and tells you to runpython manage.py djust_ai inventorydirectly. This stops a baremanage.pyleft in a shared writable directory; it is not an ownership check (anyone who can plantmanage.pycan plant a marker), which is tracked in #3462. A layout with the marker only in a parent directory (for example a repository root with.gitandmanage.pyone folder down) is now refused on Windows. POSIX checks are unchanged.- Windows AI inventory hand-off now verifies ownership and write access (#3462). A discovered
manage.pyand its directory must be owned by the current user (or, for an elevated administrator, by the owner its token assigns to new files, BUILTIN\Administrators) and must not grant broad principals write access through their DACLs; API failures reject the hand-off. The project-marker check still applies. - A misconfigured
DJUST_TRUSTED_PROXY_COUNTcan no longer round up to an extra trusted hop (#3469). A value that isn't anintwas converted withint(float(raw)), so"1.999999999999999999999999"selected 2 hops. It is now floored exactly as a decimal (giving 1). Non-finite values, and values of 10,000 or more, give 0. Every coerced value still logs a warning naming its type. This affects only a misconfigured setting; anintsetting is unchanged, and nothing here is reachable from a request. - On Python 3.14 and later, a role, staff or group check read through a local variable in
dispatch()/get()is no longer mistaken for a login-only check on live transports (GHSA-4h5m-xcmg-vvmw). The check that refuses a live mount whose own access check goes beyond the declared rule reads which user attributes the method uses. Python 3.14 compiles a local read toLOAD_FAST_BORROW, which it did not recognise, souser = request.user; if user.role != "admin": raise PermissionDeniedon a view that declares onlylogin_requiredmounted over WebSocket and SSE for any logged-in user. EveryLOAD_FASTform is now recognised, and a load of the user it cannot classify counts as a check beyond login. Python 3.13 and earlier were not affected. Regression cases inpython/djust/tests/test_live_auth_event_holders_and_user_checks.py.
Documentation
ServerEventToastMixin's docstring now shows{% server_toast_container position="top-right" %}(#3450). It showedtoast_container, which takes noposition.- Security audit checklist now names a runnable test target (#3468).
make test-securityselects security, XSS, auth and CSRF test files across the three Python test roots. - Release audit checklist carries unfinished #3129 work forward (#3470). The template keeps the raw HTML, dynamic attribute, escaping, permission, regression, penetration, deployment configuration, and sign-off reviews visible until their completing PRs remove them.