2026-10-25
The model will renovate the place
Point a model at this tree and it tries to help in the ways that cost me a week. It adds a local package folder so restore goes green. It project-references a sibling so it can skip the publish. It drops Avalonia into a library because the sample was sitting right there. It writes a Python script for a job the rest of the tree builds in C#. It opens a pull request for a change that should have been a commit on main. None of that is malice. The context is smaller than the forest, so it patches the part it can see and calls the patch a fix.
I do the same things. I am just slower, and I have a longer memory of the last time the patch cost a week. The model has the file, the error, and a strong preference for a green tool call. I have the file, the error, and a preference I can sometimes outvote. Neither of us should be trusted with a wish written in a README.
The renovations
The folder of packages is the classic. Restore cannot see Novolis.Physics at the version the csproj floated. The model packs whatever is on disk into artifacts/nuget-local, adds a source, and reports that restore succeeded. It did. Against a feed that exists in that workspace and will not exist in CI. I banned that for myself in I banned the folder of packages. The model will rediscover the ban as a clever fix unless the verify script fails the commit. A paragraph in a system prompt loses to a red error and a one-line config change. I have watched the paragraph lose.
The sibling project reference is the renovation that looks like architecture. ../../../novolis-rendering/src/...csproj type-checks today. It also pins this repo to my checkout layout and to a commit that is not a version. Sixty repos is a fence only if that path does not merge. The platform solution is the legal way to compile siblings for an afternoon. The model does not love the legal way. The legal way is two steps and a generated map. The illegal way is one line and a green build. I need the one line to be a failed check, not a style discussion.
Avalonia in a library is the renovation that looks like a demo. The test would be easier to understand if it showed the body. The showing requires a window. The window is a package reference away. Physics does not get a window, and NOV2008 and its neighbors are how that sentence survives a session that has not read the post. If the analyzer is not referenced, the model will add the window, the screenshot will look great, and the headless build will be over.
Python is the renovation that leaves the ecosystem. A text munging job, a one-off plot, a script beside a C# tool that already does the job. The script works on my machine if I have the interpreter. It is invisible to dotnet test. It rots the moment the C# type it was scraping changes shape. The tree is C#. A new language is not a fix for a missing API. It is a second system with no build.
The pull request is a social renovation. The change is a fix on main. The session opens a branch, writes a description, and waits for a review that will be me, later, confused about why a three-line correction needed a ceremony. Sometimes a PR is the right door. Often, in this forest, main is the door and CI is the review. A model that cannot tell those apart will "be safe" by splitting history. Safe for the session. Expensive for the log.
I do not have a better prompt
I do not have a paragraph of prompt that stops that. I have tried. The paragraph gets long, the session gets a narrower task, and the paragraph is the part that falls out of the window. "Be careful" lasts about ten minutes, for both of us. "Do not add a local feed" lasts until the next missing package.
What lasts is the same fences I use on myself, sitting where the model will trip on them every turn, and a build that goes red when it climbs over. Looking around is fine. A change that survives compile and the verify scripts is the same bar I am held to. If I want a rule the model will obey, I make it fail dotnet build or fail verify-nuget-only. I do not make it a bullet in a charter.
The docs stay, because the red code is not an explanation. A session that hits NOV2008 can be told to read the boundary doc. A session that never hits it will not read the doc, and should not be expected to. I assume the context is one project and the error on the screen. Design the error so the wrong renovation is the thing on the screen.
When it gets tools, I want a catalog
A chat that can edit files will edit files. A host that exposes a catalog can be boring on purpose, and I want boring next to something that will otherwise redesign the repo to make today's task easier.
novolis-agent is that catalog, host-neutral. A profile declares the actions. An action has a stable id. It says what it is. read, mutate, or irreversible. It says whether approval is required. It says whether repeating it is safe. It can carry a preview of the effect, and a schema the host checks. Compact parameter hints can stay for old clients. The schema is what I trust.
The snapshot has a revision. StateRevision moves when an accepted command actually changes the host. The command says which revision it thinks it is looking at. AgentCommandGate rejects a mismatch with stale-snapshot and does not apply it. I have watched a session act on a world that already moved, then explain the resulting mess as a new theory. The stale revision is the theory, killed before the write.
Every terminal result carries a receipt. preview, applied, rejected, or failed. A reason. Recovery text. Effects. Artifact references. Repeat the same correlationId and you get the stored receipt again, not a second apply with a new idea. A mutation gets a preview before it lands. Apply, in the development profile, is the approval-gated write. Inspect, diagnostics, build, test, diff, propose. Those can be looked at. The write waits.
Watching a build finish beats asking "are we there yet" in a loop. Callers open agent.watch, filter, and resume with afterEventSequence. Delivery is at-most-once. A full outbound queue closes that watch instead of pretending the events arrived. A bad session should replay to the step that went wrong. AgentScenario and AgentTrace do that in tests. The report is the first diverging action. The next session fails in the same place instead of inventing a new theory about a different step. Live model calls stay out of CI. The script is the regression. The model is not a test double I want on the critical path.
One contract, more than one room
The development profile is novolis-agent-dev. The freighter's bridge is another profile on the same contract. Capability captain.play. Stable action ids. The same revisioned receipts. Semantic ids for the things the bridge is willing to admit exist: cash, runway, life, the receipt, the error. UI framework types do not belong in novolis-agent. Avalonia does not leak into the protocol so a game can be played by a session. The game keeps its widgets. The protocol keeps nouns. That is the same split as everywhere else. The host is replaceable. The behavior is not.
Game play can leave ApprovalRequired off when the product UI is already the gate. A process kill, a publish, a source-control write cannot. Those come back approval-required until there is a token. The development profile uses the proposal's correlation id as that token. I would rather click once on a preview than discover the apply from the diff.
Five hundred packages do not fit in the chat
About five hundred packages do not fit in a prompt. The architecture is there so they don't have to. The session does not need the map of every repo. It needs the repo it was pointed at, the error, and a fence that makes the clever fix fail. I will keep writing the posts. I will not pretend the posts are loaded. The analyzer is loaded. The verify script is loaded when someone runs it, and CI runs it when I stop trusting either of us to remember.
If you are the session: do not renovate. Do not add the folder. Do not reach into the sibling. Do not teach a library to draw. Do not start a second language to avoid a C# change. Hit the build. Read the code it throws. The receipt beats the theory.