Skip to content
Michi v2026.05.20
Save the Tokens

Research and Explore

You have a question that needs answering before you can act — which approach, how this part of the system actually works, what a paper or spec means for your architecture. The work is to gather, think, and produce a useful finding.

In the iteration cycle, Explore and Brainstorm do the framing and the thinking. Document is the deliverable — an epic doc at docs/epics/<topic>.md (a flat-file epic when the work is research-focused) that captures what you investigated, what you found, and what you decided (or what remains open). The tool is /michi-explore, which structures a conversation around a hard question and surfaces assumptions as they emerge.

A few rules for this kind of work:

  • State the question before you start reading. If you can’t state it, that’s the first thing to work on.
  • Check local sources first — a prior epic doc, a journal entry — before researching from scratch.
  • “Not ready” is a valid outcome. A named gap beats a forced conclusion.

Use this pattern when the work is to understand or decide, not to build.

This is an abridged session — a question about which charting library to adopt for a dashboard app. It shows the shape: read the codebase before reasoning about it, check assumptions, course-correct when a prototype gives mixed results, then pull live docs to sharpen the finding.

You: /michi-explore peek

Agent: I’ve read the project docs. Here’s where things stand: [summarizes the dashboard app, its current data pipeline, and active work]. What do you want to explore?

You: Different topic. I want to figure out which charting library to use for the dashboard — I’m looking at Recharts, Victory, and visx. I want to research the options. Should I do that here?

Agent: Here is better for the codebase-grounded part — what data shapes you’re actually rendering, how deeply the current charting code is wired in, where the integration points are. My suggestion: two passes. First, I read the current usage and tell you what you’re actually working with. Then we do the ecosystem comparison against your real constraints. Or one conversation if you prefer.

You: Let’s start here. I’ve seen Recharts recommended everywhere, and it looks easy to set up. But I tried it on the time-series panels and the result doesn’t feel right — the lines are choppy on dense data and the tooltip positioning is off. Before I invest more time fixing it, I want to know if I should switch.

[The agent reads the dashboard’s current charting code, the data shapes it renders, and the time-series panel components before responding.]

Agent: Before I react to the library comparison — the codebase tells a different story than the problem you’re describing. Your time-series panels are feeding Recharts with unsampled raw data: several thousand points per series on some views. The choppiness and tooltip jitter are almost certainly a data volume issue, not a library limitation. Recharts, Victory, and visx would all behave the same way here.

The underlying issue: your data layer doesn’t downsample before the chart sees it. At 5,000 points per series, any SVG-based charting library is going to struggle — that’s a rendering constraint, not an API one.

My recommendation: don’t switch yet. The hypothesis “Recharts is the problem” isn’t supported by what the code is doing.

You: A previous session set up the pipeline this way. I assumed the library was handling it.

Agent: That changes my read, but only partially. Two things can both be true: the previous session didn’t add downsampling because Recharts doesn’t enforce it — you have to bring it yourself. But the fact that it wasn’t added is signal too — if the library’s getting-started path doesn’t surface this constraint clearly, that’s a real ongoing cost. Future sessions will make the same omission.

Sharper test: let me add a lightweight LTTB downsample step before the data hits the chart — standard algorithm, a small utility — and see how the panels look at a target of 300 points per series. Not a final answer, just data. If the choppiness resolves, the library is fine. If rendering is still slow or the tooltip behavior is still wrong, that’s evidence to compare libraries.

You: Go ahead, this branch.

[The agent adds an LTTB downsampling utility, wires it into the time-series panel data flow, and rerenders the affected panels. Reports what changed and what it didn’t touch.]

You: The lines are smoother, but the tooltip is still off — it snaps to the wrong point on hover, especially near the ends of the series. And I’m not sure the downsampled lines are accurate enough for the financial panels; the peaks look clipped. [shares screenshot]

Agent: You’re right — incrementally better, not solved. Honest read: the rendering improved, but the tooltip snapping is a known Recharts issue with custom active-dot logic on downsampled series, and the LTTB clip on the financial panels is real — LTTB preserves visual shape, not extrema, so peaks get smoothed. For financial data where the actual high/low matters, that’s a correctness problem, not just aesthetic.

Three directions: tune the tooltip and switch to a min/max-preserving downsample algorithm for the financial panels; keep Recharts and accept those constraints; or spike one alternative on the financial panel specifically to see if the tooltip behavior differs. I’d lean toward the spike — you now have a concrete, testable issue that’ll show up in any library comparison.

You: Let me ask about visx specifically. It’s from Airbnb and seems lower-level. Is it actually maintained, and can it handle what we need?

