Task: add an optional, minimal project second brain to mxcli
Before you write any code
Read CONTRIBUTING.md, THEORY.md, and the existing proposals in docs/11-proposals/.
Then write docs/11-proposals/PROPOSAL_project_brain.md following the conventions of the
existing proposals, and stop for review. Do not start implementing until the proposal is
approved.
While drafting, verify these assumptions against the actual codebase rather than trusting
this brief:
- Can mxcli read and write the
Documentation property of model objects (entities,
microflows, pages) through MDL today? If not, say so in the proposal and scope that
path out of phase 1.
- What does the catalog give us for resolving a name like
Sales.ACT_Order_Approve to a
real object, and how fast is it?
- Does the Starlark lint rule engine support rules generated at runtime from a template,
or would generated rules need to be checked in as source?
- How do the release/goreleaser and skill-registry mechanics affect shipping a skill
alongside the binary?
Flag anything in this brief that conflicts with how mxcli actually works. The design below
is a starting point, not a specification to follow off a cliff.
The problem
Developers using AI coding agents on Mendix projects accumulate project knowledge that the
agent loses every session: why a pattern was chosen, which marketplace module version
broke what, which mxbuild error means what in this codebase. The common answer is a
hand-maintained CLAUDE.md or a memory-bank tool. Both rot, and both duplicate things
mxcli can already answer.
This feature is for developers who do not already have their own approach. It must be
entirely opt-in, absent unless initialized, and removable by deleting a directory.
Core design principle
In a Mendix project, most of what generic memory tools record is derivable — mxcli can
already query the domain model, microflows, pages, and bindings. The brain stores only the
negative space: what mxcli cannot compute. Anything derivable must be answered by a
command, never written down.
Concretely, the three tiers, best first:
- Model documentation. Knowledge attached to the
Documentation property of the
object it concerns. It travels with the object, is deleted with it, and cannot drift
independently. This is the preferred destination for anything object-scoped.
- A lint rule. If the knowledge is an enforceable constraint, it becomes a Starlark
rule, not prose. Enforced knowledge cannot go stale.
- Markdown. Only what fits neither of the above.
Storage layout
Committed, human-readable, in the project's docs folder (paths configurable, these are
defaults):
docs/decisions.md # append-only; one Y-statement per decision, never edited
docs/conventions.md # house rules mxcli cannot derive (cap: 50 lines)
docs/gotchas.md # mxbuild / Studio Pro / marketplace traps (cap: 20 entries)
Tool-owned, gitignored:
.mxcli/brain/staged.jsonl # capture buffer, never promoted without a human
.mxcli/brain/config.yaml # paths, caps, hook settings
The committed files must be readable and reviewable by someone who has never installed
mxcli, and must show up in pull request diffs. Do not hide them in a dotfolder. .mxcli/
holds only state that should disappear when the tool does.
init must detect an existing docs/adr/, ADR/, docs/decisions.md or similar and
offer to adopt it rather than scaffolding a parallel store.
Anchors and staleness
Every entry carries zero or more model anchors in the form @Module.ObjectName.
mxcli brain check resolves every anchor against the actual model via the catalog. An
unresolvable anchor means the entry describes something that no longer exists — a
mechanical staleness signal, not a judgement call. In CI, check --ci exits nonzero and
reports which entries to delete or update.
This is the part of the design that only works because we have a queryable model. Get it
right.
CLI surface
The binary owns the data model, the file formats, and all enforcement. It never calls an
LLM.
mxcli brain init — scaffold, detect Mendix version and marketplace modules, adopt
existing decision docs if found, install hooks, write a short AGENTS.md pointer.
Refuses if already initialized. Writes no model inventory into AGENTS.md — the pointer
says "query the model with mxcli," it does not transcribe it.
mxcli brain capture "<note>" [--anchor ...] [--source ...] — append a candidate to
staged.jsonl. Never touches committed files.
mxcli brain staged --json — list pending candidates for an agent to work through.
mxcli brain promote <id> --to doc|lint|decision|convention [--anchor ...] — commit one
candidate to its destination. Enforces the caps: refuses when a cap would be exceeded
and names what must be pruned first.
mxcli brain drop <id> [--reason ...] — discard a candidate.
mxcli brain check [--ci] — resolve all anchors, report broken ones, report entries over
cap.
mxcli brain show — print exactly what an agent would load, with a size figure, so the
developer can see the context cost.
Every command must no-op cleanly with a clear message when the brain is not initialized.
The skill
Ship a thin skill that orchestrates the primitives. It owns exactly one piece of judgment:
routing a staged candidate to model documentation, a lint rule, a decision, a convention,
or the bin — in that order of preference. It does this by calling brain staged --json,
then brain promote or brain drop. It never writes to the committed files directly, so a
bad skill revision cannot corrupt the store.
The description field determines whether this is ever used, and skills tend to
under-trigger, so make it pushy and phrase it around symptoms rather than the feature name.
Trigger on things like "the agent keeps making the same mistake," "why did we do it this
way," "record this so we don't hit it again," "clean up the project notes." Nobody types
"second brain."
The skill body should also state the routing heuristics explicitly: object-scoped facts go
to model documentation; enforceable constraints become lint rules; irreversible choices
with rejected alternatives become decisions; anything with no anchor is either a genuine
cross-cutting convention or junk, and the agent must ask which.
Triggers, in priority order
- mxbuild error → resolution. When a build fails and a subsequent build over the same
edit scope passes, capture the error/fix pair automatically. This is the highest-value
and most Mendix-specific signal available, and it costs the developer nothing. Design
this so it also works when mxbuild is invoked outside an agent session.
- Agent session end. A hook that captures corrections into
staged.jsonl. Fail open —
a broken hook must never block a session.
- CI.
mxcli brain check --ci on pull requests.
Nothing reaches a committed file without a human going through promote. That single rule
is what keeps this minimal; do not add a path around it.
Non-goals
Be strict about these — they are how comparable tools become useless:
- No status file, progress log, or "what's next." That duplicates git and the issue tracker
and rots immediately.
- No embeddings, vector store, or semantic search.
- No cross-project or global store. This is per-project only.
- No LLM calls from the binary.
- No auto-promotion, no auto-rewrite, no scheduled "optimize the memory file" pass.
- No generated inventory of the model in any committed file.
Acceptance criteria
- A fresh
brain init on an existing Mendix project produces under 30 lines of committed
content total.
- Renaming a microflow that an entry anchors to makes
brain check fail, naming the entry.
brain promote refuses to push conventions.md past its cap and names a prune candidate.
- Every command exits cleanly and informatively on an uninitialized project.
- Deleting
docs/decisions.md, docs/conventions.md, docs/gotchas.md and .mxcli/brain/
fully removes the feature, and the rest of mxcli is unaffected.
- The skill can complete a full curate pass using only the documented CLI primitives.
Suggested phasing
- Storage, anchors,
init / capture / staged / promote / drop / check / show,
plus the skill. Markdown destinations only.
- The mxbuild error → resolution trigger.
- Promotion into model documentation, and lint rule generation.
Follow the CONTRIBUTING.md process, including Studio Pro validation and the agentic testing
steps. Update THEORY.md if this changes the project's working theory.
Task: add an optional, minimal project second brain to mxcli
Before you write any code
Read
CONTRIBUTING.md,THEORY.md, and the existing proposals indocs/11-proposals/.Then write
docs/11-proposals/PROPOSAL_project_brain.mdfollowing the conventions of theexisting proposals, and stop for review. Do not start implementing until the proposal is
approved.
While drafting, verify these assumptions against the actual codebase rather than trusting
this brief:
Documentationproperty of model objects (entities,microflows, pages) through MDL today? If not, say so in the proposal and scope that
path out of phase 1.
Sales.ACT_Order_Approveto areal object, and how fast is it?
or would generated rules need to be checked in as source?
alongside the binary?
Flag anything in this brief that conflicts with how mxcli actually works. The design below
is a starting point, not a specification to follow off a cliff.
The problem
Developers using AI coding agents on Mendix projects accumulate project knowledge that the
agent loses every session: why a pattern was chosen, which marketplace module version
broke what, which mxbuild error means what in this codebase. The common answer is a
hand-maintained
CLAUDE.mdor a memory-bank tool. Both rot, and both duplicate thingsmxcli can already answer.
This feature is for developers who do not already have their own approach. It must be
entirely opt-in, absent unless initialized, and removable by deleting a directory.
Core design principle
In a Mendix project, most of what generic memory tools record is derivable — mxcli can
already query the domain model, microflows, pages, and bindings. The brain stores only the
negative space: what mxcli cannot compute. Anything derivable must be answered by a
command, never written down.
Concretely, the three tiers, best first:
Documentationproperty of theobject it concerns. It travels with the object, is deleted with it, and cannot drift
independently. This is the preferred destination for anything object-scoped.
rule, not prose. Enforced knowledge cannot go stale.
Storage layout
Committed, human-readable, in the project's docs folder (paths configurable, these are
defaults):
Tool-owned, gitignored:
The committed files must be readable and reviewable by someone who has never installed
mxcli, and must show up in pull request diffs. Do not hide them in a dotfolder.
.mxcli/holds only state that should disappear when the tool does.
initmust detect an existingdocs/adr/,ADR/,docs/decisions.mdor similar andoffer to adopt it rather than scaffolding a parallel store.
Anchors and staleness
Every entry carries zero or more model anchors in the form
@Module.ObjectName.mxcli brain checkresolves every anchor against the actual model via the catalog. Anunresolvable anchor means the entry describes something that no longer exists — a
mechanical staleness signal, not a judgement call. In CI,
check --ciexits nonzero andreports which entries to delete or update.
This is the part of the design that only works because we have a queryable model. Get it
right.
CLI surface
The binary owns the data model, the file formats, and all enforcement. It never calls an
LLM.
mxcli brain init— scaffold, detect Mendix version and marketplace modules, adoptexisting decision docs if found, install hooks, write a short
AGENTS.mdpointer.Refuses if already initialized. Writes no model inventory into
AGENTS.md— the pointersays "query the model with mxcli," it does not transcribe it.
mxcli brain capture "<note>" [--anchor ...] [--source ...]— append a candidate tostaged.jsonl. Never touches committed files.mxcli brain staged --json— list pending candidates for an agent to work through.mxcli brain promote <id> --to doc|lint|decision|convention [--anchor ...]— commit onecandidate to its destination. Enforces the caps: refuses when a cap would be exceeded
and names what must be pruned first.
mxcli brain drop <id> [--reason ...]— discard a candidate.mxcli brain check [--ci]— resolve all anchors, report broken ones, report entries overcap.
mxcli brain show— print exactly what an agent would load, with a size figure, so thedeveloper can see the context cost.
Every command must no-op cleanly with a clear message when the brain is not initialized.
The skill
Ship a thin skill that orchestrates the primitives. It owns exactly one piece of judgment:
routing a staged candidate to model documentation, a lint rule, a decision, a convention,
or the bin — in that order of preference. It does this by calling
brain staged --json,then
brain promoteorbrain drop. It never writes to the committed files directly, so abad skill revision cannot corrupt the store.
The description field determines whether this is ever used, and skills tend to
under-trigger, so make it pushy and phrase it around symptoms rather than the feature name.
Trigger on things like "the agent keeps making the same mistake," "why did we do it this
way," "record this so we don't hit it again," "clean up the project notes." Nobody types
"second brain."
The skill body should also state the routing heuristics explicitly: object-scoped facts go
to model documentation; enforceable constraints become lint rules; irreversible choices
with rejected alternatives become decisions; anything with no anchor is either a genuine
cross-cutting convention or junk, and the agent must ask which.
Triggers, in priority order
edit scope passes, capture the error/fix pair automatically. This is the highest-value
and most Mendix-specific signal available, and it costs the developer nothing. Design
this so it also works when mxbuild is invoked outside an agent session.
staged.jsonl. Fail open —a broken hook must never block a session.
mxcli brain check --cion pull requests.Nothing reaches a committed file without a human going through
promote. That single ruleis what keeps this minimal; do not add a path around it.
Non-goals
Be strict about these — they are how comparable tools become useless:
and rots immediately.
Acceptance criteria
brain initon an existing Mendix project produces under 30 lines of committedcontent total.
brain checkfail, naming the entry.brain promoterefuses to pushconventions.mdpast its cap and names a prune candidate.docs/decisions.md,docs/conventions.md,docs/gotchas.mdand.mxcli/brain/fully removes the feature, and the rest of mxcli is unaffected.
Suggested phasing
init/capture/staged/promote/drop/check/show,plus the skill. Markdown destinations only.
Follow the CONTRIBUTING.md process, including Studio Pro validation and the agentic testing
steps. Update THEORY.md if this changes the project's working theory.