docs(auth): correct require_project predicate docstring

The docstring claimed the non-string project_id coercion matched both
_coord_create_build_kwargs and the interactive create path, but
_interactive_create_build_kwargs passes body.get("project_id") through
rather than coercing. Restate it as the gate's own rule — only a
non-empty stripped string counts as an attached project — and reference
only the coordinator persistence that actually matches. Behavior
unchanged.
This commit is contained in:
Patrick Buckley
2026-07-20 11:15:32 -07:00
parent d7331ae18b
commit 482957ce2f
+8 -6
View File
@@ -509,12 +509,14 @@ def require_project_denies_create(config_store: Any, auth: Any, project_id: Any)
Serves both gated mounts: interactive creates on nodes and coordinator
creates on the console. Refuses only when the gate is on, the caller is
not exempt automation, and no project is attached. "No project" is read
the way the create path actually persists it: a non-string body value
(int / bool / list / dict) is coerced to absent — exactly as
``_coord_create_build_kwargs`` and the interactive create do — so a
truthy non-string like ``project_id: 123`` cannot stringify past the
gate and mint a projectless session; whitespace-only counts as none too.
not exempt automation, and no project is attached. The gate counts a
project as attached only when ``project_id`` is a non-empty string after
stripping; absent, empty, whitespace-only, or a non-string body value
(int / bool / list / dict) all read as "no project." Treating a
non-string as absent matches how ``_coord_create_build_kwargs`` persists
it (``None``) and stops a truthy non-string like ``project_id: 123`` from
stringifying past the gate and minting a projectless session while the
create stores no project.
Exempt identities: the ``service`` scope (channel gateway,
scheduler) and the sessions a coordinator spawns
(``token_source == "coordinator"`` — minted per coordinator session for