From instructions to intent: defining the system before the agent builds it
Published 2 October 2026. Updated 5 October 2026.
A coding agent needs a clear definition of the system it is building. If we leave its meaning, scope and rules undefined, the agent makes those decisions while writing the code.
Before construction, I establish three things: a domain profile, invariants and intent. They define the boundaries within which the agent works. This is the foundational architecture of Options OS. To explain why these boundaries matter, it helps to look at how we moved from giving computers precise instructions to describing what we want them to build. Each stage expanded what we could do and the number of decisions involved in doing it.
More capability, more choices
The way we direct computers has expanded through four overlapping stages.

- Physical configuration: constrained operations. We wired plugboards, set switches and supplied encoded data to machines with specific capabilities. This automated operations; changing behaviour required physical reconfiguration within the machine’s capabilities.
- Programming: programmable behaviour. We wrote executable instructions, progressing from machine code to higher-level languages. This created new behaviour through software, without physically reconfiguring the machine.
- Interfaces: capabilities within a defined scope. We selected and combined implemented functions through command-line and graphical interfaces. This enabled specialised work without writing the underlying program, within the capabilities the application exposed.
- Intent: systems constructed and connected through human language. We express goals to agents that generate software and connect applications, data and services. This gives us the ability to direct workflows and systems beyond predefined application functions, while delegating procedural implementation.
Each stage gave us more possibilities and more ways to build software. It also introduced more complexity. We introduced system and codebase architectures to organise that complexity, dividing systems horizontally and vertically. Disciplines and roles developed around those divisions: backend engineering, frontend engineering, DevOps, data analysis and others.
Now we are in the era of human-language-driven development. There is a human, an intent and an AI agent. While this sounds simple, the number of possible interpretations and implementations grows rapidly. The agent has access to a vast world of learned patterns. It can appear to know everything while knowing nothing about the particular system we intend to build. The model generates tokens based on the preceding context and the patterns learned during training. What we provide shapes which patterns it draws on.
To obtain a particular program, we need to describe its intended behaviour and the relevant concepts and constraints. That description gives the model context for generating an implementation. We do not have to supply the finished program, but we do have to define what we want it to construct. A natural first attempt has been to associate an agent with a human role. Asking it to act as a software architect or backend engineer gives it a familiar frame within the engineering knowledge represented in its training. While this initially seems like a plausible solution, it can also carry over the bureaucracy associated with the role. For example, a workflow might assign separate agents to act as an architect, developer and reviewer. A bounded change can then pass through a design document, an implementation plan and a review report, with each agent repeating the same context. The roles look familiar, but we still need to establish whether those steps improve the software.
This makes it necessary to rethink the construction process: which human-oriented procedures remain useful, and which can we remove or simplify? We are still experimenting with what works. In my own work, I start by reducing the decisions the agent has to invent. Before asking it to build, I define the domain’s meaning, the rules the construction must preserve and the purpose of the system. I capture these in three documents: a domain profile, invariants and intent. Together, they give the agent a defined context to work within. The agent’s entry-point file, AGENTS.md or CLAUDE.md, references all three documents.

