Skip to content

Commit 4bafaa1

Browse files
Merge pull request #70 from InverterNetwork/dev
Release dev to main
2 parents 79e1ee7 + 92ba388 commit 4bafaa1

12 files changed

Lines changed: 1285 additions & 365 deletions

docs/user/cli-reference.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,14 +255,16 @@ incomplete untracked blockers fail with `dependency_not_tracked`.
255255

256256
Linear-backed umbrella workflows use native Linear parent/child hierarchy. If
257257
the issue has Linear children, enqueue creates the umbrella workflow, derives
258-
the shared feature branch, and records the expected child set without spawning
259-
a subtask worker. If the issue has a Linear parent, enqueue requires that the
260-
parent umbrella has already been enqueued, verifies the child is expected, and
261-
targets the child task at the umbrella feature branch.
258+
the shared feature branch, records the expected child set, and materializes
259+
incomplete children as Quay tasks targeted at that feature branch. Children
260+
that are already complete in Linear are recorded as `complete_without_quay` and
261+
do not get Quay tasks. If the issue has a Linear parent, direct enqueue fails
262+
with `umbrella_child_direct_enqueue` unless `--as-normal-task` is passed.
262263

263264
Umbrella parent enqueue returns coordination JSON instead of the normal task
264265
enqueue payload. The `expected_tasks` array exposes each persisted child row,
265-
including state values such as `expected` and `complete_without_quay`.
266+
including state values such as `linked` and `complete_without_quay`; the
267+
`child_tasks` array exposes materialized child task enqueue results.
266268

267269
`--as-normal-task` applies to Linear child issues only. It ignores the child's
268270
native parent umbrella membership for this enqueue, but it does not turn a

docs/user/concepts.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,12 @@ feature branch, and snapshots the expected Linear child set. Tick never polls
136136
Linear to discover changed membership later.
137137

138138
Each umbrella child target uses the shared feature branch as its effective PR
139-
base. Child enqueue links the concrete Quay task to an expected child row. If a
140-
child was already complete in Linear when discovered, Quay can mark that
141-
expected row `complete_without_quay`; it then counts toward final readiness
142-
without requiring a Quay task.
139+
base. Parent enqueue materializes each incomplete child as a concrete Quay task
140+
and links it to an expected child row. If a child was already complete in
141+
Linear when discovered, Quay marks that expected row `complete_without_quay`;
142+
it then counts toward final readiness without requiring a Quay task. Direct
143+
enqueue of a child issue is not part of the umbrella flow and fails unless the
144+
operator passes `--as-normal-task`.
143145

144146
Linear blocked-by relations define ordering. Same-umbrella dependency rows use
145147
`scope: "umbrella"` and wait for blockers to reach

docs/user/enqueueing-tasks.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,17 @@ reaches `merged`. Incomplete untracked blockers fail enqueue with
9090

9191
Umbrella workflows are driven by native Linear hierarchy. Enqueue the parent
9292
issue first; Quay records the expected child set and creates the shared feature
93-
branch. Enqueue child issues afterwards; Quay resolves the parent workflow from
94-
the child's Linear parent relation and targets the child task at the umbrella
95-
feature branch.
96-
97-
Child-before-parent enqueue fails with `umbrella_not_enqueued`. A child not in
98-
the parent's persisted expected set fails with `umbrella_subtask_not_expected`.
99-
Use `--as-normal-task` on a child issue only to intentionally ignore the
100-
Linear parent umbrella membership for one enqueue. Parent issues with children
101-
still create umbrella coordination state. The flag still processes Linear
102-
blocked-by relations as normal dependencies.
93+
branch. Incomplete children are materialized as Quay tasks during the parent
94+
enqueue and target the umbrella feature branch; children already complete in
95+
Linear are recorded as `complete_without_quay`.
96+
97+
Do not enqueue child issues afterwards for the umbrella flow. Direct child
98+
enqueue fails with `umbrella_child_direct_enqueue`, including after the parent
99+
has already materialized the child task. Use `--as-normal-task` on a child
100+
issue only to intentionally ignore the Linear parent umbrella membership for
101+
one enqueue. Parent issues with children still create umbrella coordination
102+
state. The flag still processes Linear blocked-by relations as normal
103+
dependencies.
103104

104105
Inside an umbrella, Linear blocked-by relations create umbrella-scoped
105106
dependency rows. Same-umbrella blockers wait for

