CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / integration (push) Successful in 53s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / Python tests (push) Failing after 1m18s
CI & Build / Build & push image (push) Skipped
status is durable and nothing clears it, so in_progress cannot also mean "someone is on this now". The claim is that second meaning, stored as who and when so it dies on read rather than needing to be cleared. - notes.claimed_by / claimed_at / claim_touched_at / claim_session (0110). - The server stamps it on the write that is the work: reaching in_progress (update or create, via apply_status_transition) and a work log on an open task. done/cancelled/todo release it. Live while touched within CLAIM_LEASE (2h); dead on read past it, with no sweep. - The plugin's PostToolUse hook on update_task/add_task_log binds the harness's session_id (GET /api/plugin/claim-session). It binds only to a live claim the caller holds; it cannot create one. - to_dict carries `claim`. Plugin version minted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
"""task_claims — a task can say a session is working it (milestone 381 step 2)
|
|
|
|
Revision ID: 0110
|
|
Revises: 0109
|
|
Create Date: 2026-09-23
|
|
|
|
`status` is durable and nothing clears it, so `in_progress` cannot also mean
|
|
"someone is on this now". The claim is that second meaning, stored as WHO and
|
|
WHEN rather than as a flag, so it can be read as dead without anything having
|
|
cleared it (`services/task_claims.py` has the semantics).
|
|
|
|
Four nullable columns, no backfill: no existing row has ever been claimed, and
|
|
inventing a claim for one would assert attention nobody observed. No CHECK
|
|
enum is touched.
|
|
"""
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision = "0110"
|
|
down_revision = "0109"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column("notes", sa.Column(
|
|
"claimed_by", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True,
|
|
))
|
|
op.add_column("notes", sa.Column("claimed_at", sa.DateTime(timezone=True), nullable=True))
|
|
op.add_column("notes", sa.Column("claim_touched_at", sa.DateTime(timezone=True), nullable=True))
|
|
op.add_column("notes", sa.Column("claim_session", sa.Text(), nullable=True))
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("notes", "claim_session")
|
|
op.drop_column("notes", "claim_touched_at")
|
|
op.drop_column("notes", "claimed_at")
|
|
op.drop_column("notes", "claimed_by")
|