Two Small Products, Two Hard Boundaries
Agentic UI and GitGrid shipped in the same week. Their useful features are different, but both products became clearer when I defined exactly what they are allowed to change.
This week I shipped two small x70 experiments that look unrelated.
Agentic UI is a chat where an agent can answer with text, a real interactive React interface, or both. GitGrid lets someone preview a steadier contribution pattern and, only after an explicit Apply step, place that plan in one dedicated private GitHub repository.
One is about generative interfaces. The other is about contribution history. The design problem underneath both was the same: the product needed a hard boundary around what generated output can do.
Agentic UI does not execute generated code
The obvious way to demo a generative interface is to ask a model for HTML or JavaScript and render it. It is also the fastest way to turn a playful demo into an unbounded code-execution problem.
Agentic UI takes a smaller route. The model returns a schema-validated tree from a finite Component Catalog. The browser maps those nodes to React and shadcn/ui components already installed in the app. A reply can contain forms, controls, tables, charts, or actions, but it cannot smuggle arbitrary source into the page.
Only the newest UI reply remains interactive. Older replies stay visible as the conversation’s record but become read-only. Refreshing ends the ephemeral session.
Those limits make the experiment more interesting, not less. The question is no longer “can a model print a button?” It becomes “can the model select a useful interaction from a known vocabulary, and can the application validate the result before a person touches it?”
GitGrid does not touch existing work
GitGrid needed an equally explicit ownership boundary.
The planner runs locally in the browser until Apply. It does not need a user
database to preview a pattern. If the user chooses to apply it, a GitHub App
creates one dedicated private repository, stores the versioned plan in
.gitgrid/config.json, and writes only the selected history through the current
day.
It does not rewrite an existing repository. It does not retain a long-lived personal token. It does not install recurring automation that continues making commits after the initial action.
GitHub currently requires the App installation to have broad repository selection before a brand-new repository exists. That provider constraint is uncomfortable, so the application boundary has to be narrower and visible: verify the returning installation belongs to the authorizing user, discard the short-lived user token, and limit writes to the repository GitGrid itself creates.
The product is free because there is no ongoing service hiding behind the planner. The repository and plan are the durable output.
Capability is less useful than containment
Both projects started with capability questions.
- Can an agent build the control that best answers a prompt?
- Can a contribution plan become a real GitHub history?
They became products only after I replaced those with containment questions.
- Which components may the agent select, and which reply may still act?
- Which repository may GitGrid create, and when may it write?
- What state survives a refresh?
- What credential is retained after the operation?
- What can the user inspect before committing to the change?
These are not security notes to add after the interface. They determine the interface. A read-only prior reply tells the user which interaction is current. A local preview makes Apply a meaningful decision. A dedicated repository makes the blast radius understandable without reading an implementation document.
The lesson I am keeping
Small experiments are easy to overbuild because the interesting technology is right there. Agentic UI could have become a general runtime. GitGrid could have become a recurring scheduler with accounts, billing, and a database.
Neither needed that to answer its core question.
The stronger version of an experimental product is often the one with fewer powers and better boundaries: a finite catalog instead of arbitrary code, one explicit Apply instead of background automation, and a visible session instead of ambiguous persistence.
That is the part I want to carry into larger systems. Before adding another capability, define the smallest object it is allowed to change.