docs/user/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ verify against the CLI implementation and tests, then fix the docs.
2525
- [Monitoring And Artifacts](monitoring-and-artifacts.md): task JSON, events,
2626
and artifact retrieval.
2727
- [Linear And Slack](linear-and-slack.md): adapter setup and behavior.
28+
- [Parent-Owned Umbrella QA Matrix](qa-parent-owned-umbrella.md): deployed
29+
Linear and test-repo validation scenarios for dependency and umbrella flows.
2830
- [Ticket Authoring](ticket-authoring.md): the `quay-config` block and ticket
2931
validation.
3032
- [Troubleshooting](troubleshooting.md): common errors and recovery paths.

docs/user/linear-and-slack.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ quay enqueue --repo myrepo --linear-issue ENG-200
8080

8181
If the issue has native Linear child issues, Quay creates or verifies a shared
8282
feature branch derived from the parent external ref, persists an umbrella
83-
workflow row, and records every child in `umbrella_expected_tasks`. Children
84-
that are already complete in Linear are recorded as `complete_without_quay`.
85-
No worker is spawned for the umbrella parent in the current flow.
83+
workflow row, records every child in `umbrella_expected_tasks`, and
84+
materializes every incomplete child as a Quay task targeting the umbrella
85+
feature branch. Children that are already complete in Linear are recorded as
86+
`complete_without_quay` and do not get Quay tasks. No worker is spawned for the
87+
umbrella parent in the current flow.
8688

8789
Child tickets use ordinary `quay-config` execution metadata:
8890

@@ -95,10 +97,9 @@ authors:
9597
slack_id: U06TDC56VJB
9698
```
9799
98-
When a child is enqueued, Quay resolves its native Linear parent to the
99-
persisted umbrella workflow and verifies the child is in the expected set. A
100-
child-before-parent enqueue fails with `umbrella_not_enqueued`; a child missing
101-
from the persisted expected set fails with `umbrella_subtask_not_expected`.
100+
Do not enqueue child tickets individually for the umbrella flow. Direct enqueue
101+
of a Linear child issue fails with `umbrella_child_direct_enqueue`, even if the
102+
parent umbrella was already enqueued and the child task already exists.
102103

103104
Pass `--as-normal-task` only on a child issue when you intentionally want to
104105
ignore its native Linear parent membership for this enqueue. The flag does not
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Parent-Owned Umbrella QA Matrix
2+
3+
Use this matrix when validating Quay against a deployed Linear workspace and a
4+
test repository. Each scenario assumes the test repo is registered in Quay and
5+
the Linear issues contain valid ordinary `quay-config` blocks with `repo`,
6+
`tags`, and `authors`.
7+
8+
## Blocked-By Dependencies
9+
10+
| Scenario | Setup | Expected result |
11+
| --- | --- | --- |
12+
| Complete blocker | Issue B is blocked by issue A, and A is already complete in Linear. | Enqueueing B succeeds as a normal task. The ticket snapshot records A, but no blocking dependency row is created. |
13+
| Incomplete tracked blocker | A has an existing Quay task that is not merged. B is blocked by A. | Enqueueing B creates a task in `waiting_dependencies` with a dependency on A requiring `merged`. |
14+
| Incomplete untracked blocker | B is blocked by A, A is incomplete in Linear, and A has no Quay task. | Enqueueing B fails with `dependency_not_tracked` before creating a task, worktree, or artifact. |
15+
16+
## Parent-Owned Umbrella Enqueue
17+
18+
| Scenario | Setup | Expected result |
19+
| --- | --- | --- |
20+
| Parent with incomplete children | Parent P has children C1 and C2, both incomplete. | Enqueueing P creates or verifies the umbrella feature branch, persists the expected child rows, and materializes C1/C2 as Quay tasks targeting the feature branch. No parent worker task is spawned. |
21+
| Parent with completed child | Parent P has child C1 complete in Linear and child C2 incomplete. | Enqueueing P marks C1 `complete_without_quay` and materializes only C2 as a Quay task. |
22+
| Same-umbrella child ordering | Parent P has children C1 and C2, and C2 is blocked by C1. | Enqueueing P materializes both tasks and creates an umbrella-scoped dependency from C2 to C1 requiring `merged_to_feature_branch`. |
23+
| External blocker inside umbrella child | Child C1 is blocked by issue A outside the umbrella. | If A is tracked, C1 waits for A with normal `merged` semantics. If A is incomplete and untracked, parent enqueue fails before side effects. |
24+
| Umbrella dependency cycle | Children C1 and C2 block each other through Linear blocked-by relations. | Parent enqueue fails with `umbrella_dependency_cycle` before creating child tasks or worktrees. |
25+
26+
## Direct Child Enqueue
27+
28+
| Scenario | Setup | Expected result |
29+
| --- | --- | --- |
30+
| Child before parent | Child C1 has parent P, but P has not been enqueued. | Direct enqueue of C1 fails with `umbrella_child_direct_enqueue`. |
31+
| Child after parent | Parent P has already materialized C1 as a Quay task. | Direct enqueue of C1 still fails with `umbrella_child_direct_enqueue`; existing child tasks must not bypass the guard. |
32+
| Child override | C1 has parent P, and the operator passes `--as-normal-task`. | C1 is processed as a normal task, with no umbrella task link. Linear blocked-by relations still become normal dependencies. |
33+
34+
## PR Lifecycle
35+
36+
| Scenario | Setup | Expected result |
37+
| --- | --- | --- |
38+
| Approved subtask PR | A materialized child task opens a PR into the umbrella feature branch and receives approval with green CI. | Quay may merge the child PR into the umbrella feature branch and mark the child `merged_to_feature_branch`. |
39+
| Final umbrella PR | All expected children are either `merged_to_feature_branch` or `complete_without_quay`. | Tick creates or reuses the final umbrella PR from the feature branch into the parent base branch, with a title/body based on the parent issue and links to subtasks. |
40+
| Final PR merge authority | The final umbrella PR is approved and green. | Quay must not merge the final PR. A human merges it; Quay only observes the merge and marks the umbrella workflow complete. |
41+
42+
For every scenario, capture the Linear issue identifiers, task ids, PR numbers,
43+
and the relevant `quay task get --json` output so regressions can be compared
44+
without relying on transient UI state.

docs/user/troubleshooting.md

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,33 +104,31 @@ Fix one of:
104104
blockers do not block enqueue.
105105
- Remove the Linear blocked-by relation if it is not a real dependency.
106106

107-
## `umbrella_not_enqueued`
107+
## `umbrella_child_direct_enqueue`
108108

109-
`quay enqueue --linear-issue` found that the Linear issue is a child of an
110-
umbrella parent, but Quay has no persisted umbrella workflow for that parent.
111-
Quay stops before creating the child task because it would not know the shared
112-
feature branch or expected child set.
109+
`quay enqueue --linear-issue` found that the Linear issue is a child of a
110+
Linear umbrella parent. Quay stops before creating or returning a task because
111+
the parent issue owns the umbrella flow and materializes child tasks itself.
113112

114113
Fix one of:
115114

116-
- Enqueue the Linear parent issue first, then enqueue the child again.
115+
- Enqueue the Linear parent issue instead.
117116
- Pass `--as-normal-task` if this child should intentionally run outside the
118117
umbrella workflow. This ignores the child's Linear parent membership only;
119118
Linear blocked-by relations are still processed as normal dependencies.
120119

121-
## `umbrella_subtask_not_expected`
120+
## `umbrella_dependency_cycle`
122121

123-
The Linear child has a parent umbrella workflow, but its external ref is not in
124-
the expected child set that Quay persisted when the parent was enqueued.
122+
Parent enqueue found a cycle among incomplete Linear children connected by
123+
same-umbrella blocked-by relations. Quay stops before creating tasks because no
124+
valid execution order exists.
125125

126126
Fix one of:
127127

128-
- Confirm the child is attached to the correct Linear parent.
129-
- Recreate or manually repair the umbrella workflow if the Linear child set was
130-
changed after parent enqueue. Automatic resync is not part of the current
131-
tick loop.
132-
- Pass `--as-normal-task` only if this child issue should run outside the
133-
umbrella.
128+
- Remove or correct one of the Linear blocked-by relations in the cycle.
129+
- Split the umbrella into smaller parent issues if the work is not actually a
130+
strict dependency chain.
131+
- Mark a blocker complete in Linear if it is already done outside Quay.
134132

135133
## `umbrella_feature_branch_missing`
136134

@@ -142,9 +140,7 @@ integrated work.
142140
Fix one of:
143141

144142
- Restore the missing feature branch to the expected remote ref.
145-
- Cancel or repair the umbrella workflow before enqueueing more subtasks.
146-
- If the child should intentionally run outside the umbrella, enqueue it with
147-
`--as-normal-task`.
143+
- Cancel or repair the umbrella workflow before re-enqueueing the parent.
148144

149145
## `dependency_cycle`
150146

0 commit comments

Comments
 (0)