Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/node/builtinSkills/loop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
name: loop
description: Route agent/control-loop requests (polling, reconciliation, retry-until-done, continuous work, repeated workspace creation) to the lightest safe mechanism before acting
---

# Loop

Use this skill before acting on requests that ask you to keep doing agent/control-loop work until a state converges: polling, reconciliation, retry-until-done, continuous work, or repeated workspace creation.

## Route first

1. **Identify the user's intent.** If the user asks conceptually, explain options. If the user asks you to execute and the safe route is clear, act with stated assumptions.
2. **Classify the loop.** Decide whether it is one-off, deterministic, workspace-dispatching, multi-turn, scheduled, durable/reusable, UI-driven, or product behavior.
3. **Choose the lightest safe mechanism.** Do not create a workflow just because the prompt says "loop".
4. **Add loop guards before side effects.** Define convergence, duplicate detection, budget, and stop conditions before creating workspaces, tasks, commits, or external updates.

## Mechanism chooser

| Need | Prefer | Notes |
| ------------------------------------------------------ | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| One-off orchestration in the current conversation | Ad-hoc agent/tool loop | Inspect state, compute missing work, call tools, re-read state, repeat with a bound. |
| Create one or more child workspaces | `task` workspace creation mode | Re-check existing workspaces first; track returned workspace/task IDs; cap fanout. |
| Parallel independent items | `task` `variants`/`n`, or workflow `parallelAgents` when already in a workflow | Use variants for named lanes; use best-of-n only when the user asks for competing candidates. |
| Deterministic reconciliation | `bash` script, project CLI, or API | Prefer code over model judgment for pure bookkeeping. Make it idempotent and bounded. |
| Current agent should continue across automatic turns | `set_goal` | Use only for explicit multi-turn, verifiable work; do not replace an active goal unless asked. |
| Recurring reminder/continuation for this workspace | `heartbeat` | Suitable for idle check-ins, not wall-clock reconciliation or hiding an unbounded polling process. |
| Wall-clock recurring reconciliation | Workflow schedule or product scheduler/reconciler | Use scheduled/workflow/product mechanisms when cadence must ignore workspace activity. |
| Durable, resumable, reusable multi-agent orchestration | Workflow | Read `workflow-authoring`; reuse an existing workflow before authoring one. Workflow conductors coordinate agents and patches, not arbitrary host operations directly. |
| GUI/browser loop | `agent-browser`, `dogfood`, or desktop delegation | Use the screenshot/action/verify loop and attach evidence when visual verification matters. |
| The app itself should keep reconciling over time | Product scheduler/reconciler service | Implement persisted desired state, actual-state observation, idempotency keys, tests, and operator-visible status. |
| Existing PR must be driven to readiness | Repo PR loop | Follow repo instructions for local gates, push, review comments, CI, and readiness scripts. |

## Guard every loop

Before the first side effect, write down or infer these invariants:

- **Desired state:** what should exist when the loop is done.
- **Actual-state read:** the tool/API/files that prove what exists now.
- **Convergence:** the exact condition that stops the loop.
- **Idempotency key:** how retries identify the same work item/workspace instead of creating duplicates.
- **Bounds:** max attempts, max fanout, time/budget limit, and what to do on repeated failure.
- **Ordering:** whether items are independent, sequential, or require apply/verify between batches.
- **Visibility:** how you will report spawned tasks/workspaces and blockers to the user.

Re-read actual state immediately before every create/update operation. If the state changed, recompute rather than continuing from stale assumptions.

## Ask when the route changes risk

Ask a short clarifying question instead of guessing when any of these are ambiguous:

- One-off action vs reusable workflow vs product behavior.
- Persistent vs disposable workspace creation.
- Duplicate detection or idempotency keys.
- Whether to wait for child workspace results or leave them running.
- Maximum attempts, budget, or fanout.
- Whether recurring work should survive app/agent interruption.

If the ambiguity is small and the safe default is obvious, state the assumption and proceed. Do not ask questions merely to avoid doing straightforward work.

## Safe ad-hoc pattern

For a one-off reconcile loop in this conversation:

1. Inspect actual state with the narrowest reliable tools.
2. Build the desired item list and an idempotency key per item.
3. Compute missing or stale items.
4. If none are missing, stop and report convergence.
5. Create/update only the missing items, recording returned IDs.
6. Await only when the next decision depends on the result.
7. Re-inspect state and repeat until converged or bounded out.

On bounded-out failure, stop spinning. Report the last observed state, attempted actions, remaining delta, and the next decision needed.

