mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
* feat(tasks): enforce sibling sequence order at the claim chokepoint A task with a parent and effective sequence N (COALESCE(sequence, 0)) can no longer be claimed while any sibling with a strictly lower effective sequence is non-terminal — assignee-blind, independent of and stricter than dependency_ids, enforced in _validate_claim_preconditions so both claim paths (gateway verbs and the dispatcher's raw REST claim) cross it. Ties run parallel; cancelled siblings never block; sequence 0 and parentless tasks are unaffected. Live failure this guards: a PM delegated revision subtasks sequenced 0..3 with no dependency edges and seq 2 started alongside seq 0 — sequence was advisory-only. set_sequence's contract updated accordingly. New e2e smoke case drives the refusal and the post-completion claim through the real gateway. * chore(scripts): skip .uv-cache and .claude in the prose scanner Repo-local tool dirs (private uv cache, agent worktrees) carry vendored and generated markdown that tripped make reflow-check. * fix(tasks): wave-derived delegation sequences + claim-gate hardening Three fixes from the adversarial review of the sequence claim gate: Delegation no longer stamps a raw per-sibling ordinal (deterministic merge-order bookkeeping) as sequence — under the strict gate that serialized ALL delegated work, including fully independent cross-dev and cross-cell siblings. Sequences are now wave-derived post-wiring (stamp_wave_sequence: 1 + max same-parent dependency sequence, 0 when independent), so independent siblings tie and run parallel while colliding/ordered work ascends. The cross-cell UX wiring restamps instead of writing relative ux+1 values (a relative write could invert a collision-derived stamp), and the dispatch merge/lane barriers gain a created_at tiebreak for wave-tied siblings so shared-branch merge order stays deterministic. PM-authored sequences are never rewritten. The guard now also fires on reclaims from needs_revision (a lower- sequence sibling delegated after the first claim was invisible), and tasks.parent_task_id gains an index (migration 069) — the guard's sibling probe ran as a Seq Scan on the hottest verb. --------- Co-authored-by: Renn F <rennf93@users.noreply.github.com>
30 lines
899 B
Python
30 lines
899 B
Python
"""Add ix_tasks_parent_task_id — sibling scans on the claim hot path.
|
|
|
|
Postgres does not auto-index FK columns, so every sibling lookup
|
|
(``get_subtasks``, the sequence claim guard's blocking-sibling probe, the
|
|
dispatch merge/lane barriers) was a Seq Scan over tasks. The sequence guard
|
|
runs on every PENDING/NEEDS_REVISION claim, so the scan sat on the hottest
|
|
verb. Plain btree; additive; no data change.
|
|
|
|
Revision ID: 069_tasks_parent_task_id_idx
|
|
Revises: 068_tasks_constraints_column
|
|
Create Date: 2026-07-10
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from alembic import op
|
|
|
|
revision = "069_tasks_parent_task_id_idx"
|
|
down_revision = "068_tasks_constraints_column"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.create_index("ix_tasks_parent_task_id", "tasks", ["parent_task_id"])
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_index("ix_tasks_parent_task_id", table_name="tasks")
|