[The agent fetches current visx docs and recent GitHub activity rather than going off training data.]

Agent: visx is actively maintained — recent releases, responsive issue tracker. The tradeoff is real though: it’s primitives, not a chart library. You compose scales, axes, line paths, and tooltip layers yourself. For the financial panels where you need control over how extrema are handled, that’s actually a fit — you own the rendering logic. For simpler panels like the summary bars, you’d be writing more code than Recharts requires.

The bigger consideration: visx is built on D3 primitives. Future sessions will default to D3 patterns unless your conventions are explicit. The code is readable if you know D3; it’s opaque if you don’t. That’s an AI-collaboration cost to factor in.

You: I found this — “Nivo is built on top of D3 and React, with support for canvas rendering.” Is canvas rendering relevant here?

[The agent searches for Nivo’s canvas support and how it applies to high-density time-series specifically.]

Agent: This is more interesting than I expected. Nivo’s canvas renderer is directly relevant to your density problem — SVG has hard limits at the point counts you’re working with; canvas doesn’t. Nivo’s ResponsiveLineCanvas component handles the same API as the SVG version, so you’re not rewriting logic, just swapping the renderer. That’s a path to fixing the financial panel performance without the visx “compose everything yourself” tradeoff.

The catch: canvas rendering loses some tooltip precision — you have to implement hit detection yourself. Which brings you back to the same tooltip problem, just at a lower level.

I’d want to verify two things before you commit to any direction: prototype ResponsiveLineCanvas on the financial panel and check whether the tooltip hit detection is workable; and read Nivo’s GitHub for recent issues on canvas + tooltip to see if this is a known pain point or already solved. If the canvas renderer handles density and the tooltip is manageable, Nivo is the most credible option I’ve seen for your specific constraints.

You: /exit

You have a question that needs answering before you can act. Maybe it’s “which approach should we take?” or “how does this part of the system actually work?” or “what does this paper mean for our architecture?” The work is to gather, think, and produce a useful finding — not code.

This is the Research / Explore use case. The iteration cycle runs here like anywhere else; what’s distinctive is that Explore and Brainstorm do the framing and the thinking, and Document is the deliverable — not a cleanup step.

The iteration cycle applies to every kind of work, including this kind. What changes is the emphasis.

Explore is the phase that frames a research effort. It is not necessarily the longest, but it is the one that most shapes everything after — it uncovers the assumptions you’re carrying and sets what the question actually is. Get it wrong and the rest of the cycle answers the wrong thing.

Gather before you reason. Read the sources, walk the codebase, survey the options. The goal is to have enough in hand to think clearly.

This phase has a trap: explore-as-theatre — going through the motions of research without really understanding the question first. Before you start reading, state the question plainly. What does a useful answer look like? What would change your mind?

The /michi-explore skill is built for this: it structures a conversation around a hard question, keeps it on track, and surfaces assumptions as they surface. It is not a checklist; it is structured dialogue.

Check what already exists. Before spending time researching an alternative, scan local sources — the project docs, the codebase, any prior epic docs. Someone may have already done this work.

With material in hand, think through it. Compare options against real constraints (your codebase, your team, your timeline — not abstract tradeoffs). Surface the assumptions baked into each choice. Pull threads that feel underexplored.

Brainstorm in this context is not freeform. It is disciplined questioning: what am I taking for granted here? What would change if this assumption were wrong? The Clarify before Asserting principle applies — don’t let imported defaults (a blog post, a framework’s marketing) steer you without acknowledgment.

Research tends to alternate between Explore and Brainstorm. You read something, reason about it, find a gap, go back and read more. That alternation is expected and healthy.

For research, Plan is light. It asks: what decision does this need to reach, and what would we need to know to reach it? Frame it explicitly, especially if the question is large enough to span sessions. Write it down — a sentence or two is enough.

This prevents a common failure: open-ended exploration that produces impressions rather than a finding. The plan names what you are trying to conclude so Verify has something to check.

The investigation proper. Explore and Execute alternate — structured dialogue, then heads-down reading, then back. There is no sharp boundary; this is the nature of research.

If you are evaluating a library or tool, test it against your actual codebase, not a hello-world example. The constraints that matter are your constraints.

Checkpoint: has the question been answered? Is the finding strong enough to act on?

“Not ready” is a valid outcome. Naming a gap beats forcing a conclusion. A research pass that ends with “we need to know X before we can decide” is a successful pass — it clarifies where the work is and avoids a premature decision.

What is not valid: drifting to the end without checking. Ask the question you named in Plan. Does the finding answer it?

For research, Document is not cleanup. It is the deliverable.

