By now you have probably seen the demos: someone builds a full app in an afternoon, ships it, and the whole thing works. That is real. Coding agents genuinely have gotten that good.
Odoo development, though, is a different level. At Trobz, as an Odoo Integrator, we have our hands in a lot of Odoo projects: building custom modules, layering in OCA work, migrating clients across versions, inheriting years of accumulated customisations that only half the team remembers. The modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… has never seen most of it, and the parts it has seen may have shifted since trainingThe process of exposing a machine learning model to labeled or unlabeled data so it can learn patterns. During training, the model adjusts its internal parameters (weights) to minimize a loss….
A naive attempt looks like this: write a promptThe input text provided to an LLM to guide its response. Prompt design — choosing words, structure, and examples — significantly affects output quality. Also referred to as the user message or query., the AI gives you something that almost works, you correct it, it almost works again, you correct it again. At some point, either the context windowThe maximum number of tokens an LLM can process in a single request — both input (prompt) and output (completion) combined. Larger context windows allow the model to "remember" more of a conversation… fills up or you quietly close the terminal and go take a walk.
If that loop sounds familiar, this post is for you.
This post documents a workflow we use for non-trivial Odoo module work: Research, Plan, Implement. Three phases, three files, one /clear between each. The goal is to keep every session well below the context limit where modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… quality starts to slide, and to make the thinking reviewable before a single line of code is written.
Prerequisites
- Install Trobz’s marketplace:
$ claude plugin marketplace add [email protected]:trobz/skills.git - Install
odoo-devplugin:$ claude plugin install odoo-dev@trobz-skills
RPI Workflow
Value of context engineering
After watching Dex Horthy’s talk on context engineering (YouTube), one idea stuck: on any real project, what the modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… sees matters more than which modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… you picked.
For Odoo work the stakes are higher. An agent that grep-crawls web/ finds twenty hooks into the pivot view and cannot tell which is current. And with --dangerously-skip-permissions, a wrong turn in minute three costs you fifty-seven minutes of cleanup.
The unit of work here is not a promptThe input text provided to an LLM to guide its response. Prompt design — choosing words, structure, and examples — significantly affects output quality. Also referred to as the user message or query.. It is a file on disk that survives /clear.
Models are stateless, so: “You put good tokens in, you get good tokens out.”
Dumb zone
TransformerA neural network architecture introduced in the 2017 paper "Attention Is All You Need." Transformers use self-attention mechanisms to process sequences in parallel, enabling training on large… models lose recall past roughly 40% of the context windowThe maximum number of tokens an LLM can process in a single request — both input (prompt) and output (completion) combined. Larger context windows allow the model to "remember" more of a conversation…. For Claude Code that is about 67k of its 168k tokens.
Symptoms you will recognise:
- Reuses an older version of a file it already patched
- Invents a method signature that was correct two turns ago but changed since
- Retries the same broken approach it tried twenty minutes back
- Claude says “You’re absolutely right”!!!
The instinct is to write a longer promptThe input text provided to an LLM to guide its response. Prompt design — choosing words, structure, and examples — significantly affects output quality. Also referred to as the user message or query.. That feeds the problem. Corrections inside one session also compound: the modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… weights the “try, get corrected, try again” pattern into its next guess.
Rule of thumb: past the 40% mark with no progress, dump what you have learned to a file and start fresh.
Trobz’s arsenal
Research, Plan, Implement. Three phases. Each produces a file. Each ends with /clear.
┌──────────────────────────────────────────────────────────────────────────────┐
│ RPI WORKFLOW │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ /odoo-dev:brainstorm "feature description" │
│ │ │
│ ├──► Scouts project, then fans out in parallel: │
│ │ • odoo-scout (project addons inventory) │
│ │ • odoo-source-scout (Odoo core source at ~/code/odoo/<ver>/) │
│ │ • WebSearch │
│ │ │
│ ├──► Proposes 2-3 approaches, user selects one │
│ │ │
│ └──► Output: plans/reports/brainstorm-YYYY-MM-DD-HHmm-topic.md │
│ │
│ /clear │
│ │
│ /odoo-dev:plan --brainstorm-report <path> │
│ │ │
│ ├──► Reads brainstorm report │
│ ├──► Asks clarifying questions the research did not answer │
│ ├──► Splits work into commit-sized phases │
│ │ │
│ └──► Output: plans/YYYY-MM-DD-HHmm-description/ │
│ ├── plan.md │
│ └── phase-NN-*.md │
│ │
│ /clear │
│ │
│ /odoo-dev:code <plan_path> [--fast] │
│ │ │
│ ├──► Loads plan, creates task list from phases │
│ ├──► Uses odoo-scout before modifying files │
│ ├──► Executes phase by phase, runs tests after each │
│ ├──► Updates checkboxes in plan.md │
│ │ │
│ └──► Working code + commits │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
The files are the point. Memory evaporates at /clear. Files do not. Each phase starts fresh, reads only what it needs, and stays well below the 40% line.
All RPI outputs live in a predictable place:
plans/
├── reports/
│ └── YYYY-MM-DD-HHmm-topic.md
└── YYYY-MM-DD-HHmm-description/
├── plan.md
└── phase-NN-*.md
What each phase produces
Phase 1 - Research: A brainstorm report dense enough to plan from, cheap enough to throw away. The goal is not to write code. It is to answer “where in this version’s source does the featureAn individual measurable property or characteristic of the data used as input to a model. Feature engineering — selecting, transforming, and creating features — is a critical step in the ML pipeline. hook in, and what are the traps?” Sub-agents burn their own context on exploration and return pointers, not pages. The main session stays lean and ends with a single file on disk.
Phase 2 - Plan: A phase-by-phase plan that fixes every decision before any code is written: state shape, merge rules, reset semantics, file boundaries, commit tags. Review the plan, not the code. One bad plan line is a hundred bad code lines. Catching it here costs a sentence.
Phase 3 - Execute: Transcribe the plan into commits. One phase per /clear. The modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or… is no longer deciding. It is executing. If implementation gets interesting, the plan was wrong: go back to phase 2, do not improvise.
The Task
To make this concrete, we will walk the RPI loop end-to-end on a small OCA module for Odoo 19.0: web_pivot_merge_rows.
The UX is simple. Hover a pivot row header, click +, and the row fuses with the one below into a synthetic row: summed measures, composite title (“A + B”). Click × to split. No new modelA mathematical function trained on data that maps inputs to outputs. In ML, a model is the artifact produced after training — it encapsulates learned patterns and is used to make predictions or…, no server round-trip, session-only state.
The scope is deliberately narrow. The codebase it touches is not: web/static/src/views/pivot/ is OWL, inherited twice, and cares about row identity in ways that bite the first time you try to synthesise a row. Exactly the kind of work where walking in blind burns an afternoon.
Each of the three commands below comes from the odoo-dev plugin (trobz/skills), which we install via claude plugin marketplace add [email protected]:trobz/skills.git and enable with odoo-dev.
Phase 1: Research
/odoo-dev:brainstorm "add interactive row grouping directly in the UI instead of relying only on predefined group_by from the search view. When the user hovers over a row, a '+' icon appears next to it. Clicking merges the selected row with the adjacent row below into a single combined row."
The brainstorm skill scouts the project first, then fans out agents in parallel: odoo-scout inventories the project’s own addons for existing pivot work, odoo-source-scout reads Odoo core at odoo/addons/web/static/src/views/pivot/ to document how group_by flows from the search view into the measure groups, and a web search sweep catches OCA prior art so we do not accidentally rebuild an existing module.
Each sub-agent returns a short list of file paths, line ranges, and a paragraph of findings. The main session never sees the raw source. It sees a digest. Context spend stays under 15%.
The report that lands on disk is maybe 1,500 lines. It names the exact methods to override, the two places where measure aggregation happens, and one trap: the pivot renderer memoises row identity on a field path, so any synthetic row needs a synthetic path or the framework silently collapses it back. That trap is the reason this phase exists. It would have cost an hour of debugging to discover during implementation.
Phase 2: Plan
/clear. Fresh context. One input: the brainstorm report path.
/odoo-dev:plan --brainstorm-report \
/home/trisdoan/code/oca/19.0/web/plans/reports/brainstorm-260413-1500-pivot-row-merge.md
The plan recipe opens the brainstorm, asks a handful of questions that the research did not answer. In our case: what happens to the measure when one of the merged rows was the subtotal? what happens on column pivot? should merges persist across reload? Then it produces a phased plan.
Each phase is a commit-sized unit: a short title, the files it touches, the invariants that must hold before and after, and a checklist of verification steps. Review happens here. A reviewer who spends fifteen minutes on a good plan catches what two hours of code review would miss, because the plan exposes the decisions, not the syntax.
Expect to reject the first plan. It is normal. The first plan usually assumes the featureAn individual measurable property or characteristic of the data used as input to a model. Feature engineering — selecting, transforming, and creating features — is a critical step in the ML pipeline. is simpler than it is, or splits the work along the wrong seams. Push back in writing, let the agent revise. The revision is cheap; it is still just a document.
Phase 3: Implement
Only after research and planning are complete do we move to implementation, in a new session. Pass in the plan document.
/odoo-dev:code /home/trisdoan/code/oca/19.0/web/plans/260413-1500-pivot-row-merge/plan.md
At this stage I normally use --dangerously-skip-permissions. The code skill reads the plan completely, executes the phases in order, runs verification after each phase, and updates checkboxes directly in the plan file as it goes.
The agent should not be making design decisions at this point. If it starts asking “should I refactor this?” or “would it be better to…”, the plan was underspecified. Stop, go back to phase 2, update the plan, return. Improvising in the implementation session is how you end up with code that does not match the plan it was supposed to execute, and reviewers lose the ability to trust either document.
If the context windowThe maximum number of tokens an LLM can process in a single request — both input (prompt) and output (completion) combined. Larger context windows allow the model to "remember" more of a conversation… gets close to 40% during a long phase, /clear and restart from the next checkbox. The plan file is the recovery anchor.
Final Result
The resulting module, web_pivot_merge_rows, came out quite impressive (If it fits your project, go approve the PR ;-) ). The code follows our internal conventions end-to-end: module structure, OWL component patterns, test coverage. No manual patching, no improvised shortcuts.
Conclusion
RPI is not a promptThe input text provided to an LLM to guide its response. Prompt design — choosing words, structure, and examples — significantly affects output quality. Also referred to as the user message or query. trick. It is a loop you run with the agent, not a query you fire at it.
RPI is designed to prevent AI slop: plausible-looking code that passes a quick read but is wrong in the ways that only surface in production, because the agent was guessing and neither of you caught it. It is active collaboration: you read the research, you push back on the plan, you check the checkboxes. The agent does the mechanical work. You do the thinking that keeps it honest.
Well, as Dex said, “Do not outsource your thinking”.