diff options
| -rw-r--r-- | .ai/workflows/open-tasks.org | 16 | ||||
| -rw-r--r-- | claude-rules/todo-format.md | 23 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/open-tasks.org | 16 |
3 files changed, 53 insertions, 2 deletions
diff --git a/.ai/workflows/open-tasks.org b/.ai/workflows/open-tasks.org index fe782d6..7f1bf1a 100644 --- a/.ai/workflows/open-tasks.org +++ b/.ai/workflows/open-tasks.org @@ -176,6 +176,8 @@ Next Mode answers two questions in one output: "what matters most right now?" (t Apply the prioritization cascade in order. Stop at the first matching step. This is the importance/urgency answer. +*Exclude blocked tasks.* A task tagged =:blocked:= has an unmet cross-project dependency (its =:BLOCKED_BY:= property names the project and the work owed, per =todo-format.md=). It can't be worked until that other project delivers, so it is *never* the cascade recommendation — skip it at every cascade step below. Blocked tasks are surfaced on their own in Step 3 so the stalled dependency stays visible instead of silently dropping out of view. + **** 1. In-Progress Tasks - Look for tasks marked =DOING= or partially complete. - *If found:* Recommend that task (always finish what's started). @@ -228,9 +230,17 @@ Within each row, pick a single task per the same-level tie-breakers above (block The friction filter is the override path. When the cascade winner is partially blocked, hardware-dependent, or simply too large for the user's current state, one of the friction rows is what they pick instead. +*** Step 3 — Blocked-on-other-projects surface + +Independently of the cascade and the friction filter, collect every open task tagged =:blocked:=. These are tasks this project can't advance until another project delivers; surfacing them keeps a cross-project dependency from rotting at low priority on the other side — the exact failure the tag exists to prevent (a blocked task whose blocker is a =[#D]= in another project sits forever otherwise). + +For each blocked task, read its =:BLOCKED_BY:= property (=<project>: <what>=) and present one line: the task, the blocking project, and what that project owes. Then offer — per blocked task — to nudge the blocker: an =inbox-send <project> --text= note naming what's needed and why it's blocking, so the dependency gets attention in the project that owns it. Don't send without the user's go. + +If no =:blocked:= tasks exist, omit this surface entirely (the common case). + *** Output Format -Pair the cascade recommendation with the friction block beneath it. Recommendation-at-item-1 convention applies to the friction rows — quick+solo first, since it's the strongest low-friction pick. +Pair the cascade recommendation with the friction block beneath it, and the blocked-on-other-projects surface (Step 3) beneath that when any blocked task exists. Recommendation-at-item-1 convention applies to the friction rows — quick+solo first, since it's the strongest low-friction pick. #+begin_example Cascade recommendation (importance/urgency): @@ -240,6 +250,9 @@ If you want lower friction instead: 1. Quick + solo: Bump linter config — [#C] :quick:solo:, ~15 min 2. Quick: Confirm new dirvish setup — [#B] :quick:, needs your eye 3. Solo: Refactor config-utilities — [#B] :solo:, bounded but multi-hour + +Blocked on other projects (can't advance until the blocker delivers): +- Wrap-teardown feature — blocked by emacsd: ai-term companion functions — nudge? #+end_example Include for each row: @@ -247,6 +260,7 @@ Include for each row: - Priority + tag cluster. - One-line reasoning. For the cascade row, name which cascade step matched. For friction rows, an effort hint when one is obvious. - Progress indicator (for V2MOM-structured todos) on the cascade row only. +- For a blocked row: the blocking project and what it owes (from =:BLOCKED_BY:=), plus the nudge offer. **** Edge cases diff --git a/claude-rules/todo-format.md b/claude-rules/todo-format.md index 895526f..0bfd3d3 100644 --- a/claude-rules/todo-format.md +++ b/claude-rules/todo-format.md @@ -263,3 +263,26 @@ are noise that pollute his `cj:` greps. ** DOING [#A] Kostya's contract :admin:kostya: *** 2026-05-15 Fri @ 14:00:00 -0500 Kostya basis — part-time, 20 hr/week Nerses confirmed 5/15 13:30 CDT: Kostya runs at 20 hr/week part-time, mirroring Vrezh's structure. Plugged into Exhibit A § 2 of the contract draft. + +## Cross-Project Dependency Tag + +A task can be blocked by work that has to happen in a *different project* — a rulesets task that can't finish until `.emacs.d` ships a companion function, say. Left unmarked, two things go wrong: the what's-next workflow keeps recommending the blocked task even though it can't move, and the blocker sits at low priority in the other project, so the dependency stalls silently. + +Mark the dependency with the `:blocked:` tag plus a `:BLOCKED_BY:` property: + +``` +** DOING [#B] Wrap-teardown feature :feature:blocked: +:PROPERTIES: +:BLOCKED_BY: emacsd: ai-term companion functions (cj/ai-term-quit, -live-count) +:END: +Body... +``` + +- The `:blocked:` tag on the heading is the filterable marker — it's what `open-tasks.org` reads to pull the task out of the "do this next" recommendation. +- The `:BLOCKED_BY:` property names *which* project blocks the task and *what* that project owes, as `<project>: <what>`. The project token is the short basename (`emacsd`, `home`, `work`), matching the inbox/handoff naming. + +A task stays `:blocked:` only while the external dependency is genuinely outstanding. When the other project delivers, or the dependency dissolves, drop the `:blocked:` tag and the `:BLOCKED_BY:` property in the same edit — the task is workable again. + +`open-tasks.org` Next Mode surfaces `:blocked:` tasks in a dedicated "Blocked on other projects" section instead of the cascade, naming each blocker so a stalled cross-project dependency stays visible (and can be nudged via `inbox-send`) rather than rotting. See that workflow for the surfacing behavior. + +This is distinct from `VERIFY`, which marks "waiting on Craig's input." `:blocked:` marks "waiting on another *project's* work." If Craig's input is what's needed, it's a VERIFY, not `:blocked:`. diff --git a/claude-templates/.ai/workflows/open-tasks.org b/claude-templates/.ai/workflows/open-tasks.org index fe782d6..7f1bf1a 100644 --- a/claude-templates/.ai/workflows/open-tasks.org +++ b/claude-templates/.ai/workflows/open-tasks.org @@ -176,6 +176,8 @@ Next Mode answers two questions in one output: "what matters most right now?" (t Apply the prioritization cascade in order. Stop at the first matching step. This is the importance/urgency answer. +*Exclude blocked tasks.* A task tagged =:blocked:= has an unmet cross-project dependency (its =:BLOCKED_BY:= property names the project and the work owed, per =todo-format.md=). It can't be worked until that other project delivers, so it is *never* the cascade recommendation — skip it at every cascade step below. Blocked tasks are surfaced on their own in Step 3 so the stalled dependency stays visible instead of silently dropping out of view. + **** 1. In-Progress Tasks - Look for tasks marked =DOING= or partially complete. - *If found:* Recommend that task (always finish what's started). @@ -228,9 +230,17 @@ Within each row, pick a single task per the same-level tie-breakers above (block The friction filter is the override path. When the cascade winner is partially blocked, hardware-dependent, or simply too large for the user's current state, one of the friction rows is what they pick instead. +*** Step 3 — Blocked-on-other-projects surface + +Independently of the cascade and the friction filter, collect every open task tagged =:blocked:=. These are tasks this project can't advance until another project delivers; surfacing them keeps a cross-project dependency from rotting at low priority on the other side — the exact failure the tag exists to prevent (a blocked task whose blocker is a =[#D]= in another project sits forever otherwise). + +For each blocked task, read its =:BLOCKED_BY:= property (=<project>: <what>=) and present one line: the task, the blocking project, and what that project owes. Then offer — per blocked task — to nudge the blocker: an =inbox-send <project> --text= note naming what's needed and why it's blocking, so the dependency gets attention in the project that owns it. Don't send without the user's go. + +If no =:blocked:= tasks exist, omit this surface entirely (the common case). + *** Output Format -Pair the cascade recommendation with the friction block beneath it. Recommendation-at-item-1 convention applies to the friction rows — quick+solo first, since it's the strongest low-friction pick. +Pair the cascade recommendation with the friction block beneath it, and the blocked-on-other-projects surface (Step 3) beneath that when any blocked task exists. Recommendation-at-item-1 convention applies to the friction rows — quick+solo first, since it's the strongest low-friction pick. #+begin_example Cascade recommendation (importance/urgency): @@ -240,6 +250,9 @@ If you want lower friction instead: 1. Quick + solo: Bump linter config — [#C] :quick:solo:, ~15 min 2. Quick: Confirm new dirvish setup — [#B] :quick:, needs your eye 3. Solo: Refactor config-utilities — [#B] :solo:, bounded but multi-hour + +Blocked on other projects (can't advance until the blocker delivers): +- Wrap-teardown feature — blocked by emacsd: ai-term companion functions — nudge? #+end_example Include for each row: @@ -247,6 +260,7 @@ Include for each row: - Priority + tag cluster. - One-line reasoning. For the cascade row, name which cascade step matched. For friction rows, an effort hint when one is obvious. - Progress indicator (for V2MOM-structured todos) on the cascade row only. +- For a blocked row: the blocking project and what it owes (from =:BLOCKED_BY:=), plus the nudge offer. **** Edge cases |