## Workflow route

Choose a workflow only when durability/reuse/resume or structured multi-agent phases justify the overhead. Before authoring one:

1. Run `workflow_list` to look for an existing workflow.
2. Read `workflow-authoring`.
3. Encode the loop as bounded control flow with clear `phase`/`log` events.
4. Delegate filesystem/shell/web investigation or implementation to workflow-owned agents.
5. Resume interrupted runs with `workflow_resume`; do not re-run completed steps manually.

## Avoid these traps

- Do not use `heartbeat` for wall-clock reconciliation; it is idle-recency gated and may be deferred by activity.
- Do not busy-poll with repeated tool calls. Prefer one blocking wait, a bounded script, or an awaited task/workflow.
- Do not treat `task` `isolation: "none"` as a loop or safety mechanism. Use it only for read-only or no-overlap work when sharing the parent checkout is acceptable.
- Do not assume workspace names or tags alone make creation idempotent. Re-read actual state and use a stable idempotency key before every create.

## Completion criteria

You are done when either:

- the actual-state read proves convergence and every created task/workspace that must be awaited has reached the required state, or
- the loop hit a declared bound/blocker and you reported the remaining delta plus the next human decision.
2 changes: 2 additions & 0 deletions src/node/services/agentSkills/agentSkillsService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ describe("agentSkillsService", () => {
"bar",
"foo",
"init",
"loop",
"mux-diagram",
"mux-docs",
"orchestrate",
Expand Down Expand Up @@ -661,6 +662,7 @@ describe("agentSkillsService", () => {
expect(diagnostics.skills.map((s) => s.name)).toEqual([
"foo",
"init",
"loop",
"mux-diagram",
"mux-docs",
"orchestrate",
Expand Down
16 changes: 16 additions & 0 deletions src/node/services/agentSkills/builtInLoopSkill.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, expect, test } from "bun:test";

import { SkillNameSchema } from "@/common/orpc/schemas";
import { getBuiltInSkillDescriptors } from "./builtInSkillDefinitions";

describe("built-in loop skill", () => {
const name = SkillNameSchema.parse("loop");

test("is registered as a model-invoked built-in skill", () => {
const descriptor = getBuiltInSkillDescriptors().find((d) => d.name === name);

expect(descriptor).toBeDefined();
expect(descriptor!.scope).toBe("built-in");
expect(descriptor!.advertise).not.toBe(false);
});
});
101 changes: 101 additions & 0 deletions src/node/services/agentSkills/builtInSkillContent.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,107 @@ export const BUILTIN_SKILL_FILES: Record<string, Record<string, string>> = {
"",
].join("\n"),
},
loop: {
"SKILL.md": [
"---",
"name: loop",
"description: Route agent/control-loop requests (polling, reconciliation, retry-until-done, continuous work, repeated workspace creation) to the lightest safe mechanism before acting",
"---",
"",
"# Loop",
"",
"Use this skill before acting on requests that ask you to keep doing agent/control-loop work until a state converges: polling, reconciliation, retry-until-done, continuous work, or repeated workspace creation.",
"",
"## Route first",
"",
"1. **Identify the user's intent.** If the user asks conceptually, explain options. If the user asks you to execute and the safe route is clear, act with stated assumptions.",
"2. **Classify the loop.** Decide whether it is one-off, deterministic, workspace-dispatching, multi-turn, scheduled, durable/reusable, UI-driven, or product behavior.",
'3. **Choose the lightest safe mechanism.** Do not create a workflow just because the prompt says "loop".',
"4. **Add loop guards before side effects.** Define convergence, duplicate detection, budget, and stop conditions before creating workspaces, tasks, commits, or external updates.",
"",
"## Mechanism chooser",
"",
"| Need | Prefer | Notes |",
"| ------------------------------------------------------ | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |",
"| One-off orchestration in the current conversation | Ad-hoc agent/tool loop | Inspect state, compute missing work, call tools, re-read state, repeat with a bound. |",
"| Create one or more child workspaces | `task` workspace creation mode | Re-check existing workspaces first; track returned workspace/task IDs; cap fanout. |",
"| Parallel independent items | `task` `variants`/`n`, or workflow `parallelAgents` when already in a workflow | Use variants for named lanes; use best-of-n only when the user asks for competing candidates. |",
"| Deterministic reconciliation | `bash` script, project CLI, or API | Prefer code over model judgment for pure bookkeeping. Make it idempotent and bounded. |",
"| Current agent should continue across automatic turns | `set_goal` | Use only for explicit multi-turn, verifiable work; do not replace an active goal unless asked. |",
"| Recurring reminder/continuation for this workspace | `heartbeat` | Suitable for idle check-ins, not wall-clock reconciliation or hiding an unbounded polling process. |",
"| Wall-clock recurring reconciliation | Workflow schedule or product scheduler/reconciler | Use scheduled/workflow/product mechanisms when cadence must ignore workspace activity. |",
"| Durable, resumable, reusable multi-agent orchestration | Workflow | Read `workflow-authoring`; reuse an existing workflow before authoring one. Workflow conductors coordinate agents and patches, not arbitrary host operations directly. |",
"| GUI/browser loop | `agent-browser`, `dogfood`, or desktop delegation | Use the screenshot/action/verify loop and attach evidence when visual verification matters. |",
"| The app itself should keep reconciling over time | Product scheduler/reconciler service | Implement persisted desired state, actual-state observation, idempotency keys, tests, and operator-visible status. |",
"| Existing PR must be driven to readiness | Repo PR loop | Follow repo instructions for local gates, push, review comments, CI, and readiness scripts. |",
"",
"## Guard every loop",
"",
"Before the first side effect, write down or infer these invariants:",
"",
"- **Desired state:** what should exist when the loop is done.",
"- **Actual-state read:** the tool/API/files that prove what exists now.",
"- **Convergence:** the exact condition that stops the loop.",
"- **Idempotency key:** how retries identify the same work item/workspace instead of creating duplicates.",
"- **Bounds:** max attempts, max fanout, time/budget limit, and what to do on repeated failure.",
"- **Ordering:** whether items are independent, sequential, or require apply/verify between batches.",
"- **Visibility:** how you will report spawned tasks/workspaces and blockers to the user.",
"",
"Re-read actual state immediately before every create/update operation. If the state changed, recompute rather than continuing from stale assumptions.",
"",
"## Ask when the route changes risk",
"",
"Ask a short clarifying question instead of guessing when any of these are ambiguous:",
"",
"- One-off action vs reusable workflow vs product behavior.",
"- Persistent vs disposable workspace creation.",
"- Duplicate detection or idempotency keys.",
"- Whether to wait for child workspace results or leave them running.",
"- Maximum attempts, budget, or fanout.",
"- Whether recurring work should survive app/agent interruption.",
"",
"If the ambiguity is small and the safe default is obvious, state the assumption and proceed. Do not ask questions merely to avoid doing straightforward work.",
"",
"## Safe ad-hoc pattern",
"",
"For a one-off reconcile loop in this conversation:",
"",
"1. Inspect actual state with the narrowest reliable tools.",
"2. Build the desired item list and an idempotency key per item.",
"3. Compute missing or stale items.",
"4. If none are missing, stop and report convergence.",
"5. Create/update only the missing items, recording returned IDs.",
"6. Await only when the next decision depends on the result.",
"7. Re-inspect state and repeat until converged or bounded out.",
"",
"On bounded-out failure, stop spinning. Report the last observed state, attempted actions, remaining delta, and the next decision needed.",
"",
"## Workflow route",
"",
"Choose a workflow only when durability/reuse/resume or structured multi-agent phases justify the overhead. Before authoring one:",
"",
"1. Run `workflow_list` to look for an existing workflow.",
"2. Read `workflow-authoring`.",
"3. Encode the loop as bounded control flow with clear `phase`/`log` events.",
"4. Delegate filesystem/shell/web investigation or implementation to workflow-owned agents.",
"5. Resume interrupted runs with `workflow_resume`; do not re-run completed steps manually.",
"",
"## Avoid these traps",
"",
"- Do not use `heartbeat` for wall-clock reconciliation; it is idle-recency gated and may be deferred by activity.",
"- Do not busy-poll with repeated tool calls. Prefer one blocking wait, a bounded script, or an awaited task/workflow.",
'- Do not treat `task` `isolation: "none"` as a loop or safety mechanism. Use it only for read-only or no-overlap work when sharing the parent checkout is acceptable.',
"- Do not assume workspace names or tags alone make creation idempotent. Re-read actual state and use a stable idempotency key before every create.",
"",
"## Completion criteria",
"",
"You are done when either:",
"",
"- the actual-state read proves convergence and every created task/workspace that must be awaited has reached the required state, or",
"- the loop hit a declared bound/blocker and you reported the remaining delta plus the next human decision.",
"",
].join("\n"),
},
"mux-diagram": {
"SKILL.md": [
"---",
Expand Down
Loading