An epic doc (docs/epics/<topic>.md) is the standard home for research findings — typically a flat file when the work is research-focused, growing to a subdirectory only if the investigation deepens. It captures what was investigated, what was found, and what was decided (or what remains open). It feeds directly into the next effort’s planning — someone reading another epic’s plan will cross-reference this epic rather than redo the investigation.

Write the finding while the context is hot. Discoveries are the value; they disappear if you don’t capture them.

Research genuinely differs by mode.

Paired is the common mode for research, even when other work runs Entrusted. The explore skill is structured dialogue — the human steers between rounds, corrects the frame when it drifts, and surfaces assumptions in conversation. Because framing the question well is most of the work, having a human in the loop during Explore pays off more here than in implementation work.

Entrusted can work when the question is well-framed and the risk of answering the wrong question is low. The agent runs rounds of investigation more independently and delivers the finding at the gate for human review. This is reasonable for a bounded option evaluation with clear constraints, less reasonable for conceptual design or questions where the scope itself is uncertain.

The riskier the framing — is this even the right question? — the more Paired the research should be.

You are comparing approaches, libraries, or tools. The work is concrete: gather realistic options, evaluate them against real constraints, and land a recommendation.

The most common failure here is comparing options in the abstract — benchmark numbers, feature matrices, GitHub stars. These matter less than the answer to: does this fit how we actually work? Evaluate against the real codebase. Test the integration you actually need.

Land in an epic doc with a clear recommendation and the reasoning. “We chose X because Y; we ruled out Z because W” is more useful than “here are the tradeoffs.”

You are digesting something dense — a paper, an external codebase, a specification. The goal is extracting what applies to your project.

Approach it as a structured read, not passive consumption. Before you start: what are you looking for? As you go: what is applicable here? At the end: what changes, if anything?

A reading note that connects the external material to a specific project decision is far more useful than a summary. Write the connection explicitly.

You are thinking through a hard problem before it is a plan — a data model, an architecture decision, a boundary. The work is mostly reasoning, and it may take several rounds before the answer is clear.

This is where the Rule of 3 applies directly: one round surfaces the obvious, a second catches what the first assumed, a third consolidates. Stopping after one round is usually overconfidence. Pushing past three without progress is usually a signal to stop and reframe, not to try again.

Conceptual design often ends in a design decision rather than code. Write that decision explicitly and locate it where it will be found — a flat-file epic, or the plan doc for the epic that will execute it.

Answering before understanding the question. The most common failure in research. State the question plainly before reading anything. If you can’t state it, that is the first thing to work on.

Not checking what already exists. Local sources come first. A prior epic doc, a journal entry, a patterns doc — these may already contain the answer, or a useful starting point.

Drifting without capturing. Research produces discoveries mid-investigation. Write them down as they emerge. A finding you don’t capture is a finding that will need to be rediscovered.

Forcing a conclusion. If the question isn’t answered, say so clearly. A named gap is more useful than a hedged conclusion that quietly defers the real decision.

Letting outside defaults steer. Blog posts, framework documentation, and Stack Overflow answers carry their own assumptions. They are background, not authority for your project. Evaluate imports explicitly.

A developer wants to replace the state management library in a mid-sized web application. The existing library is working but has caused pain — complex async flows, hard-to-test selectors, unfamiliar patterns for new team members.

Explore: They scan the codebase to map how state is actually used — how many stores, what kind of data, which async patterns. They check whether there is a prior epic on this question (there isn’t). They identify three candidate libraries and read their documentation.

Brainstorm: They reason against real constraints: the team’s existing fluency, the async patterns the codebase actually uses, migration risk for the parts that are load-bearing. One candidate looks appealing in the abstract but requires rewriting the async layer. That cost isn’t in the documentation; it emerged from reading the codebase.

Plan: The question is: can we swap the library without rewriting the async layer, and if so, which library fits best? They name the decision they need to reach.

Execute: They prototype the integration for the most promising candidate in an isolated branch — not a hello-world, but the actual async pattern the codebase uses. They find an edge case the documentation didn’t mention.

Verify: The prototype answers the question. One library fits; the others don’t for specific, documented reasons. The finding is strong enough to act on.

Document: A flat-file epic at docs/epics/state-management-evaluation.md captures the options considered, the constraints that drove the decision, the prototype findings, and the recommendation. The next milestone’s plan doc references it rather than re-litigating the question.

The team now has a decision they can execute against — and a record of why, so future questions (“why did we choose this?”) have an answer.


For the skill that carries the exploration phase, see /michi-explore. For how research findings feed into milestone planning, see /michi-planning and Plan Docs.