Repository navigation
feat(kanban): diagnose worktree tasks with no repo to check out in - #103120
Open
lucascmg-vx wants to merge 1 commit into
Open
lucascmg-vx wants to merge 1 commit into
lucascmg-vx wants to merge 1 commit into
Conversation
A `workspace_kind=worktree` task resolves against its own `workspace_path` or the board's `default_workdir`. With neither, `_resolve_worktree_workspace` raises rather than guess a repo. That is the right call, but it raises at *dispatch*: the task burns its retries and the circuit breaker parks it as `blocked` behind a message that reads like an infrastructure fault instead of "this task was created with nowhere to run". Multi-repo boards leave `default_workdir` unset on purpose, so a fallback root can never check work out into the wrong repo. On those boards this is the only way the mistake surfaces, and it surfaces after the retries are gone. Add `worktree_without_checkout_root`, which reports the same condition while the task is still queued: `error` when it is merely mis-created, `critical` once it is already failing. The rule mirrors the resolver rather than `project_id`. A project is what usually supplies the path -- `create_task` turns a project link into `<repo>/.worktrees/<id>` -- but it does so only at creation, and only when the project has a primary repo; resolution never consults it again. Keying on `project_id` would miss a task that has a link and no path. It deliberately does not guess the repo. On a 24-task sample of exactly this failure, inheriting the parent task's project would have misdirected 4 (17%), every one of them from a direct parent, because cross-repo hand-offs are normal rather than exceptional. A silent checkout into the wrong repo is worse than a loud stall. `board_default_workdir` is threaded through `config` so the dashboard judges each task against its own board rather than whichever board is current; CLI callers fall back to reading the current board. Tests cover both severities, every silencing path (own path, board default, other workspace kinds, terminal statuses), the project-linked-but-pathless case, and an integration test pinning the rule to the resolver it predicts.
SummaryNew kanban diagnostic rule Findings
VerdictWell-reasoned diagnostic with strong tests, including a resolver-parity pin. No concerns. |
12 of 19 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
A
workspace_kind=worktreetask resolves against its ownworkspace_pathor the board'sdefault_workdir. With neither,_resolve_worktree_workspaceraises rather than guess a repo:That is the right call — the docstring says it fails loudly "rather than guess" — but it raises at dispatch. The task burns its retries and the circuit breaker parks it as
blockedbehind a message that reads like an infrastructure fault instead of "this task was created with nowhere to run".Multi-repo boards leave
default_workdirunset on purpose, because a single fallback root would silently check work out into the wrong repo. On those boards this raise is the only way the mistake surfaces, and it surfaces after the retries are gone.This adds
worktree_without_checkout_root, reporting the same condition while the task is still queued —errorwhen it is merely mis-created,criticalonce it is already failing.Why the rule keys on the resolver, not on
project_id. A project is what usually supplies the path:create_taskturns a project link into<repo>/.worktrees/<id>. But it does that only at creation, and only when the project has a primary repo — resolution never consultsproject_idagain. A row that has a link and no path (project without a primary repo, or a directUPDATE) is equally undispatchable, so the rule follows_resolve_worktree_workspaceand usesproject_idonly to choose the remedy text.Why it does not guess the repo. Inheriting the parent task's project looks obvious. On a 24-task sample of exactly this failure it would have misdirected 4 (17%), every one from a direct parent, because cross-repo hand-offs (a spec task in one repo spawning the follow-up that edits another) are normal rather than exceptional. A silent checkout into the wrong repo is worse than a loud stall — the same reasoning the resolver already applies. Choosing the repo stays with the operator.
Related Issue
No existing issue — I searched open and closed issues and PRs for
worktree,missing workdir,worktree_without_projectand found none. Happy to open one if you'd prefer it tracked.Type of Change
Changes Made
hermes_cli/kanban_diagnostics.py—_rule_worktree_without_checkout_root+ registration in_RULES; new public helperread_board_default_workdir().hermes_cli/kanban.py— passboard_default_workdirat the twocompute_task_diagnosticscall sites (show,diag).plugins/kanban/dashboard/plugin_api.py— thread the requestedboardinto_compute_task_diagnosticsso a multi-board process judges each task against its board rather than whichever board is current.tests/hermes_cli/test_kanban_diagnostics.py— 11 tests.DIAGNOSTIC_KINDSis intentionally not touched: perCOMPAT_MANIFEST.mdit is arestored-definside the revert-scheduledPLUGIN-COMPATblock, and nothing in-tree may depend on those pointers.python scripts/check_compat_pointers.pypasses.How to Test
default_workdir, create a worktree task with no project:hermes kanban create "demo" --workspace worktree hermes kanban diagworktree_without_checkout_rootaterrorbefore the task is ever dispatched. Let it fail once and it escalates tocritical.default_workdiron the board (or give the task an explicit--workspace worktree:<repo>) and the diagnostic clears.pytest tests/hermes_cli/test_kanban_diagnostics.py -q # 16 passed python scripts/check_compat_pointers.pytest_worktree_without_checkout_root_matches_the_resolverbuilds a real task, assertsresolve_workspaceraises, and asserts the rule fires on the same row — so the rule stays pinned to the code it predicts rather than to a hand-built fixture.Checklist
Code
Note on the suite:
pytest tests/hermes_cli/ -k "kanban or dashboard or diagnostic or worktree or workspace"gives 57 failed / 759 passed on this branch and 57 failed / 748 passed on pristinemain— same failures, +11 passes (exactly the new tests). Those pre-existing failures are intest_web_server*/test_web_ui_buildand look like in-process pollution thatscripts/run_tests.shisolates around; none are related to this change.Documentation & Housekeeping
cli-config.yaml.example(board_default_workdiris read from existing board metadata, not user config)