Skip to content

Team loop ​

This path is for moving a story, an epic or a workshop of evolutions forward through a three-role loop: an analyst, a senior developer and a QA engineer take turns on the OPALE pipe. You come here when you want the agent to chain the work instead of driving it step by step.

The engine does not run any agent itself: it returns the contract for the next act, your agent runs it (with a sub-agent if it has one), then reports the result.

What you ask the agent ​

💬 You ask your agent

« Start the team loop on the current epic. »

→ The agent callseffortless_crew_init
  • goal = the current epic
💬 You ask your agent

« Run the team on this story only, with pnpm test and pnpm lint as the bar. »

→ The agent callseffortless_crew_init
  • goal = this story only
  • bar = {"test":"pnpm test","lint":"pnpm lint"}
💬 You ask your agent

« Where is the loop? Who has to act now? »

→ The agent callseffortless_crew_status
💬 You ask your agent

« Show me the full trace of what happened in the loop. »

→ The agent callseffortless_crew_status
  • full = true
💬 You ask your agent

« Classify task TSK-03 as complex, deep tier, high effort, and tell me which model that gives. »

→ The agent callseffortless_task_classify
  • task_id = TSK-03
  • complexity = complex
  • capability_tier = deep
  • effort_level = high
💬 You ask your agent

« Generate a provider profile from the claude preset, for this project only. »

→ The agent callseffortless_provider_profile_init
  • family = claude
  • scope = project
💬 You ask your agent

« Show me the available provider presets and my current profile. »

💬 You ask your agent

« Start the autonomous loop on the simple tasks of the backlog. »

→ The agent callseffortless_loop_init
  • goal = the simple tasks of the backlog

What the agent does ​

Start the team loop ​

  1. effortless_crew_init takes goal (the objective, repeated in every role's brief) and scope: story, epic (default), all or workshop. max_rounds (100 by default) and max_epics (3 by default) cap the loop; 0 means unlimited.
  2. bar declares the mechanical bar: an object that maps a name (test, lint, typecheck, build) to a command, or to an object with command and optionally cwd or stack. At least one command is needed, and it must be runnable: an unmeasured command would never be green and QA could never return go.
  3. force: true overwrites a loop that is already initialized.
  4. With scope all, when there is no epic left to deliver, the loop enters the evolutions workshop and graduates an axis into the next epic, up to max_epics.

Run one round of the loop ​

  1. effortless_crew_step returns the contract for the current act: which role must act, the recommended model and effort, the expected output, and prompt_path, the path of a file that holds the brief (a prompt key). The agent reads that file before starting the sub-agent. Called twice, effortless_crew_step returns the same thing twice: it advances nothing. document targets a specific framing document.
  2. The role performs the act.
  3. effortless_crew_report reports the result: role (analyst, developer or qa, the one the step expects), verdict (done for the analyst and the developer, go or no-go for QA), summary, and payload (the role's structured output). For a payload too large to pass inline, payload_path points to a JSON file instead, never both.
  4. effortless_crew_report measures the mechanical bar before returning; the call can be long. It returns the next act directly.
  5. At delivery, the engine itself commits the task's work, then the closure. It repeats the round until the scope is covered or a cap is reached. Three no-go in a row stop the loop.

Follow the loop ​

  1. effortless_crew_status reads the state without changing anything: step, expected role, epic / story / task pointer, counters, caps, end reason (scope_covered, epics_exhausted or rounds_exhausted, null while the loop runs) and a dated ledger of the acts. By default only the latest acts are returned; full: true returns the full trace.

Route a task to a model tier ​

  1. effortless_task_classify classifies a task of the active story on one or more axes: complexity (simple or complex), capability_tier (deep, standard or light), effort_level (low, medium or high). At least one is required; an omitted axis is left unchanged.
  2. effortless_task_route_show returns the resolved recommendation: tier and effort, translated into a concrete model and a native effort by your provider profile (project profile first, then global). Without classification, the default is standard / medium. It is a suggestion, never an obligation.

Set up providers ​

  1. effortless_provider_presets_list lists the embedded and custom presets.
  2. effortless_provider_profile_show reads your active profile.
  3. effortless_provider_profile_init (re)generates the profile, a tier × effort matrix, from a preset family: claude, codex, gemini, mistral or a free name. scope is global (default) or project. An existing profile is overwritten only with force: true.

The autonomous loop ​

A simpler loop that takes the backlog tasks one by one.

  1. effortless_loop_init starts it with a goal.
  2. effortless_loop_step advances it: Plan, Implementation, Acceptance, Delivery. At acceptance it runs test_command (by default, the test cycle of the first stack's model). An unclassified task must be classified first; a complex task is broken down into simple tasks. When the tests pass, the loop tries to commit the task. After too many acceptance failures, it stops.

What you get ​

  • Work moves forward task after task, with one delivery commit per task and a closure when the epic is done.
  • A loop state and a timestamped ledger, readable at any time through effortless_crew_status.
  • In the app, you follow progress in Tasks, Backlog and Dashboard.
  • A provider profile in your home folder (global profile) or in the project (project profile).

When the agent is refused ​

SituationWhat the refusal saysWhat to do
The project is in semi-auto modeAn "execution tool disabled" message, flagged gated, for crew_init, crew_step, crew_report, loop_init, loop_stepSwitch the project to full mode.
Unknown scopecrew:scopeInvalidPass scope among story, epic, all, workshop.
No active epiccrew:noActiveEpicActivate an epic with effortless_epic_activate, or start again with scope: "workshop".
A loop already existscrew:alreadyInitializedPass force: true to overwrite it.
No bar commandcrew:barMissingPass bar, for example {"test": "…", "lint": "…"}.
The bar cannot runcrew:barUnrunnable, which names the faulty executableFix the commands named in bar, then run again.
Bar cwd absolute or outside the projectcrew:barCwdInvalidRun effortless_crew_init again with a bar.cwd relative to the project root.
A stack's path not foundcrew:stackPathMissingCreate the named folders, or fix the stack's path with effortless_stack_add.
No loop initializedcrew:notInitializedRun effortless_crew_init.
Unknown role or verdictcrew:roleUnknown or crew:verdictUnknownPass role among analyst, developer, qa; verdict among go, no-go, done.
The reported role is not the expected onecrew:roleMismatchReport with the expected role; effortless_crew_step names it.
Report on a step with no actorcrew:stageHasNoActorCall effortless_crew_step to learn the act actually expected.
payload and payload_path togethercrew:payloadPathEtPayloadProvide only one of the two.
payload_path missing, outside the project, too large or malformedcrew:payloadPathIntrouvable, crew:payloadPathHorsPerimetre, crew:payloadPathTropGros, crew:payloadPathJsonInvalide, crew:payloadPathRacineNonObjetPoint to a JSON file in the project whose root is an object (4 MiB at most).
Declared code absent from the branchcrew:filesNotIntegratedRun effortless_worktree_reintegrate from the worktree that holds the work, then report again.
The delivery commit is refusedcrew:commitRefusedRemove the cause git names in the refusal, then report again.
Delivery interrupted, report from another rolecrew:deliveryResumeRequiresQaGoResume with the qa / go report that could have started it.
Provider profile already presentcreate:providerExistsPass force: true to overwrite it.
Invalid profile scopecommon:scopeInvalidPass scope as global or project.
Project profile without a projectcommon:projectNotInitializedInitialize the project, or target the global scope.

Effortless — ArboRithm