Skip to content

Feature: project second brain #1017

Description

@ako

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:

  1. 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.
  2. A lint rule. If the knowledge is an enforceable constraint, it becomes a Starlark
    rule, not prose. Enforced knowledge cannot go stale.
  3. 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

  1. 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.
  2. Agent session end. A hook that captures corrections into staged.jsonl. Fail open —
    a broken hook must never block a session.
  3. 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

  1. Storage, anchors, init / capture / staged / promote / drop / check / show,
    plus the skill. Markdown destinations only.
  2. The mxbuild error → resolution trigger.
  3. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions