Outcome
Add a first-class server-side stack object: ordered pull request entries with stored commit boundaries, structural validation, and health states. Branch topology alone stays ambiguous; the stack row is the identity.
Context
docs/stacked-prs.md sections 5.2–5.3, 7.1–7.2, and 8 define the model. Follow repo conventions: OpenAgents.Repo migrations, binary-id primary keys, utc_datetime_usec, CHECK constraints paired with changeset inclusion validations.
Acceptance criteria
pull_request_stacks rows carry repository scope, a repository-local number, trunk ref, state (open, completed, dissolved), an optimistic version, and timestamps.
pull_request_stack_entries rows carry position, boundary OID, observed head OID, and soft-removal. Positions are contiguous from 1; a partial unique index keeps one PR in at most one active stack.
- OIDs store in a representation that accepts SHA-1 and SHA-256, not a fixed 40-character column.
- Structural invariants enforce same-repository membership, unique entries, no duplicate branches, and the direct-base chain. Generic PR base edits route through the stack service or fail with an explanation.
- Health states separate from state:
healthy, needs_rebase, conflicted, missing_ref, head_changed, policy_blocked, operation_in_progress. A stale graph never dissolves a stack.
- The contract records as an invariant in
INVARIANTS.md with an executable proof under ops/ci/.
Verification
Domain tests in OpenAgents.DataCase for every invariant violation, plus migration up/down. Run mix precommit.
Dependencies
Basic pull requests (#1) must land first so stacks have something to order.
Outcome
Add a first-class server-side stack object: ordered pull request entries with stored commit boundaries, structural validation, and health states. Branch topology alone stays ambiguous; the stack row is the identity.
Context
docs/stacked-prs.mdsections 5.2–5.3, 7.1–7.2, and 8 define the model. Follow repo conventions:OpenAgents.Repomigrations, binary-id primary keys,utc_datetime_usec, CHECK constraints paired with changeset inclusion validations.Acceptance criteria
pull_request_stacksrows carry repository scope, a repository-local number, trunk ref, state (open,completed,dissolved), an optimisticversion, and timestamps.pull_request_stack_entriesrows carry position, boundary OID, observed head OID, and soft-removal. Positions are contiguous from 1; a partial unique index keeps one PR in at most one active stack.healthy,needs_rebase,conflicted,missing_ref,head_changed,policy_blocked,operation_in_progress. A stale graph never dissolves a stack.INVARIANTS.mdwith an executable proof underops/ci/.Verification
Domain tests in
OpenAgents.DataCasefor every invariant violation, plus migration up/down. Runmix precommit.Dependencies
Basic pull requests (#1) must land first so stacks have something to order.