From 15805a4d2ccbcbd9e289b6a86c3f78cea0f45092 Mon Sep 17 00:00:00 2001 From: bougyman's bot Date: Sat, 26 Sep 2026 01:12:30 -0400 Subject: [PATCH 1/4] fix(stokowski): make the before_run hook best-effort The glean workflow's hook ran `git rebase origin/main || git rebase --abort`. On a dirty worktree the rebase refuses to start, and the abort then exits 128 because no rebase is in progress, so every dispatch in that workspace failed. EXT-68 retried it every 5 minutes until the orchestrator was stopped. The other three workflows used `set -eu`, which the Bash standard forbids, and left a half-finished rebase behind when it hit a conflict. All four now share one hook: skip the rebase when fetch or status fails or the tree is dirty, abort a failed rebase, and fail only when that abort fails. Also resolve leftover merge-conflict markers in the opus workflow's after_create hook, which made the file invalid YAML. Co-Authored-By: Claude Opus 5.5 --- workflow.claude.yaml | 24 +++++++++++++++++++----- workflow.codex.yaml | 24 +++++++++++++++++++----- workflow.glean.yaml | 24 ++++++++++++++++++++++-- workflow.opus.yaml | 28 +++++++++++++++++++--------- 4 files changed, 79 insertions(+), 21 deletions(-) diff --git a/workflow.claude.yaml b/workflow.claude.yaml index 5f70a42..de76c13 100644 --- a/workflow.claude.yaml +++ b/workflow.claude.yaml @@ -117,14 +117,28 @@ hooks: git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . mix setup before_run: | - set -eu - git fetch origin main - changes="$(git status --porcelain)" + # Best-effort refresh onto origin/main. A failed hook fails the whole agent + # run, so only a rebase that cannot be cleaned up is fatal. + if ! git fetch origin main; then + echo "before_run: git fetch origin main failed; skipping rebase" >&2 + exit 0 + fi + if ! changes="$(git status --porcelain)"; then + echo "before_run: git status failed; skipping rebase" >&2 + exit 0 + fi if [ -n "$changes" ]; then echo "before_run: preserving uncommitted workspace changes; skipping rebase" - else - git rebase origin/main + exit 0 + fi + if ! git rebase origin/main; then + echo "before_run: rebase onto origin/main failed; aborting it" >&2 + if ! git rebase --abort; then + echo "before_run: git rebase --abort failed; the workspace needs manual repair" >&2 + exit 1 + fi fi + exit 0 timeout_ms: 120000 # --------------------------------------------------------------------------- diff --git a/workflow.codex.yaml b/workflow.codex.yaml index e5f8ffb..7515c59 100644 --- a/workflow.codex.yaml +++ b/workflow.codex.yaml @@ -118,14 +118,28 @@ hooks: git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . mix setup before_run: | - set -eu - git fetch origin main - changes="$(git status --porcelain)" + # Best-effort refresh onto origin/main. A failed hook fails the whole agent + # run, so only a rebase that cannot be cleaned up is fatal. + if ! git fetch origin main; then + echo "before_run: git fetch origin main failed; skipping rebase" >&2 + exit 0 + fi + if ! changes="$(git status --porcelain)"; then + echo "before_run: git status failed; skipping rebase" >&2 + exit 0 + fi if [ -n "$changes" ]; then echo "before_run: preserving uncommitted workspace changes; skipping rebase" - else - git rebase origin/main + exit 0 + fi + if ! git rebase origin/main; then + echo "before_run: rebase onto origin/main failed; aborting it" >&2 + if ! git rebase --abort; then + echo "before_run: git rebase --abort failed; the workspace needs manual repair" >&2 + exit 1 + fi fi + exit 0 timeout_ms: 120000 # --------------------------------------------------------------------------- diff --git a/workflow.glean.yaml b/workflow.glean.yaml index d8665c8..02ba6c1 100644 --- a/workflow.glean.yaml +++ b/workflow.glean.yaml @@ -26,8 +26,28 @@ hooks: mise install mise exec -- mix setup before_run: | - git fetch origin main - git rebase origin/main 2>/dev/null || git rebase --abort + # Best-effort refresh onto origin/main. A failed hook fails the whole agent + # run, so only a rebase that cannot be cleaned up is fatal. + if ! git fetch origin main; then + echo "before_run: git fetch origin main failed; skipping rebase" >&2 + exit 0 + fi + if ! changes="$(git status --porcelain)"; then + echo "before_run: git status failed; skipping rebase" >&2 + exit 0 + fi + if [ -n "$changes" ]; then + echo "before_run: preserving uncommitted workspace changes; skipping rebase" + exit 0 + fi + if ! git rebase origin/main; then + echo "before_run: rebase onto origin/main failed; aborting it" >&2 + if ! git rebase --abort; then + echo "before_run: git rebase --abort failed; the workspace needs manual repair" >&2 + exit 1 + fi + fi + exit 0 timeout_ms: 240000 claude: diff --git a/workflow.opus.yaml b/workflow.opus.yaml index 5c23899..7d06660 100644 --- a/workflow.opus.yaml +++ b/workflow.opus.yaml @@ -116,20 +116,30 @@ hooks: after_create: | git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . mix setup -<<<<<<< HEAD - mix deps.get -======= cd app && mix deps.get ->>>>>>> main before_run: | - set -eu - git fetch origin main - changes="$(git status --porcelain)" + # Best-effort refresh onto origin/main. A failed hook fails the whole agent + # run, so only a rebase that cannot be cleaned up is fatal. + if ! git fetch origin main; then + echo "before_run: git fetch origin main failed; skipping rebase" >&2 + exit 0 + fi + if ! changes="$(git status --porcelain)"; then + echo "before_run: git status failed; skipping rebase" >&2 + exit 0 + fi if [ -n "$changes" ]; then echo "before_run: preserving uncommitted workspace changes; skipping rebase" - else - git rebase origin/main + exit 0 + fi + if ! git rebase origin/main; then + echo "before_run: rebase onto origin/main failed; aborting it" >&2 + if ! git rebase --abort; then + echo "before_run: git rebase --abort failed; the workspace needs manual repair" >&2 + exit 1 + fi fi + exit 0 timeout_ms: 120000 # --------------------------------------------------------------------------- From 1360dc43ceb42812bacc9c83cec24370261d795a Mon Sep 17 00:00:00 2001 From: bougyman's bot Date: Sat, 26 Sep 2026 01:23:26 -0400 Subject: [PATCH 2/4] fix(stokowski): fetch root deps before mix setup in new workspaces The root RepoTasks project depends on req, and it has no alias that fetches deps. In a fresh clone, `mix setup` therefore ran without its dependencies. Every after_create hook now runs `mix deps.get` at the top level before `mix setup`. Also correct the repository layout note in CLAUDE.md, which described the root project as having no deps. Co-Authored-By: Claude Opus 5.5 --- workflow.claude.yaml | 1 + workflow.codex.yaml | 1 + workflow.glean.yaml | 1 + workflow.opus.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/workflow.claude.yaml b/workflow.claude.yaml index de76c13..e10e356 100644 --- a/workflow.claude.yaml +++ b/workflow.claude.yaml @@ -115,6 +115,7 @@ workspace: hooks: after_create: | git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . + mix deps.get mix setup before_run: | # Best-effort refresh onto origin/main. A failed hook fails the whole agent diff --git a/workflow.codex.yaml b/workflow.codex.yaml index 7515c59..ce8eefd 100644 --- a/workflow.codex.yaml +++ b/workflow.codex.yaml @@ -116,6 +116,7 @@ workspace: hooks: after_create: | git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . + mix deps.get mix setup before_run: | # Best-effort refresh onto origin/main. A failed hook fails the whole agent diff --git a/workflow.glean.yaml b/workflow.glean.yaml index 02ba6c1..e0e7272 100644 --- a/workflow.glean.yaml +++ b/workflow.glean.yaml @@ -24,6 +24,7 @@ hooks: git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . mise trust mise install + mise exec -- mix deps.get mise exec -- mix setup before_run: | # Best-effort refresh onto origin/main. A failed hook fails the whole agent diff --git a/workflow.opus.yaml b/workflow.opus.yaml index 7d06660..3440f1a 100644 --- a/workflow.opus.yaml +++ b/workflow.opus.yaml @@ -115,6 +115,7 @@ workspace: hooks: after_create: | git clone --depth 1 --recursive git@github.com:rubyists/linear-cli . + mix deps.get mix setup cd app && mix deps.get before_run: | From 5e77751043716938251552f287c839ef8c8c0f96 Mon Sep 17 00:00:00 2001 From: bougyman's bot Date: Sat, 26 Sep 2026 01:23:49 -0400 Subject: [PATCH 3/4] docs(agents): note that the root project has its own deps The repository layout described the root RepoTasks project as having no deps. It depends on req, so a fresh clone needs `mix deps.get` at the top level as well as in app/. (The previous commit's message mentioned this change, but the edit did not reach that commit.) Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fc9073a..4095328 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,8 +62,9 @@ This repo uses two Mix projects side-by-side, not nested: - `app/` — The CLI itself (`LinearCli` application, version-managed, Burrito-released). All end-user features live here. -- `lib/`, `mix.exs` (root) — Repo-management tooling (`RepoTasks` project, - no deps). Mix tasks that operate on the repo as a whole: `mix lc`, +- `lib/`, `mix.exs` (root) — Repo-management tooling (`RepoTasks` project; + its own small deps, such as `req`, so a fresh clone needs `mix deps.get` + here as well as in `app/`). Mix tasks that operate on the repo as a whole: `mix lc`, `mix setup`, `mix git_hooks`, `mix stokowski`, `mix container.build/publish`. These tasks orchestrate other tools as child processes and know nothing about `app/`'s internal modules. From f8eb38853d8822616d8d4073c8ed01655a52aab6 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Sat, 26 Sep 2026 09:01:47 -0400 Subject: [PATCH 4/4] chore: update stokowski to fixed pin --- mise.toml | 4 ++-- vendor/stokowski | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mise.toml b/mise.toml index 03f9765..97f263a 100644 --- a/mise.toml +++ b/mise.toml @@ -8,8 +8,8 @@ erlang = "29.0.3" elixir = "1.20.3" python = "3.14.7" uv = "0.12.18" -codex = "0.157.0" -claude = "2.1.282" +codex = "0.157.1" +claude = "2.1.283" [env] #ANTHROPIC_BASE_URL = "http://127.0.0.1:13305" #ANTHROPIC_AUTH_TOKEN = "lemonade" diff --git a/vendor/stokowski b/vendor/stokowski index 35f4a55..1f843c0 160000 --- a/vendor/stokowski +++ b/vendor/stokowski @@ -1 +1 @@ -Subproject commit 35f4a5585082f75b90b6ce06a23aab066ece535a +Subproject commit 1f843c0915bba42b4ca7372c3315c748d1297bd8