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
« Start the team loop on the current epic. »
« Run the team on this story only, with pnpm test and pnpm lint as the bar. »
effortless_crew_initgoal=this story onlybar={"test":"pnpm test","lint":"pnpm lint"}
« Where is the loop? Who has to act now? »
effortless_crew_status« Show me the full trace of what happened in the loop. »
« Classify task TSK-03 as complex, deep tier, high effort, and tell me which model that gives. »
effortless_task_classifytask_id=TSK-03complexity=complexcapability_tier=deepeffort_level=high
« Generate a provider profile from the claude preset, for this project only. »
« Show me the available provider presets and my current profile. »
effortless_provider_presets_list« Start the autonomous loop on the simple tasks of the backlog. »
What the agent does
Start the team loop
effortless_crew_inittakesgoal(the objective, repeated in every role's brief) andscope:story,epic(default),allorworkshop.max_rounds(100 by default) andmax_epics(3 by default) cap the loop;0means unlimited.bardeclares the mechanical bar: an object that maps a name (test,lint,typecheck,build) to a command, or to an object withcommandand optionallycwdorstack. At least one command is needed, and it must be runnable: an unmeasured command would never be green and QA could never returngo.force: trueoverwrites a loop that is already initialized.- 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 tomax_epics.
Run one round of the loop
effortless_crew_stepreturns the contract for the current act: which role must act, the recommended model and effort, the expected output, andprompt_path, the path of a file that holds the brief (apromptkey). The agent reads that file before starting the sub-agent. Called twice,effortless_crew_stepreturns the same thing twice: it advances nothing.documenttargets a specific framing document.- The role performs the act.
effortless_crew_reportreports the result:role(analyst,developerorqa, the one the step expects),verdict(donefor the analyst and the developer,goorno-gofor QA),summary, andpayload(the role's structured output). For a payload too large to pass inline,payload_pathpoints to a JSON file instead, never both.effortless_crew_reportmeasures the mechanical bar before returning; the call can be long. It returns the next act directly.- 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-goin a row stop the loop.
Follow the loop
effortless_crew_statusreads the state without changing anything: step, expected role, epic / story / task pointer, counters, caps, end reason (scope_covered,epics_exhaustedorrounds_exhausted,nullwhile the loop runs) and a dated ledger of the acts. By default only the latest acts are returned;full: truereturns the full trace.
Route a task to a model tier
effortless_task_classifyclassifies a task of the active story on one or more axes:complexity(simpleorcomplex),capability_tier(deep,standardorlight),effort_level(low,mediumorhigh). At least one is required; an omitted axis is left unchanged.effortless_task_route_showreturns 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 isstandard/medium. It is a suggestion, never an obligation.
Set up providers
effortless_provider_presets_listlists the embedded and custom presets.effortless_provider_profile_showreads your active profile.effortless_provider_profile_init(re)generates the profile, a tier × effort matrix, from a preset family:claude,codex,gemini,mistralor a free name.scopeisglobal(default) orproject. An existing profile is overwritten only withforce: true.
The autonomous loop
A simpler loop that takes the backlog tasks one by one.
effortless_loop_initstarts it with agoal.effortless_loop_stepadvances it: Plan, Implementation, Acceptance, Delivery. At acceptance it runstest_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
| Situation | What the refusal says | What to do |
|---|---|---|
| The project is in semi-auto mode | An "execution tool disabled" message, flagged gated, for crew_init, crew_step, crew_report, loop_init, loop_step | Switch the project to full mode. |
| Unknown scope | crew:scopeInvalid | Pass scope among story, epic, all, workshop. |
| No active epic | crew:noActiveEpic | Activate an epic with effortless_epic_activate, or start again with scope: "workshop". |
| A loop already exists | crew:alreadyInitialized | Pass force: true to overwrite it. |
| No bar command | crew:barMissing | Pass bar, for example {"test": "…", "lint": "…"}. |
| The bar cannot run | crew:barUnrunnable, which names the faulty executable | Fix the commands named in bar, then run again. |
Bar cwd absolute or outside the project | crew:barCwdInvalid | Run effortless_crew_init again with a bar.cwd relative to the project root. |
| A stack's path not found | crew:stackPathMissing | Create the named folders, or fix the stack's path with effortless_stack_add. |
| No loop initialized | crew:notInitialized | Run effortless_crew_init. |
| Unknown role or verdict | crew:roleUnknown or crew:verdictUnknown | Pass role among analyst, developer, qa; verdict among go, no-go, done. |
| The reported role is not the expected one | crew:roleMismatch | Report with the expected role; effortless_crew_step names it. |
| Report on a step with no actor | crew:stageHasNoActor | Call effortless_crew_step to learn the act actually expected. |
payload and payload_path together | crew:payloadPathEtPayload | Provide only one of the two. |
payload_path missing, outside the project, too large or malformed | crew:payloadPathIntrouvable, crew:payloadPathHorsPerimetre, crew:payloadPathTropGros, crew:payloadPathJsonInvalide, crew:payloadPathRacineNonObjet | Point to a JSON file in the project whose root is an object (4 MiB at most). |
| Declared code absent from the branch | crew:filesNotIntegrated | Run effortless_worktree_reintegrate from the worktree that holds the work, then report again. |
| The delivery commit is refused | crew:commitRefused | Remove the cause git names in the refusal, then report again. |
| Delivery interrupted, report from another role | crew:deliveryResumeRequiresQaGo | Resume with the qa / go report that could have started it. |
| Provider profile already present | create:providerExists | Pass force: true to overwrite it. |
| Invalid profile scope | common:scopeInvalid | Pass scope as global or project. |
| Project profile without a project | common:projectNotInitialized | Initialize the project, or target the global scope. |