Domain profile: reducing the agent’s world
The agent brings patterns from many domains. Before asking it to build a crypto-options engine, I define the domain it should work within. That is the role of the domain profile. It establishes the concepts the system uses, what they mean and how they relate. It defines:
- Scope: which instruments and market categories belong in the domain.
- Meaning: how contracts, prices, volatility, Greeks and exposure are represented.
- Qualification: which units, sources and times must accompany a value.
- Lifecycle: how trading, expiry, exercise and settlement differ.
- Authority: which decisions belong to the engine, libraries or venue specifications.
By loading the profile, I reduce the agent’s world. It has a declared set of meanings to use instead of choosing freely among the conventions it has learned.
For example, “price” is too broad for a crypto-options engine. A bid, mark, valuation and settlement price serve different purposes. The profile establishes those distinctions. It also requires the unit, basis, source and time needed to interpret a value. The profile requires an explicit rule before one price can be substituted for another. Volatility has similar requirements. A venue may represent 80% volatility as 80, while the canonical decimal representation is 0.8. The translation must be explicit. Implied, realized and forecast volatility also remain distinct.
The profile does not choose the strategy or its risk limits. It defines the domain within which those choices must be made. A particular engine can narrow that domain (for example, to one asset and one settlement style) while preserving its meaning. The agent still has implementation choices. What it no longer has to invent is the domain those implementations represent.
Invariants: setting the development rules
The domain profile defines the world the agent works within. Invariants define the rules it must follow when building software in that world. I use this document to establish what every valid implementation must preserve. Some concrete examples are:
- Each concept has one owner. The agent uses the existing instrument definition instead of creating another version inside the risk module.
- Calculations have no hidden external actions. An exposure calculation receives prices as inputs. It does not fetch them from an exchange while calculating.
- Dependencies follow declared boundaries. Engine logic uses an explicit capability to interact with a venue. It does not import the venue adapter directly.
- Expected failures are explicit. An unavailable exchange response produces a failure result. The agent cannot log the error and continue as if the request succeeded.
- Inputs have no hidden defaults. A missing input cannot silently become a convenient value that changes the calculation’s meaning.
- Tests establish behaviour. A test checks the resulting exposure, rather than only checking that a calculation function was called.
These rules reduce the construction choices available to the agent. It can choose an implementation within the boundaries, but it cannot redefine them to make the task easier. Each invariant states what must hold, what would violate it and how it can be checked. Some rules can be enforced automatically through hooks, pre-commit checks and CI. Others require behavioural tests or review. A check for prohibited imports cannot prove that an exposure calculation is correct.
The result is a shared set of development rules across tasks and agents. The agent has less to guess about how to build, and I have a clear basis for checking its work.
Intent: defining what the system should do
The domain profile defines the world. Invariants set the development rules. Intent defines the particular system we want to build. This comes from traditional development practices: understanding the problem, defining requirements and establishing acceptance criteria. With an agent doing the implementation, those decisions still need to be made. I use the intent document to define:
- Purpose: why the system exists and who it serves.
- Outcomes: what observable result it must produce.
- Requirements: what it must do to achieve that result.
- Scenarios: how it should behave under normal and adverse conditions.
- Constraints and non-goals: its limits and what it must not attempt.
- Acceptance: how we establish that the required behaviour works.
For a trading engine, intent starts with the market idea: what recurring behaviour we intend to trade, why it should create an edge and what would invalidate it. For example, 'build a crypto-options engine' leaves almost everything open. An engine that monitors opportunities, one that places orders, and one that manages existing positions have different purposes and therefore require different intents. If the intent is to monitor opportunities, the requirements might include evaluating candidates under defined conditions and reporting the result with supporting evidence. Placing orders would be explicitly excluded. Adding execution requires a change to the intent.
Acceptance also needs to be concrete. When required market data is missing, the system must report that it cannot complete the evaluation. When the data is sufficient, it must evaluate the candidate and explain the result. Both behaviours belong in the definition. Intent gives the agent a clear target and limits the scope it may build. Every capability must trace to a requirement. A missing decision remains a question to resolve, rather than becoming an assumption hidden in the code.
How the three definitions work together
Consider delta hedging. The phrase sounds specific, but it still leaves several kinds of decision open:
- Profile: defines what delta means, its unit and basis, how position deltas are aggregated, and how the inputs are qualified.
- Invariants: require the exposure calculation to receive explicit inputs, keep exchange access behind a declared boundary and represent expected failures explicitly.
- Intent: specifies the permitted exposure band, when to hedge, which instruments may be used, the target exposure and what to do when the hedge cannot be completed.
Acceptance scenarios then check exposure inside and outside the band, invalid inputs, an unavailable hedge instrument and partial hedge execution. The profile supplies the meaning, invariants constrain construction and intent supplies the decisions for this engine. The implementation must produce evidence that those definitions hold; loading the documents alone does not establish compliance.
Options OS as a concrete implementation
This approach is not theoretical. It is the architecture behind Options OS. In Options OS, these three documents are not optional documentation,they are the agent’s primary entry point.
The shared domain conventions and construction laws are already established. The author defines the particular trading system, and the agent builds within those boundaries. The profile supplies the domain language, the invariants constrain the construction, and the intent supplies the decisions for this specific engine.
The Options OS documentation describes the full construction model: how the trading engine intent translates into engineering specifications, how the repository is structured, and how the agent control layer enforces the invariants during construction. It is the practical counterpart to the principles in this article.
A smaller world to build within
Together, these documents answer three questions: what do the concepts mean, what development rules must hold, and what should this system do? The documents can be substantial, but each task needs the relevant rules and requirements. Their purpose is to reduce the choices the agent must invent and give us a clear basis for checking its work. From here, we move to codebase architecture: organising the implementation so its structure reflects those definitions. I will describe that in the next article.
The rules also need enforcement. Loading an invariant does not prove that the agent followed it. I use hooks and a custom agent control layer to check changes and catch violations during construction. I will cover that separately.
This is my current practice for making human-language development more manageable. I judge it by whether the software preserves the defined meaning, fulfils its purpose and requires less correction.
For your own build, start with three questions: what do the concepts mean, what must every implementation preserve and what exactly should this system do? The Options OS documentation is the next place to inspect how those definitions connect to construction and to see the working system that results from them.