From 02d9dc3f38b0fb10de749778fe3706485ece0a58 Mon Sep 17 00:00:00 2001 From: droidnoob Date: Sat, 30 May 2026 17:48:37 +0530 Subject: [PATCH 1/2] chore(release): 0.11.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - workspace Cargo.toml: 0.10.0 -> 0.11.0 - 23 skill body `hew:version=` markers bumped to match - .claude/ install snapshot refreshed via `hew init --runtime=claude` - CHANGELOG.md: move [Unreleased] content into [0.11.0] — 2026-05-30 Release contents since 0.10.0: #53 parallel hew loop via per-worker git worktrees (hew-6az) #54 per-task model selection + per-model token spend (hew-1tq) #55 init re-run UX — refresh/reconfigure/cancel (hew-0wa) #56 split /hew:auto from /hew:loop semantics (hew-6n0v) #57 cut local cargo test from ~2 min to ~22s (hew-v2ib) #58 hew loop run --scope={ready|epics} (hew-b3yl) #59 batch planner + end-of-run verify + loop graph (hew-lf40) #60 retry_etxtbsy stub flake fix (hew-0rky) Breaking surface: hew loop run in non-interactive mode now requires --scope. Justifies the minor bump. Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/commands/hew/auto.md | 64 ++++++++--- .claude/commands/hew/loop.md | 29 +++-- .claude/commands/hew/ship.md | 10 +- .claude/skills/hew/SKILL.md | 9 +- .claude/skills/hew/brownfield/hew-audit.md | 2 +- .claude/skills/hew/brownfield/hew-boundary.md | 2 +- .../skills/hew/brownfield/hew-convention.md | 2 +- .claude/skills/hew/brownfield/hew-migrate.md | 2 +- .claude/skills/hew/brownfield/hew-scan.md | 2 +- .claude/skills/hew/core/hew-checkpoint.md | 2 +- .claude/skills/hew/core/hew-decompose.md | 106 ++++++++++++++++-- .claude/skills/hew/core/hew-execute.md | 13 ++- .claude/skills/hew/core/hew-guard.md | 2 +- .claude/skills/hew/core/hew-new-project.md | 2 +- .claude/skills/hew/core/hew-plan.md | 18 ++- .claude/skills/hew/core/hew-verify.md | 2 +- .../hew/optional/hew-adversarial-review.md | 2 +- .claude/skills/hew/optional/hew-blast.md | 2 +- .claude/skills/hew/optional/hew-compact.md | 2 +- .claude/skills/hew/optional/hew-deps.md | 2 +- .claude/skills/hew/optional/hew-quick.md | 2 +- .claude/skills/hew/optional/hew-research.md | 2 +- .claude/skills/hew/optional/hew-review.md | 2 +- .claude/skills/hew/optional/hew-security.md | 2 +- .claude/skills/hew/optional/hew-spec.md | 2 +- CHANGELOG.md | 2 + Cargo.lock | 4 +- Cargo.toml | 2 +- skills/SKILL.md | 2 +- skills/brownfield/hew-audit.md | 2 +- skills/brownfield/hew-boundary.md | 2 +- skills/brownfield/hew-convention.md | 2 +- skills/brownfield/hew-migrate.md | 2 +- skills/brownfield/hew-scan.md | 2 +- skills/core/hew-checkpoint.md | 2 +- skills/core/hew-decompose.md | 2 +- skills/core/hew-execute.md | 2 +- skills/core/hew-guard.md | 2 +- skills/core/hew-new-project.md | 2 +- skills/core/hew-plan.md | 2 +- skills/core/hew-verify.md | 2 +- skills/data/planner-prompt.md | 2 +- skills/optional/hew-adversarial-review.md | 2 +- skills/optional/hew-blast.md | 2 +- skills/optional/hew-compact.md | 2 +- skills/optional/hew-deps.md | 2 +- skills/optional/hew-quick.md | 2 +- skills/optional/hew-research.md | 2 +- skills/optional/hew-review.md | 2 +- skills/optional/hew-security.md | 2 +- skills/optional/hew-spec.md | 2 +- 51 files changed, 245 insertions(+), 94 deletions(-) diff --git a/.claude/commands/hew/auto.md b/.claude/commands/hew/auto.md index 204f9e2..5817c4e 100644 --- a/.claude/commands/hew/auto.md +++ b/.claude/commands/hew/auto.md @@ -1,30 +1,58 @@ --- -description: Autonomously drain the queue via the process-level loop (`hew loop run --until-empty`). +description: Drive the loop in-conversation, walking the children of one active epic. --- -Run the autonomous outer loop until the ready queue drains: +In-conversation, epic-scoped driver. `/hew:auto` stays inside the +current Claude session and walks the children of one active epic in +dependency order — one continuous transcript, full mid-loop steering. + +This is **not** the subprocess loop. For fresh-context-per-iter with +prompt-cache hits, hard caps, and per-iter logs on disk, use +[`/hew:loop`](./loop.md) (`hew loop run`). + +## Pick the active epic + +If the user named one in the prompt, use it. Otherwise: ```sh -hew loop run --until-empty +hew epic list # open epics +hew epic tree # children + dep order for the chosen epic ``` -`--until-empty` is on by default — stop signals fire when the queue -hits zero, when a budget caps, when the operator touches the stop-file, -or on a runtime error. Use `--max-iter N` to bound the run, `--strict` -(default) to promote craft warnings to failures, `--budget-tokens N` / -`--budget-wall ` for hard caps. +If exactly one open epic exists, pick it. If several, ask the user once +which to drive. Never default to the full `bd ready` set — that's the +subprocess loop's job. + +## The walk + +Until the active epic has no open children: + +1. From `hew epic tree `, pick the next unblocked child + (lowest-id ties break by creation order). Skip closed/in_progress + children belonging to another assignee. +2. Tail-call `/hew:next` for that task. `/hew:next` claims, runs the + full `hew-execute` loop (read → code → tests → `hew-guard` → close + → commit → optional `hew remember`), and returns. +3. Loop. The session stays focused on one epic at a time; cross-epic + work needs an explicit re-invocation. + +Stop when: -Per-iter logs land in `.hew/loop//iter-NNN.json`. Inspect with -`hew loop list`, `hew loop logs --tail 5`, `hew loop cancel`. +- All children of the active epic are closed → run `/hew:verify`, + then offer to close the epic and report done. +- A Rule-4 architectural change blocks progress → surface to the + user and wait. +- The user interrupts. -For the in-conversation walk through the workflow (older `/hew:auto` -behavior — useful when you want to drive iters from inside one Claude -session rather than spawning fresh subprocesses), call `/hew:work` and -let it tail-call `/hew:next` until either: +Honor every `hew-execute` rule along the way (guard before close, +deviation tags in close reasons, atomic commits, branching contract). -- `hew status` ready list is empty (call `/hew:verify`, then report done), or -- a Rule-4 architectural change blocks you (stop, surface, wait). +## When to reach for `/hew:loop` instead -Honor all guard / deviation / convention rules; atomic commits per task. +- You want each task in a fresh context window with a cache-warm + prefix. +- You want hard caps (token / wall-clock / max-iter) and per-iter + logs to disk. +- You're draining the global ready queue, not focusing one epic. -See `docs/LOOP.md` for the full design. +See [`docs/LOOP.md`](../docs/LOOP.md) for the full design. diff --git a/.claude/commands/hew/loop.md b/.claude/commands/hew/loop.md index b392cb2..6aa2027 100644 --- a/.claude/commands/hew/loop.md +++ b/.claude/commands/hew/loop.md @@ -9,11 +9,14 @@ ready-queue empty, stop-file, max-iter, runtime error). Common invocations: ```sh -hew loop run --dry-run --max-iter 1 # smoke: prompt-assemble, no spawn -hew loop run --until-empty # drain the ready queue (default on) -hew loop run --max-iter 5 --strict # bounded run, craft warnings = fail -hew loop run --budget-tokens 200000 # cap cumulative tokens -hew loop run --budget-wall 30m # cap wall clock +hew loop run --scope=ready --dry-run --max-iter 1 # smoke: prompt-assemble, no spawn +hew loop run --scope=ready --until-empty # drain the ready queue (default on) +hew loop run --scope=epics --epics=hew-6az # only tasks under one epic +hew loop run --scope=ready --max-iter 5 --strict # bounded run, craft warnings = fail +hew loop run --scope=ready --budget-tokens 200000 # cap cumulative tokens +hew loop run --scope=ready --budget-wall 30m # cap wall clock +hew loop run --scope=ready --runtime=codex # drive codex-cli instead of claude +hew loop run --scope=ready --fallback-runtime=codex # swap to codex on primary RuntimeError hew loop list # recent runs + state hew loop logs --tail 5 # last 5 iters of latest run @@ -30,9 +33,19 @@ Per-iter artifacts land in `.hew/loop//`: the loop to halt at the next iter boundary The loop runner is process-level: each iter is one fresh `claude -p` -invocation. Prompt prefix (skill body + memory primer) is byte-stable -across iters of the same skill so Anthropic's prompt cache hits; -`prompt_prefix_hash` in the iter log lets you verify that. +(or `codex exec`) invocation. Prompt prefix (skill body + memory primer) +is byte-stable across iters of the same skill so the agent's prompt +cache hits; `prompt_prefix_hash` in the iter log lets you verify that. +`--fallback-runtime` is primary-sticky with a configurable cooldown +(`--fallback-cooldown-iters`, default 3); see `docs/LOOP.md` for the +full state machine. + +**Scope is required.** Every `hew loop run` invocation declares which +slice of `bd ready` it consumes — `--scope=ready` for the whole queue, +or `--scope=epics --epics=` for tasks transitively under one or +more epics. Interactive runs get a picker; agent-driven runs that omit +the flag exit with `MissingFlag { flag: "scope" }`. See `docs/LOOP.md` +§ Scope. For the full design + the 10 locked decisions behind the loop, see `docs/LOOP.md` and the `hew-gr1` epic. diff --git a/.claude/commands/hew/ship.md b/.claude/commands/hew/ship.md index 870f78f..784ded6 100644 --- a/.claude/commands/hew/ship.md +++ b/.claude/commands/hew/ship.md @@ -5,5 +5,11 @@ description: Create a PR and (optionally) a gate for the next epic. After the current epic verifies clean: 1. Push the branch (if not already on main). 2. Open a PR with a summary auto-generated from closed task descriptions. -3. Optionally create a Beads gate (gates aren't wrapped by `hew task new`; use bd directly): `bd create --type=gate --title="PR #N merged" --await-type=gh:pr --await-id=N` -4. Add the gate as a dependency of the next epic via `hew dep add --on ` so the agent waits for merge. +3. Optionally create an external-state gate that blocks the next epic on + this PR's merge: `hew gate new --gh-pr=N --title="PR #N merged"` + (returns a gate task id). Backed by `gh pr view N --json state,mergedAt`; + the gate resolves when GitHub reports `state=MERGED`. +4. Wire the gate as a dependency of the next epic via + `hew dep add ` so the loop blocks on merge. +5. Run `hew gate poll` periodically (or wire into a loop hook) to flip + resolved gates from open → done and unblock downstream work. diff --git a/.claude/skills/hew/SKILL.md b/.claude/skills/hew/SKILL.md index 15d3c34..41f93cb 100644 --- a/.claude/skills/hew/SKILL.md +++ b/.claude/skills/hew/SKILL.md @@ -1,4 +1,4 @@ - + --- name: hew description: Index of installed hew skills. Loaded by the agent on session start. @@ -156,7 +156,10 @@ Do not create planning markdown files (`PLAN.md`, `TODO.md`, `ROADMAP.md`, code, not plans. Do not use string-prefixed task titles (`"GATE: ..."`, `"PHASE: ..."`) to fake -structural roles. Beads has native types: `--type=gate`, `--type=epic`, -`bd mol bond`. Use them. +structural roles. Use the typed surfaces: `--type=epic` for hierarchical +containers, `--type=decision` for ADR-shaped records, and the dedicated +`hew gate` command for external-state gates (PR merge / future +issue-close / etc). `bd mol bond` is documented broken — wire cross-epic +ordering with `hew dep add` instead. Do not skip the `hew-guard` step before `hew task close`. Drift compounds. diff --git a/.claude/skills/hew/brownfield/hew-audit.md b/.claude/skills/hew/brownfield/hew-audit.md index 5711955..24e4f4f 100644 --- a/.claude/skills/hew/brownfield/hew-audit.md +++ b/.claude/skills/hew/brownfield/hew-audit.md @@ -1,4 +1,4 @@ - + --- name: hew-audit category: brownfield diff --git a/.claude/skills/hew/brownfield/hew-boundary.md b/.claude/skills/hew/brownfield/hew-boundary.md index c917757..cc1f800 100644 --- a/.claude/skills/hew/brownfield/hew-boundary.md +++ b/.claude/skills/hew/brownfield/hew-boundary.md @@ -1,4 +1,4 @@ - + --- name: hew-boundary category: brownfield diff --git a/.claude/skills/hew/brownfield/hew-convention.md b/.claude/skills/hew/brownfield/hew-convention.md index 2d28cf7..f2435b2 100644 --- a/.claude/skills/hew/brownfield/hew-convention.md +++ b/.claude/skills/hew/brownfield/hew-convention.md @@ -1,4 +1,4 @@ - + --- name: hew-convention category: brownfield diff --git a/.claude/skills/hew/brownfield/hew-migrate.md b/.claude/skills/hew/brownfield/hew-migrate.md index 82ba323..47b67b9 100644 --- a/.claude/skills/hew/brownfield/hew-migrate.md +++ b/.claude/skills/hew/brownfield/hew-migrate.md @@ -1,4 +1,4 @@ - + --- name: hew-migrate category: brownfield diff --git a/.claude/skills/hew/brownfield/hew-scan.md b/.claude/skills/hew/brownfield/hew-scan.md index 8e2b0f7..6ac5d89 100644 --- a/.claude/skills/hew/brownfield/hew-scan.md +++ b/.claude/skills/hew/brownfield/hew-scan.md @@ -1,4 +1,4 @@ - + --- name: hew-scan category: brownfield diff --git a/.claude/skills/hew/core/hew-checkpoint.md b/.claude/skills/hew/core/hew-checkpoint.md index b55929e..3efbf24 100644 --- a/.claude/skills/hew/core/hew-checkpoint.md +++ b/.claude/skills/hew/core/hew-checkpoint.md @@ -1,4 +1,4 @@ - + --- name: hew-checkpoint category: core diff --git a/.claude/skills/hew/core/hew-decompose.md b/.claude/skills/hew/core/hew-decompose.md index 1639f52..6525f6b 100644 --- a/.claude/skills/hew/core/hew-decompose.md +++ b/.claude/skills/hew/core/hew-decompose.md @@ -1,4 +1,4 @@ - + --- name: hew-decompose category: core @@ -214,6 +214,63 @@ Heuristics for "too small": Then merge it into the next task. +### Batch mode — `bd create --graph` for >3 tasks + +`hew task new` in a loop hits `GOTCHA:zsh-cmd-substitution`: multi-line +descriptions with apostrophes, backticks, or `$(…)` substitutions blow up +the shell before they reach bd. For any decomposition above ~3 tasks, +emit a single graph-JSON file and run `bd create --graph plan.json` — +one transaction, deps wired inline, content passes through verbatim +(apostrophes/quotes/backticks/`$(…)` all survive). + +This is a **documented bd hold-out**: `hew` doesn't wrap batch creation; +`bd create --graph` is the path. + +```json +{ + "nodes": [ + {"key": "epic", "title": "Auth System", "type": "epic", "priority": 1, + "description": "JWT auth for /api/v1/*. See DECISION:auth."}, + + {"key": "contracts", "parent_key": "epic", "title": "Define auth contracts", + "type": "task", "priority": 1, + "description": "**Why:** interface-first ordering.\n**What:** AuthResponse, RefreshRequest, route paths /login /refresh /logout.\n**Files:** app/api/v1/auth/types.py."}, + + {"key": "login", "parent_key": "epic", "title": "Implement POST /login", + "type": "task", "priority": 1, + "description": "**Why:** D-04. **What:** validates body, returns AuthResponse.\nApostrophes', \"quotes\", $(this) and `backticks` all pass through verbatim.\nFiles: app/services/auth_service.py, tests/api/test_login.py."}, + + {"key": "refresh", "parent_key": "epic", "title": "Implement /refresh + rotation", + "type": "task", "priority": 1, + "description": "**What:** rotation-on-use, revoke-old, reuse-detection."} + ], + "edges": [ + {"from_key": "login", "to_key": "contracts", "type": "blocks"}, + {"from_key": "refresh", "to_key": "contracts", "type": "blocks"} + ] +} +``` + +Run it: + +``` +bd create --graph plan.json +# Created 4 issues +# epic -> hew-a3f8 +# contracts -> hew-a3f8.1 +# login -> hew-a3f8.2 +# refresh -> hew-a3f8.3 +``` + +Schema cheat-sheet: + +- **`nodes[].key`** — local-only handle, used by edges and parent_key. Discarded after creation. +- **`nodes[].parent_key`** / **`nodes[].parent_id`** — wire hierarchy. Use `parent_key` for siblings in the same plan; `parent_id` for an already-existing parent (e.g. `"hew-a3f8"`). +- **`nodes[].type`** — `task` / `epic` / `feature` / `bug` / `chore` / `decision`. (No `gate` type — see Step 5.) +- **`edges[].from_key` / `to_key`** — `from` is the dependent (blocked); `to` is the prerequisite. `type` is typically `"blocks"`. + +For a one-off task with no hostile content, plain `hew task new` is still fine. Reach for `--graph` when the plan is >3 tasks or any description carries shell-hostile characters. + ## Step 4 — wire dependencies A task `hew dep add --on ` if it cannot start until @@ -236,20 +293,27 @@ hew dep add hew-X.4 --on hew-X.2 ## Step 5 — place gates for external blockers -Gates are for anything outside the Beads graph. Never fake a gate with a -title prefix. Create the blocked task first, then attach a gate to it. +Gates are for anything outside the Beads graph (a PR has to merge, CI +has to go green, a human has to approve). Never fake a gate with a title +prefix. Create the gate first, then wire it as a prerequisite of the +blocked task. | Trigger | Command | |---------|---------| -| Wait for PR merge | `bd gate create --type=gh:pr --blocks= --await-id=42 --reason="PR #42 merge"` | -| Wait for CI | `bd gate create --type=gh:run --blocks= --await-id= --reason="CI green"` | -| Manual approval | `bd gate create --type=human --blocks= --reason="Staging approved"` | -| Timer / cooldown | `bd gate create --type=timer --blocks= --timeout=30m` | +| Wait for PR merge | `hew gate new --gh-pr=42 --title="PR #42 merged"` | +| Wait for CI / issue close / cmd | (deferred — only `--gh-pr` ships in v1; the `GateKind` enum scaffolds `GhIssue` / `GhRun` / `Cmd`) | +| Manual approval | create a normal task with title `"Approval: "`, leave it open until human closes — no special primitive needed | -Gate creation is a documented hold-out — `hew` has no `gate` wrapper yet -(`bd gate create` stays the path; `bd gate resolve ` closes manual -gates). Inspect with `bd gate list`. The `--blocks` flag does the -dependency wiring inline, so no separate `hew dep add` is needed. +Then attach the gate to the blocked task: + +``` +GATE=$(hew gate new --gh-pr=42 --title="PR #42 merged" --quiet) +hew dep add "$GATE" +``` + +Resolve gates periodically (or wire into a loop hook): `hew gate poll` +queries the external source and closes any whose state has resolved +(`MERGED` for `--gh-pr`). Inspect with `hew gate list`. ## Step 6 — pick types and priorities @@ -260,7 +324,10 @@ dependency wiring inline, so no separate `hew dep add` is needed. | `bug` | semantic alias — surfaces in bug queries | | `chore` | refactor, cleanup, non-feature | | `epic` | container; only closes when all children close | -| `gate` | external blocker (above) | +| `decision` | ADR-shaped record | + +(External-blocker gates use the dedicated `hew gate` surface above, not +a task type — see Step 5.) | `--priority=` | Meaning | |---------------|---------| @@ -275,6 +342,21 @@ dependency wiring inline, so no separate `hew dep add` is needed. Priority inflation kills the signal. Reserve P0 for the critical path. If everything is P0, you have not decomposed enough. +### Optional — flag heavy tasks for a stronger model + +If one task in the batch is meaningfully harder than the rest +(thorny refactor, gnarly algorithm, architectural call inside the +slice), route just that task to a stronger model when `hew loop` +spawns it. Two cheap surfaces, both per-task: + +- Add `` anywhere in the description. +- Or `bd label add model:opus-4-7` after the task lands. + +For batch-wide policy (e.g. "every P0 runs on opus-4-7"), use +`hew config set loop.model.by_priority.P0 opus-4-7` once and skip +the per-task annotation. See `docs/LOOP.md` "Per-task model +selection" for the full precedence chain. + ## Step 7 — concrete example, end to end User asks for "auth on an existing FastAPI app." Plan is approved. diff --git a/.claude/skills/hew/core/hew-execute.md b/.claude/skills/hew/core/hew-execute.md index 06fffc7..6375f34 100644 --- a/.claude/skills/hew/core/hew-execute.md +++ b/.claude/skills/hew/core/hew-execute.md @@ -1,4 +1,4 @@ - + --- name: hew-execute category: core @@ -457,9 +457,14 @@ it out. Future-you saves the lookup time. Run `hew prime execute` again. Pick the next ready task. Continue. -If the user said "do this one task," stop after closing it. If "keep going" -or `/hew:auto`, loop until `hew prime execute` shows no ready tasks (then call `hew-verify`) or -a Rule-4 architectural decision blocks you (then surface and stop). +If the user said "do this one task," stop after closing it. If "keep going," +loop until `hew prime execute` shows no ready tasks (then call `hew-verify`) +or a Rule-4 architectural decision blocks you (then surface and stop). + +If invoked via `/hew:auto`, the walk is scoped to the children of one +active epic (`hew epic tree `), not the global `bd ready` set — +finish the epic, run `/hew:verify`, then stop. For the subprocess loop +that drains the global queue with cache-warm prefixes, see `/hew:loop`. ### Step 10a — review picker (optional, config-gated) diff --git a/.claude/skills/hew/core/hew-guard.md b/.claude/skills/hew/core/hew-guard.md index f80690b..760bc20 100644 --- a/.claude/skills/hew/core/hew-guard.md +++ b/.claude/skills/hew/core/hew-guard.md @@ -1,4 +1,4 @@ - + --- name: hew-guard category: core diff --git a/.claude/skills/hew/core/hew-new-project.md b/.claude/skills/hew/core/hew-new-project.md index 6c3fc67..3892627 100644 --- a/.claude/skills/hew/core/hew-new-project.md +++ b/.claude/skills/hew/core/hew-new-project.md @@ -1,4 +1,4 @@ - + --- name: hew-new-project category: core diff --git a/.claude/skills/hew/core/hew-plan.md b/.claude/skills/hew/core/hew-plan.md index e6d0426..12f26bc 100644 --- a/.claude/skills/hew/core/hew-plan.md +++ b/.claude/skills/hew/core/hew-plan.md @@ -1,4 +1,4 @@ - + --- name: hew-plan category: core @@ -258,6 +258,16 @@ read these per-plan deviations *in addition to* the project's `CONVENTION:craft.*` memories. Deviations are scoped to the plan id; they do not bleed across features. +### Note for `hew loop` runs + +If you expect this plan to drive an autonomous `hew loop` and one or +two tasks are clearly heavier than the rest, mention it now — the +decomposer will mark those tasks with `` +or a `model:` label so the loop routes them to a stronger +model. Project-wide policy (e.g. "all P0s on opus-4-7") lives in +`loop.model.by_priority` / `loop.model.by_type` and is set once at +the config layer; see `docs/LOOP.md` "Per-task model selection." + ## What you don't do - **No tasks.** That is `hew-decompose`. Do not run `hew task new` here. @@ -286,8 +296,10 @@ On "Skip" or after `/hew:research` completes: "Plan is approved. Calling `hew-decompose` to build the Beads graph." Then invoke `hew-decompose` with the plan in context. `hew-decompose` will read the same memories, plus the conversation it inherits -from you, and produce `hew task new` / `hew dep add` calls (and `bd -create --type=gate` for external blockers; gates aren't wrapped). +from you, and produce `bd create --graph` for the task batch (or `hew task +new` for one-offs), `hew dep add` for cross-task ordering, and +`hew gate new --gh-pr=N` for external blockers (e.g. a downstream epic +that waits on a PR merge). After `hew-decompose` finishes, write the phase marker: diff --git a/.claude/skills/hew/core/hew-verify.md b/.claude/skills/hew/core/hew-verify.md index 41726f3..507ffcd 100644 --- a/.claude/skills/hew/core/hew-verify.md +++ b/.claude/skills/hew/core/hew-verify.md @@ -1,4 +1,4 @@ - + --- name: hew-verify category: core diff --git a/.claude/skills/hew/optional/hew-adversarial-review.md b/.claude/skills/hew/optional/hew-adversarial-review.md index ded4569..b435de0 100644 --- a/.claude/skills/hew/optional/hew-adversarial-review.md +++ b/.claude/skills/hew/optional/hew-adversarial-review.md @@ -1,4 +1,4 @@ - + --- name: hew-adversarial-review category: optional diff --git a/.claude/skills/hew/optional/hew-blast.md b/.claude/skills/hew/optional/hew-blast.md index d68be17..5b6c15d 100644 --- a/.claude/skills/hew/optional/hew-blast.md +++ b/.claude/skills/hew/optional/hew-blast.md @@ -1,4 +1,4 @@ - + --- name: hew-blast category: optional diff --git a/.claude/skills/hew/optional/hew-compact.md b/.claude/skills/hew/optional/hew-compact.md index b20c178..612e5be 100644 --- a/.claude/skills/hew/optional/hew-compact.md +++ b/.claude/skills/hew/optional/hew-compact.md @@ -1,4 +1,4 @@ - + --- name: hew-compact category: optional diff --git a/.claude/skills/hew/optional/hew-deps.md b/.claude/skills/hew/optional/hew-deps.md index 30f7749..08ba40b 100644 --- a/.claude/skills/hew/optional/hew-deps.md +++ b/.claude/skills/hew/optional/hew-deps.md @@ -1,4 +1,4 @@ - + --- name: hew-deps category: optional diff --git a/.claude/skills/hew/optional/hew-quick.md b/.claude/skills/hew/optional/hew-quick.md index a53e423..06c9568 100644 --- a/.claude/skills/hew/optional/hew-quick.md +++ b/.claude/skills/hew/optional/hew-quick.md @@ -1,4 +1,4 @@ - + --- name: hew-quick category: optional diff --git a/.claude/skills/hew/optional/hew-research.md b/.claude/skills/hew/optional/hew-research.md index a09de9a..c78aa55 100644 --- a/.claude/skills/hew/optional/hew-research.md +++ b/.claude/skills/hew/optional/hew-research.md @@ -1,4 +1,4 @@ - + --- name: hew-research category: optional diff --git a/.claude/skills/hew/optional/hew-review.md b/.claude/skills/hew/optional/hew-review.md index 2bcc5e5..8f1cb50 100644 --- a/.claude/skills/hew/optional/hew-review.md +++ b/.claude/skills/hew/optional/hew-review.md @@ -1,4 +1,4 @@ - + --- name: hew-review category: optional diff --git a/.claude/skills/hew/optional/hew-security.md b/.claude/skills/hew/optional/hew-security.md index 4a9c50c..72b44e0 100644 --- a/.claude/skills/hew/optional/hew-security.md +++ b/.claude/skills/hew/optional/hew-security.md @@ -1,4 +1,4 @@ - + --- name: hew-security category: optional diff --git a/.claude/skills/hew/optional/hew-spec.md b/.claude/skills/hew/optional/hew-spec.md index d61e4b0..8d922c5 100644 --- a/.claude/skills/hew/optional/hew-spec.md +++ b/.claude/skills/hew/optional/hew-spec.md @@ -1,4 +1,4 @@ - + --- name: hew-spec category: optional diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f18447..c9fb4d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ versioning follows [Semantic Versioning](https://semver.org/). ## [Unreleased] +## [0.11.0] — 2026-05-30 + ### Added - **`hew loop graph` DAG renderer (`hew-m7lq`).** Renders the loop's diff --git a/Cargo.lock b/Cargo.lock index 732ef79..e44daf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,7 +893,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hew" -version = "0.10.0" +version = "0.11.0" dependencies = [ "anstream", "anstyle", @@ -924,7 +924,7 @@ dependencies = [ [[package]] name = "hew-core" -version = "0.10.0" +version = "0.11.0" dependencies = [ "etcetera", "insta", diff --git a/Cargo.toml b/Cargo.toml index 312de5e..1e76a55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["hew-core", "hew"] [workspace.package] -version = "0.10.0" +version = "0.11.0" edition = "2024" rust-version = "1.91" license = "MIT" diff --git a/skills/SKILL.md b/skills/SKILL.md index 0663488..41f93cb 100644 --- a/skills/SKILL.md +++ b/skills/SKILL.md @@ -1,4 +1,4 @@ - + --- name: hew description: Index of installed hew skills. Loaded by the agent on session start. diff --git a/skills/brownfield/hew-audit.md b/skills/brownfield/hew-audit.md index 5711955..24e4f4f 100644 --- a/skills/brownfield/hew-audit.md +++ b/skills/brownfield/hew-audit.md @@ -1,4 +1,4 @@ - + --- name: hew-audit category: brownfield diff --git a/skills/brownfield/hew-boundary.md b/skills/brownfield/hew-boundary.md index c917757..cc1f800 100644 --- a/skills/brownfield/hew-boundary.md +++ b/skills/brownfield/hew-boundary.md @@ -1,4 +1,4 @@ - + --- name: hew-boundary category: brownfield diff --git a/skills/brownfield/hew-convention.md b/skills/brownfield/hew-convention.md index 2d28cf7..f2435b2 100644 --- a/skills/brownfield/hew-convention.md +++ b/skills/brownfield/hew-convention.md @@ -1,4 +1,4 @@ - + --- name: hew-convention category: brownfield diff --git a/skills/brownfield/hew-migrate.md b/skills/brownfield/hew-migrate.md index 82ba323..47b67b9 100644 --- a/skills/brownfield/hew-migrate.md +++ b/skills/brownfield/hew-migrate.md @@ -1,4 +1,4 @@ - + --- name: hew-migrate category: brownfield diff --git a/skills/brownfield/hew-scan.md b/skills/brownfield/hew-scan.md index 8e2b0f7..6ac5d89 100644 --- a/skills/brownfield/hew-scan.md +++ b/skills/brownfield/hew-scan.md @@ -1,4 +1,4 @@ - + --- name: hew-scan category: brownfield diff --git a/skills/core/hew-checkpoint.md b/skills/core/hew-checkpoint.md index b55929e..3efbf24 100644 --- a/skills/core/hew-checkpoint.md +++ b/skills/core/hew-checkpoint.md @@ -1,4 +1,4 @@ - + --- name: hew-checkpoint category: core diff --git a/skills/core/hew-decompose.md b/skills/core/hew-decompose.md index c908419..6525f6b 100644 --- a/skills/core/hew-decompose.md +++ b/skills/core/hew-decompose.md @@ -1,4 +1,4 @@ - + --- name: hew-decompose category: core diff --git a/skills/core/hew-execute.md b/skills/core/hew-execute.md index 0c3b0db..6375f34 100644 --- a/skills/core/hew-execute.md +++ b/skills/core/hew-execute.md @@ -1,4 +1,4 @@ - + --- name: hew-execute category: core diff --git a/skills/core/hew-guard.md b/skills/core/hew-guard.md index f80690b..760bc20 100644 --- a/skills/core/hew-guard.md +++ b/skills/core/hew-guard.md @@ -1,4 +1,4 @@ - + --- name: hew-guard category: core diff --git a/skills/core/hew-new-project.md b/skills/core/hew-new-project.md index 6c3fc67..3892627 100644 --- a/skills/core/hew-new-project.md +++ b/skills/core/hew-new-project.md @@ -1,4 +1,4 @@ - + --- name: hew-new-project category: core diff --git a/skills/core/hew-plan.md b/skills/core/hew-plan.md index 981ee49..12f26bc 100644 --- a/skills/core/hew-plan.md +++ b/skills/core/hew-plan.md @@ -1,4 +1,4 @@ - + --- name: hew-plan category: core diff --git a/skills/core/hew-verify.md b/skills/core/hew-verify.md index 41726f3..507ffcd 100644 --- a/skills/core/hew-verify.md +++ b/skills/core/hew-verify.md @@ -1,4 +1,4 @@ - + --- name: hew-verify category: core diff --git a/skills/data/planner-prompt.md b/skills/data/planner-prompt.md index edc4690..4b05043 100644 --- a/skills/data/planner-prompt.md +++ b/skills/data/planner-prompt.md @@ -1,4 +1,4 @@ - + # Hew loop — batch planner You are the planner subprocess inside `hew loop run --jobs N`. Your only diff --git a/skills/optional/hew-adversarial-review.md b/skills/optional/hew-adversarial-review.md index ded4569..b435de0 100644 --- a/skills/optional/hew-adversarial-review.md +++ b/skills/optional/hew-adversarial-review.md @@ -1,4 +1,4 @@ - + --- name: hew-adversarial-review category: optional diff --git a/skills/optional/hew-blast.md b/skills/optional/hew-blast.md index d68be17..5b6c15d 100644 --- a/skills/optional/hew-blast.md +++ b/skills/optional/hew-blast.md @@ -1,4 +1,4 @@ - + --- name: hew-blast category: optional diff --git a/skills/optional/hew-compact.md b/skills/optional/hew-compact.md index b20c178..612e5be 100644 --- a/skills/optional/hew-compact.md +++ b/skills/optional/hew-compact.md @@ -1,4 +1,4 @@ - + --- name: hew-compact category: optional diff --git a/skills/optional/hew-deps.md b/skills/optional/hew-deps.md index 30f7749..08ba40b 100644 --- a/skills/optional/hew-deps.md +++ b/skills/optional/hew-deps.md @@ -1,4 +1,4 @@ - + --- name: hew-deps category: optional diff --git a/skills/optional/hew-quick.md b/skills/optional/hew-quick.md index a53e423..06c9568 100644 --- a/skills/optional/hew-quick.md +++ b/skills/optional/hew-quick.md @@ -1,4 +1,4 @@ - + --- name: hew-quick category: optional diff --git a/skills/optional/hew-research.md b/skills/optional/hew-research.md index a09de9a..c78aa55 100644 --- a/skills/optional/hew-research.md +++ b/skills/optional/hew-research.md @@ -1,4 +1,4 @@ - + --- name: hew-research category: optional diff --git a/skills/optional/hew-review.md b/skills/optional/hew-review.md index 2bcc5e5..8f1cb50 100644 --- a/skills/optional/hew-review.md +++ b/skills/optional/hew-review.md @@ -1,4 +1,4 @@ - + --- name: hew-review category: optional diff --git a/skills/optional/hew-security.md b/skills/optional/hew-security.md index 4a9c50c..72b44e0 100644 --- a/skills/optional/hew-security.md +++ b/skills/optional/hew-security.md @@ -1,4 +1,4 @@ - + --- name: hew-security category: optional diff --git a/skills/optional/hew-spec.md b/skills/optional/hew-spec.md index d61e4b0..8d922c5 100644 --- a/skills/optional/hew-spec.md +++ b/skills/optional/hew-spec.md @@ -1,4 +1,4 @@ - + --- name: hew-spec category: optional From 35bbf0868c63d318f49ddd553e1188ba51a17f31 Mon Sep 17 00:00:00 2001 From: droidnoob Date: Sat, 30 May 2026 17:51:03 +0530 Subject: [PATCH 2/2] docs(readme): reflect 0.11.0 surface changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /hew:auto description updated to in-conversation epic walk (was the legacy plan→decompose→execute→verify; rewritten in hew-6n0v / #56) - slash count 40 → 41 (new /hew:auto + various) - loop snippets show --scope (required in non-interactive mode per hew-b3yl / #58), --jobs N, --verify-tests, hew loop summary, hew loop graph - autonomous-loop bullets gain parallel-workers, scoped-runs + per-task-model, end-of-run-verification entries - Selected knobs table adds loop.model.*, loop.planner.*, loop.end_of_run.verify_tests, loop.fallback_runtime No changes to brand, hero copy, or repo description. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e707c12..5425e95 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Hew inverts that. **Beads is the graph. The agent queries it.** There's a known trick for autonomous coding — [Ralph](https://ghuntley.com/ralph/), Geoffrey Huntley's one-liner that pipes a prompt into the agent in an infinite shell loop. It works better than it has any right to, and it's where `hew loop` starts. The difference is what hew adds around the loop so it can run unattended without drifting: ```sh -hew loop run --until-empty +hew loop run --scope=ready ```

@@ -53,7 +53,10 @@ hew loop run --until-empty - **The graph is the state.** Each iter asks `bd ready` for the next unblocked task instead of re-reading a prose prompt that drifts. The agent queries; it doesn't re-narrate what to do next. - **A backpressure gate with rollback.** After each iter, hew runs your project's tests and lint; if they fail, the iter is reverted with `git reset --hard ` so a bad pass can't compound. The gate runs *your* commands — a `test` / `lint` target in your `Makefile`, a `justfile` recipe, or a `package.json` script — across Rust, Python, Go, Node, whatever your project already uses. No signal, no gate: the loop trusts the agent and keeps moving. - **A byte-stable prompt prefix.** The skill body and memory primer are identical across iters, so the prompt cache hits instead of paying full input cost every pass. -- **Budgets and clean stops.** `--max-iter`, `--budget-tokens`, `--budget-wall`, and `--until-empty` bound the run; Ctrl+C lets the in-flight iter finish cleanly rather than corrupting state. +- **Parallel workers via git worktrees.** `--jobs N` fans out across N out-of-tree worktrees at `~/.hew/wt///`, merges each worker's branch back at shutdown, and files a `[merge-conflict]` bug task if any merge isn't clean. `--jobs=1` (the default) is byte-identical to today's single-worker loop. +- **Scoped runs and per-task models.** `--scope=epics --epics=hew-XXXX` restricts the run to one epic's descendants; `loop.model.by_priority`/`by_type` route heavy tasks to a stronger model without changing the rest of the queue. Per-iter token spend is reported per model in the summary. +- **End-of-run verification (opt-in).** `--verify-tests` (or `loop.end_of_run.verify_tests = true`) runs your test command after the last iter to prove the final stacked state is green; failures surface as a `STATUS:loop-verify-failed:` memory plus a non-zero exit. +- **Budgets and clean stops.** `--max-iter`, `--budget-tokens`, `--budget-wall`, and `--until-empty` (default) bound the run; Ctrl+C lets the in-flight iter finish cleanly rather than corrupting state. Full guide: [`docs/LOOP.md`](./docs/LOOP.md). @@ -241,7 +244,7 @@ Open your agent (Claude Code, Cursor, etc.) and route on intent — skills auto- /hew:next Claim the top unblocked task and start work /hew:verify End-to-end verification after a batch closes /hew:quick Fast mode — one task, no plan overhead -/hew:auto Run plan → decompose → execute → verify autonomously +/hew:auto Walk the active epic in-conversation, one task at a time /hew:loop Drive the autonomous outer loop (process-level) ``` @@ -250,16 +253,23 @@ ready queue across many tasks while you do something else — drive [the loop](#the-autonomous-loop) directly: ```sh -hew loop run --until-empty # drain everything ready -hew loop run --max-iter 5 # bounded -hew loop run --unattended # auto-resolve DEFERRED: memories -hew loop list # recent runs -hew loop logs --tail 5 # last 5 iters of latest run -hew loop cancel # touch stop-file on latest run +hew loop run --scope=ready # drain every bd-ready task +hew loop run --scope=epics --epics=hew-XXXX # one epic only +hew loop run --scope=ready --jobs 4 # 4 parallel workers via git worktrees +hew loop run --scope=ready --verify-tests # run your test suite after the last iter +hew loop run --max-iter 5 --budget-tokens 200k # bounded +hew loop list # recent runs +hew loop logs --tail 5 # last 5 iters of latest run +hew loop summary # re-render the end-of-run report +hew loop graph # render the run as a mermaid DAG +hew loop cancel # touch stop-file on latest run ``` End of run prints a summary with the cache hit rate, token breakdown, a -sparkline of per-iter spend, and the symbols the run touched. +sparkline of per-iter spend, and the symbols the run touched. With +`--jobs N` the same summary adds a per-worker table; with `--verify-tests` +it adds a `verify:` line and a `STATUS:loop-verify-failed:` memory on +failure. On Claude Code the agent statusline shows what hew is working on (scope, progress bar, phase, epic fraction) — auto-wired by `hew init --runtime=claude`. See `hew statusline --help` for `--compact` / `--full` / `--width` overrides. @@ -278,13 +288,13 @@ A brief table of the most-used slashes. Full reference: [`docs/COMMANDS.md`](./d | `/hew:quick` | One task, one commit — no plan/decompose overhead | | `/hew:verify` | Batch-level end-to-end verification | | `/hew:ship` | Create a PR and prepare for merge after verify passes | -| `/hew:auto` | Run plan → decompose → execute → verify autonomously | +| `/hew:auto` | Walk the active epic in this Claude session, one task at a time | | `/hew:loop` | Drive the autonomous outer loop (process-level, drains the ready queue) | | `/hew:checkpoint` | Save rich session state before `/clear` | | `/hew:status` | Human-readable project state | | `/hew:compact` | Reduce a noisy memory prefix from N entries to ~K canonical ones | -**40 total slashes** covering: +**41 total slashes** covering: - Brownfield onboarding — `/hew:scan`, `/hew:convention`, `/hew:audit`, `/hew:boundary`, `/hew:migrate` - Reviews — `/hew:review`, `/hew:adversarial-review` @@ -354,6 +364,13 @@ Selected knobs: | `craft.max_function_lines` | `0` | Soft-warn when a changed function exceeds this many lines (0 = disabled) | | `compact.dry_run_default` | `true` | `/hew:compact` starts in dry-run mode unless `--apply` passed | | `review.after_n_tasks` | `0` | Fire the review picker after this many closed tasks (0 = disabled) | +| `loop.model.default` | unset | Model passed to the spawner per iter; precedence is description-tag > label > `by_priority` > `by_type` > this | +| `loop.model.by_priority` | `{}` | Per-priority override map, e.g. `{ "0" = "claude-opus-4-7", "2" = "claude-sonnet-4-6" }` | +| `loop.model.by_type` | `{}` | Per-task-type override map, e.g. `{ "bug" = "claude-opus-4-7" }` | +| `loop.planner.enabled` | `true` | When `--jobs >= 2` and the iter agent didn't suggest a `next_iteration`, spawn a small planner subprocess to pick the next batch | +| `loop.planner.budget_tokens` | `10000` | Pre-spawn budget cap; planner skips rather than truncating context when over | +| `loop.end_of_run.verify_tests` | `false` | Opt-in mandatory test step after the last iter (stack-detected test command + budget cap) | +| `loop.fallback_runtime` | unset | When set (`claude` / `codex`), the loop switches to it on `RuntimeError` for `loop.fallback_cooldown_iters` iters before retrying primary | Run `hew config keys` for the full list.