[rig-claude] Improve Claude dynamic-workflow compatibility for rig - #309
Conversation
Demonstrates the three Claude dynamic-workflow primitives (log, budget, until) that had no sample-level example. Maps directly to Claude's log(message), budget.remaining(), and open-ended while convergence loops. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
There was a problem hiding this comment.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 58.3 AIC · ⌖ 4.07 AIC · ⊞ 6.3K
Comment /matt to run again
| phase("Crawl"); | ||
| const pages: { url: string; summary: string }[] = []; | ||
|
|
||
| await until({ max: 20, noProgressRounds: 3 }, async (_, round) => { |
There was a problem hiding this comment.
[/grill-with-docs] until state accumulator is ignored — pages is mutated via closure rather than threaded through the state parameter.
The UntilStep<S> contract passes the previous return's state value into the next call as the first argument. The sample names it _ and instead mutates pages via closure, which works (same reference), but obscures the state-threading contract — especially confusing for developers porting a Claude dynamic workflow who expect state to flow through until.
💡 Idiomatic rewrite
Thread state explicitly:
await until({ max: 20, noProgressRounds: 3 }, async (state: typeof pages = [], round) => {
// ...
if (result) state.push({ url, summary: result.summary });
return { state, done, progressKey: `${visited.size}` };
});Or add a comment explaining the identity relationship if the closure style is intentional.
Compatibility gap addressed
log,budget, anduntilare three Claude dynamic-workflow primitives with direct rig equivalents documented inclaude-workflow-conversion.md, but no existing sample demonstrated their use. A developer porting a Claude workflow that useslog(message), guards a loop withbudget.remaining(), or replaces an open-endedwhileloop withuntilhad nowhere to look for a working rig example.Why this improves transfer
Sample 320 (
320-budget-aware-crawler.md) shows all three concepts together in a realistic, runnable program:log(...)— structured progress messages visible in the event streambudget.remaining()— agent-call budget guard inside a loopuntil({ max, noProgressRounds }, step)— bounded convergence replacing an open-endedwhileThe header comment references
claude-workflow-conversion.mdso the sample serves as a direct bridge for anyone searching after reading the conversion table.Files changed
skills/rig/samples/320-budget-aware-crawler.md— new sampleValidation run
391 tests, 1 passed (390 skipped/unrelated). TypeScript extracted from the new sample typechecks cleanly.
Remaining intentional differences
None introduced. Existing documented differences (
effort,agentType, resume journal, sandboxing) are unchanged.