Skip to content

feat(tasks): enforce unassigned tasks start Unclaimed on create - #808

Open
lkubie wants to merge 1 commit into
mainfrom
cakeagents/ex-2934
Open

lkubie wants to merge 1 commit into
mainfrom
cakeagents/ex-2934

Conversation

@lkubie

@lkubie lkubie commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

What

client.tasks.create / create_many now enforce the platform's task lifecycle rule client-side: a task created without assigned_to always starts Unclaimed. A missing state is defaulted to Unclaimed in the outgoing payload, and ownership states (Not Started, In Progress) are rejected with a clear AlbertException before any request is sent. The invariant ("a task cannot be In Progress and unassigned") is documented on TaskState, BaseTask.state / BaseTask.assigned_to, and the create / create_many / update docstrings (which feed the public docs site).

Why

SDK counterpart to EX-2918 / https://github.com/MoleculeEngineering/api-task/pull/486 (requested by Lenore Kubie). The API now defaults unassigned task creates to Unclaimed because stateless tasks break the UI and cannot be repaired via PATCH (state transitions require the current state). Enforcing the same contract in the SDK means callers get a deterministic payload and a clear client-side error instead of relying on server-side defaulting. Linear: EX-2934.

How

  • New pure helper resolve_unassigned_task_state in src/albert/utils/tasks.py, mirroring the API's taskState.helper.js: None -> UNCLAIMED, NOT_STARTED / IN_PROGRESS -> raise, explicit UNCLAIMED / terminal states (COMPLETED, CLOSED, CANCELLED) pass through unchanged for ingestion flows (EX-2401).
  • Applied in TaskCollection.create and create_many only when assigned_to is None, by setting state on the serialized payload. create_with_combinations delegates to create, so it is covered too.
  • update is intentionally not blocked: the platform auto-assigns the calling user when an unclaimed task is moved forward (FTR-257), which is now documented in the update Notes instead.

Testing

  • 7 new unit tests in tests/unit/utils/test_tasks.py covering the default, both rejected ownership states, and the pass-through table.
  • uv run pytest tests/unit: 1278 passed, 2 xfailed. ruff format / ruff check: clean.
  • Integration tests not run (require live API credentials); the change is offline payload-assembly logic covered by unit tests.

Cake session: https://agents.ai.albertinventdev.com/sessions/e26da368-3c7e-4ac2-8ab2-53b852318ce5

Mirror the platform create-path rule (EX-2918): a task created without
assigned_to gets state defaulted to Unclaimed, and ownership states
(Not Started, In Progress) are rejected without an assignee. Explicit
terminal states are preserved for ingestion flows. Documents the
state/assignee coupling on TaskState, BaseTask, and the
create/create_many/update docstrings.
@claude

claude Bot commented Sep 30, 2026

Copy link
Copy Markdown

Looks good - no bugs or correctness issues found.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant