Skip to content

Release dev to main - #147

Merged
lafawnduh1966 merged 28 commits into
mainfrom
dev
Jul 14, 2026
Merged

Release dev to main#147
lafawnduh1966 merged 28 commits into
mainfrom
dev

Conversation

@lafawnduh1966

@lafawnduh1966 lafawnduh1966 commented Jul 14, 2026

Copy link
Copy Markdown

Objective

Release the current dev branch to main for the next Quay patch release.

  • Proposed next tag after merge: v0.3.42
  • Compare: main...dev
  • Base origin/main: 94ed23c413294949c50af0b11eaf890bb6589582
  • Head origin/dev: f0c3e79195e0899569622a7f738d1b8d8e892f03
  • Previous published release: v0.3.41

Included PRs

Derived from main...dev compare commits plus GitHub's associated PR API.

PR Title Author Merged at Risk category
#135 BRIX-1899: restrict review-finding Linear issues to synthetic_review + align adopted verdict policy @lafawnduh1966 2026-07-13T12:03:08Z Core review workflow behavior
#136 BRIX-1897: remove dead TS outbox-deliver Linear handler @lafawnduh1966 2026-07-13T12:04:03Z Cleanup, low runtime risk
#137 BRIX-1898: admin-UI toggle for review-finding Linear issue creation @lafawnduh1966 2026-07-13T12:03:32Z Admin UI and review issue creation behavior
#138 BRIX-1897: remove now-dead loadCurrentFinding @lafawnduh1966 2026-07-13T12:06:25Z Cleanup, low runtime risk
#139 fix(core): back off spawn failures (BRIX-1919) @app/quay-worker 2026-07-13T14:21:26Z Core tick retry/backoff behavior
#140 fix(core): handle spawn-window missing worktrees (BRIX-1922) @app/quay-worker 2026-07-14T07:47:22Z Core worktree recovery behavior
#141 fix(core): harden missing worktree recovery (BRIX-1922) @app/quay-worker 2026-07-14T08:14:52Z Core worktree recovery behavior
#145 feat(cli): add task worktree recreation command (BRIX-1923) @app/quay-worker 2026-07-14T08:37:21Z Operator CLI tooling
#146 fix(umbrella): retire umbrella workflow when all children are cancelled (BRIX-1924) @lafawnduh1966 2026-07-14T10:07:43Z Umbrella workflow terminal-state reconciliation
#143 fix(merge): use repo's allowed merge method and back off on policy rejection @lafawnduh1966 2026-07-14T10:08:05Z GitHub merge adapter and non-retryable failure handling
#142 feat: add quay task resnapshot to re-baseline a task's ticket snapshot @lafawnduh1966 2026-07-14T10:08:22Z Operator CLI tooling and review snapshot state
#148 fix(resnapshot): update task objective @lafawnduh1966 2026-07-14T10:36:47Z Release-blocking resnapshot/reviewer prompt correctness fix
#149 docs: clarify resnapshot objective refresh @lafawnduh1966 2026-07-14T10:46:49Z Documentation follow-up from independent re-review

Deferred Open PRs

None. gh pr list --repo InverterNetwork/quay --state open --limit 100 now shows only this release PR (#147).

Validation

Initial release-candidate run in clean worktree /private/tmp/quay-release-147-validate-20260714 at origin/dev SHA 2623a9ff6ec11dbe4ee2ee10aad9afd1cc78ed55.

Command Result
bun install --frozen-lockfile PASS (148 packages installed)
QUAY_DATA_DIR=/private/tmp/quay-release-147-testdata-empty QUAY_CONFIG_DIR=/private/tmp/quay-release-147-testconfig-empty bun test PASS outside sandbox: 1332 pass, 5 skip, 0 fail, 6137 expect() calls, 1337 tests across 224 files
bun run typecheck PASS
bun run build PASS

Validation notes:

  • An initial bun test with ambient local Quay environment failed one validator child-process test because the child inherited the local Quay DB/config environment and hit SQLiteError: table identity_mappings already exists. The same focused test passed with isolated QUAY_DATA_DIR/QUAY_CONFIG_DIR.
  • A sandboxed full-suite rerun then failed the Slack timeout server setup because Bun.serve({ port: 0 }) could not bind inside the sandbox. The focused Slack timeout test and the full suite passed outside the sandbox.

Post-review release-blocker fix #148 was validated in worktree /private/tmp/quay-release-147-fix-resnapshot and merged into dev. Follow-up docs PR #149 aligned the user docs with that fix. The final origin/dev SHA is f0c3e79195e0899569622a7f738d1b8d8e892f03.

Command Result
bun install --frozen-lockfile PASS
bun test packages/cli/tests/resnapshot/task_resnapshot.test.ts packages/cli/tests/core/worker_prompt.test.ts packages/cli/tests/adapters/test_github_adapter_merge_method.test.ts PASS: 41 pass, 0 fail, 154 expect() calls
bun run typecheck PASS
bun run build PASS
env QUAY_DATA_DIR=/private/tmp/quay-release-147-fix-testdata QUAY_CONFIG_DIR=/private/tmp/quay-release-147-fix-testconfig bun test PASS outside sandbox: 1334 pass, 5 skip, 0 fail, 6152 expect() calls, 1339 tests across 224 files
GitHub Actions CI for #148 (29325882122) PASS
git diff --check for #149 docs fix PASS
GitHub Actions CI for #149 (29326484809) PASS
Final GitHub Actions CI for #147 at f0c3e79195e0899569622a7f738d1b8d8e892f03 (29326570408) PASS

Independent review finding addressed:

Release Procedure After Merge

After this PR is approved and merged by a human:

  1. Fetch origin/main and confirm it contains this PR's merge commit.
  2. Confirm the release tag name. Proposed next patch tag: v0.3.42.
  3. Tag the merged origin/main SHA with the confirmed v* tag and push the tag.
  4. Watch the Release workflow.
  5. Verify the GitHub Release includes:
    • quay-linux-amd64
    • quay-linux-arm64
    • quay-darwin-amd64
    • quay-darwin-arm64
    • SHA256SUMS
  6. Download the current-platform asset, verify it against SHA256SUMS, and run --version.
  7. Open the hermes-agent PR that updates deploy.values.yaml to the new Quay release tag.

Rollback

Pin hermes-agent back to the previous published Quay tag, currently v0.3.41, and rerun the installer.

lafawnduh1966 and others added 25 commits July 13, 2026 11:14
…+ align adopted verdict policy

Adopted PRs (authoring_mode = adopted_external_pr) already respawn a Quay
worker on changes_requested, so Quay owns their feedback loop. Previously
adopted was treated as quay_owned for respawn but as synthetic for the
Linear gate and the reviewer verdict policy, so a mixed-finding review on an
adopted PR both respawned the worker (fixing non-blocking findings in-loop)
AND filed a redundant Linear issue for those same findings.

Treat adopted_external_pr like quay_owned for review disposition:

- Eligibility gate (review_finding_linear_outbox.ts): loadEligibleFindings
  and loadCurrentFinding now restrict to authoring_mode = 'synthetic_review'
  only, so no review_finding_linear_issue outbox rows are enqueued for
  adopted PRs.
- Reviewer verdict policy (pr_review.ts, composeTaskReviewBrief): classify
  adopted as quay_owned so non-blocking-only findings return
  changes_requested (worker fixes in-loop) instead of approve-with-notes.
  This closes the gap where, after removing adopted from the gate, a
  non-blocking-only finding on an adopted PR would be neither fixed nor filed.

Intentional behavior change, not a pure bugfix: it redefines "adopted" as
"Quay owns the feedback loop", justified because the worker already respawns.
synthetic_review (human owns the branch) is unchanged: non-blocking findings
still approve-with-notes and file a Linear issue as the sole capture.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Quay's review-finding -> Linear side effects are enqueued as durable
outbox rows and delivered by the Python orchestrator (hermes-agent), not
by Quay's own binary. The TypeScript `quay outbox deliver` path that also
delivered them was dead code: nothing scheduled it. BRIX-1896 moves Linear
delivery fully into the orchestrator, so this removes Quay's now-superseded
parallel path.

Removed:
- `quay outbox deliver` subcommand + `handleOutboxDeliver` (dispatch.ts)
  and its help entry (help.ts).
- Delivery functions in review_finding_linear_outbox.ts:
  processReviewFindingLinearIssueOutboxItem,
  deliverClaimedReviewFindingLinearIssue, and their delivery-only helpers
  (nextEligibleAtFromError, loadOutboxItem, renderLinearIssueBody,
  formatLineRange, parsePayload, linearIssueProviderIdempotencyKey,
  stableUuid). The enqueue side (enqueueReviewFindingLinearIssuesInOpenTxn
  and its queries/helpers) is unchanged; loadEligibleFindings and
  loadCurrentFinding are left untouched (owned by BRIX-1899).
- LinearAdapter.createIssue (its only caller was the removed delivery
  handler) and its now-dead dependencies: LinearPort.createIssue,
  LinearCreateIssueInput/LinearCreatedIssue, resolveTeamIdByKey,
  CREATE_ISSUE_MUTATION, GET_TEAM_BY_KEY_QUERY, RawIssueCreatePayload,
  RawTeamsByKey/RawTeamNode, normalizeOptionalString.
- The adapters.linear.default_issue_team_key config expectation (schema +
  linearAdapterOptionsFromConfig plumbing) and its docs; it was only read
  by the removed createIssue path and never set on the deployment.

Tests: dropped the deliver-command/handler cases; kept enqueue coverage
(the reattachment test now seeds the dedup-ledger link row directly
instead of running the removed delivery handler).

Depends on BRIX-1896 landing so the orchestrator owns delivery.
Part of BRIX-1897.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make review-finding -> Linear issue creation toggleable from the Quay
admin UI: a global default (ON when unset) plus a per-repo tri-state
override (inherit / on / off). The switch gates the enqueue in tick.ts —
whether the review_finding_linear_issue outbox row is placed — not the
drain. When off for a scope no outbox row is produced; findings are still
persisted and still appear in the PR review. Only synthetic_review tasks
reach this gate, so worker-authored (quay_owned) tasks are unaffected.

Stacked on BRIX-1899 (narrows enqueue eligibility to synthetic_review).

Layers:
- settings: deployment_settings.review_finding_linear_enabled (boolean|null,
  NULL resolves to ON); read/write mirror the existing agent defaults.
- migration: 0040 adds nullable-INTEGER tri-state columns (CHECK IN (0,1))
  to deployment_settings and repos.
- enqueue gate: review_finding_linear_policy.ts resolves repo-override-else-
  global-else-ON; tick's persistReviewFindings enqueues only when on.
- api: deployment_settings.update + repo.update patches accept the field;
  global read model exposes review_findings.linear_enabled.
- global UI: "Review findings" SubGroup + Toggle under §03 Adapters,
  distinct from the Linear adapter connectivity flag.
- repo UI: "Review findings" SubGroup with Inherit/On/Off Segmented, feeding
  the Overview overrides counter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ility

BRIX-1899: restrict review-finding Linear issues to synthetic_review + align adopted verdict policy
…oggle

BRIX-1898: admin-UI toggle for review-finding Linear issue creation
…liver

BRIX-1897: remove dead TS outbox-deliver Linear handler
Follow-up to #135 (BRIX-1899) + #136 (BRIX-1897). `loadCurrentFinding`
became dead once #136 removed its sole caller
(`deliverClaimedReviewFindingLinearIssue`) while #135 owned the function's
eligibility predicate — neither PR could delete it without a cross-PR
modify/delete conflict. Now that both are on `dev`, drop it. Non-exported;
typecheck + review_finding_linear_outbox tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rrentfinding

BRIX-1897: remove now-dead loadCurrentFinding
A task's `ticket_snapshot` is captured once at creation and is the
definition-of-done the reviewer enforces. When an operator changes scope
mid-flight by editing the live Linear ticket, the frozen snapshot never
updates, so the reviewer keeps enforcing stale acceptance criteria (this
looped BRIX-1907). `resnapshot` gives operators an explicit, audited
re-baseline.

`quay task resnapshot <task_id> --reason <text>` re-fetches the task's
Linear issue and re-composes the snapshot via the exact enqueue path
(`fetchTicketContextWithIssue`), then replaces the single per-task
`ticket_snapshot` artifact both worker and reviewer read (no version
skew). Creation-time augmentations (dependency/hierarchy keys) it does
not recompute are preserved verbatim. It emits a `ticket_resnapshotted`
audit event carrying the required reason and a before/after diff, and
supersedes the latest terminal review verdict so the next tick runs a
fresh review against the new snapshot (a stale `changes_requested` no
longer blocks re-review via the `terminal_verdict_exists` gate). Running
it when the ticket is unchanged is a safe, still-audited no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(core): back off spawn failures (BRIX-1919)
…jection

BRIX-1920: GitHubAdapter.mergePullRequest hardcoded `gh pr merge --merge`,
which fails on squash-only repos ("Merge commits are not allowed on this
repository"). Before merging, read the repo's merge-method policy
(allow_merge_commit / allow_squash_merge / allow_rebase_merge) via
`gh api repos/{owner}/{repo}` and pass the matching flag. Preference order
among allowed methods is merge -> squash -> rebase, so merge-commit repos are
byte-identical to before and squash-only repos use `--squash`. The result is
cached per repo_id (an umbrella's child PRs share one repo). Raises a clear
error if the repo allows no merge method. Applies to every mergePullRequest
call site via the shared adapter.

BRIX-1921: a policy-rejected merge previously fell into the `unknown` bucket,
so the tick retried the identical doomed merge every cycle with no backoff.
Add a distinct non-retryable `method_not_allowed` kind to GitHubMergeError and
classify "not allowed on this repository" / "merge method not allowed" into it.
On a non-retryable merge failure the umbrella auto-merge path now parks the
task into `non_budget_loop` with the reason recorded instead of looping;
retryable failures (head_mismatch, transient not_mergeable) still retry.

Tests: adapter-level method selection per repo config (squash-only -> --squash,
merge-allowed -> --merge, rebase-only -> --rebase, none -> error), per-repo
caching, and classification; tick-level test that a non-retryable failure parks
the task and a second tick does not re-attempt the merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(core): handle spawn-window missing worktrees (BRIX-1922)
fix(core): harden missing worktree recovery (BRIX-1922)
feat(cli): add task worktree recreation command (BRIX-1923)
Resolve conflicts from #145 (task recreate-worktree): both PRs add a new
`task` subcommand, so keep both entries in dispatch routing, help metadata,
and the CLI reference.
An umbrella workflow whose child tasks were all cancelled (observed on
BRIX-1902) stayed `active` forever: `readReadyUmbrellaFinalPrWorkflows`
gates the final PR on children reaching `merged_to_feature_branch` /
`complete_without_quay`, which cancelled children never reach, and no
other code path transitions the `umbrella_workflows` row to a terminal
state.

Add tick-time reconciliation that retires such umbrellas. Each tick,
`readRetirableUmbrellaWorkflows` selects `active` umbrellas whose every
expected child is linked to a Quay task that terminated as `cancelled`
(the exact inverse of the readiness gate) and `retireUmbrellaWorkflow`
transitions them to `cancelled`, emitting an `umbrella_retired` tick
audit action. Guardrails preserved: umbrellas with a child still in
progress, a child merged to the feature branch, a `complete_without_quay`
success, a still-unlinked `expected` child, or already `completed` are
untouched; no final PR is created, adopted, or dismissed. The
`state = 'active'` UPDATE predicate makes re-runs idempotent no-ops.

BRIX-1924

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…retire

fix(umbrella): retire umbrella workflow when all children are cancelled (BRIX-1924)
…e-method

fix(merge): use repo's allowed merge method and back off on policy rejection
…apshot

feat: add `quay task resnapshot` to re-baseline a task's ticket snapshot
…ective

fix(resnapshot): update task objective

@quay-reviewer quay-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Findings

Blocking

None.

…cli-docs

docs: clarify resnapshot objective refresh

@quay-reviewer quay-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Findings

Blocking

None.

@lafawnduh1966
lafawnduh1966 merged commit 143e304 into main Jul 14, 2026
1 check passed
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