Manifesto
The Owned Software Manifesto
Build with AI. Own what you build.
Software should be useful.
It should solve a real problem for a real person. It should survive contact with production, change without collapsing, and explain itself well enough that someone can repair it at 2:00 AM without performing archaeology by flashlight.
AI can help us build that software.
It can help us explore an idea, challenge an architecture, draft contracts, write tests, trace failures, refactor modules, explain unfamiliar code, generate documentation, and compress weeks of mechanical work into days.
We should use it.
Aggressively. Curiously. Throughout the entire software lifecycle.
But we should not confuse generated software with owned software.
A system is not ours merely because it exists in our repository.
We own it when we can explain it, defend it, change it, and accept responsibility for what it does.
AI-assisted construction
↓
Verified working system
↓
Human review and comprehension
↓
Owned softwareThat final step is not optional.
What we want
We want to build useful software.
Not demonstration software built to impress a meeting. Not dependency collections assembled because the tools were fashionable. Not architecture shaped ten imagined quarters ahead of the problem.
We want software that helps someone do something worth doing.
We want to build maintainable software.
Not merely code that compiles. Not merely code that passes tests. Software whose structure communicates its purpose, whose names reveal its boundaries, and whose failures leave evidence rather than folklore.
We want AI involved in every phase where it adds value:
- discovering and clarifying problems;
- exploring alternatives;
- planning incremental delivery;
- designing contracts;
- generating implementation;
- reviewing code;
- finding security and correctness risks;
- writing and improving tests;
- investigating failures;
- refactoring;
- documenting;
- teaching unfamiliar concepts;
- preparing releases;
- operating and learning from the system.
But we want to own the result.
That means AI is a collaborator, accelerator, critic, and power tool.
It is not the accountable engineer.
Principle 1: Working is necessary, not sufficient
Software that does not work is unfinished.
Software that works but cannot be understood is also unfinished.
A passing suite proves that tested behavior remains intact. It does not prove that:
- the architecture is coherent;
- the code is safe;
- the abstractions are useful;
- the names communicate intent;
- the tests cover the dangerous boundaries;
- the system can be modified without fear;
- another engineer can find the relevant code;
- the generated implementation is the simplest reasonable design.
The acceptance criterion should not stop at:
Tests pass.
It should include:
A competent engineer can locate and explain the important path without spelunking through a 2,000-line file or decoding a compiler riddle.
Principle 2: The human owns the meaning
AI can generate syntax quickly.
The human must decide what the system means.
Consider an LLM execution system.
AI can implement retries, fallback, replay, budgets, persistence, and comparison. But a human must decide:
- what counts as success;
- whether fallback is healthy recovery or degraded service;
- whether fewer tokens are actually better;
- whether a provider failure is capacity, outage, timeout, or rejection;
- when replay data may be retained;
- how long sensitive input should exist;
- whether an ambiguous provider call may be retried;
- which tradeoffs should remain visible instead of becoming one magical score.
Those are not implementation details.
They are the product and safety semantics.
AI may propose them.
Humans must understand and choose them.
Principle 3: If we cannot explain it, we do not own it yet
Ownership does not require memorizing every line.
It requires a reliable mental map.
We should be able to answer:
- Where does a request enter?
- Which module owns this decision?
- Which contract crosses this boundary?
- Where is sensitive data encrypted?
- Which code performs retries?
- What prevents duplicate work?
- Where is the final outcome recorded?
- What breaks if this type changes?
- Which limitations are deliberate?
- Which behavior is protected by tests?
When the answer is:
There is probably a generic somewhere in
index.ts.
the software is asking for a comprehension pass.
This is not personal failure.
It is maintainability evidence.
Principle 4: Prefer explicit meaning over clever compression
Type systems are tools for making invalid states difficult to represent.
They should not make valid ideas difficult to understand.
This type may be technically correct:
type EventPayload = ExecutionEvent extends infer Event
? Event extends ExecutionEvent
? Omit<Event, keyof EventGenerated>
: never
: never;But it asks the reader to understand conditional-type distribution, infer, union behavior, and reverse subtraction before learning the domain idea.
The domain idea is simple:
Event payload supplied by the domain
+
Metadata generated by the recorder
=
Stored eventAn explicit model costs more lines:
type AttemptStartedPayload = {
type: "attempt.started";
attemptNumber: number;
provider: string;
model: string;
};
type RetryScheduledPayload = {
type: "retry.scheduled";
attemptNumber: number;
delayMs: number;
reason: string;
};
type ExecutionEventPayload =
| AttemptStartedPayload
| RetryScheduledPayload;But the meaning is cheaper.
Conciseness is not clarity.
Cleverness must earn its rent.
Principle 5: Structure should reveal purpose
A useful file name answers:
Why would I open this file?
Good homes have names such as:
execution-service.ts
event-recorder.ts
retry-policy.ts
replay-capability.ts
lease-heartbeat-controller.ts
comparison-projection.ts
saved-scope.tsWeak homes have names such as:
utils.ts
helpers.ts
shared.ts
misc.ts
index.tsA package entrypoint should be a map, not a city.
export * from "./execution/execution-service.js";
export * from "./durable/durable-execution-worker.js";
export * from "./replay/replay-store.js";It should not contain the entire civilization.
The opposite failure matters too.
One function per file is not architecture. It is confetti.
We want cohesive modules with one nameable purpose, not a treasure hunt with 300 tiny drawers.
Principle 6: AI output is a proposal until reviewed
Generated code may be:
- correct;
- subtly wrong;
- overengineered;
- underexplained;
- insecure;
- inconsistent with the domain;
- brilliantly useful;
- all of these in the same commit.
We should treat generated output as a strong draft.
Review asks:
- Does it solve the requested problem?
- Does it preserve the intended boundaries?
- Does it invent new semantics?
- Does it silently weaken safety?
- Does it add a fashionable dependency for a trivial job?
- Does it create a god file?
- Does it claim a guarantee the system cannot provide?
- Does it conceal missing evidence by converting it to zero?
- Is there a simpler explicit design?
- Can we explain it afterward?
AI-assisted speed increases the need for judgment.
It does not reduce it.
Principle 7: Use AI throughout the lifecycle, not only to emit code
The shallow use of AI is:
Write this feature.
The stronger use is a loop:
Clarify
→ Plan
→ Implement
→ Verify
→ Inspect
→ Explain
→ Refactor
→ Operate
→ LearnClarify
Ask AI to identify ambiguity, assumptions, risks, and missing decisions.
Plan
Use AI to propose bounded vertical slices, non-goals, completion signals, and rollback points.
Implement
Generate code, tests, migrations, documentation, and tooling.
Verify
Run type checks, tests, security scans, audits, and manual scenarios. Require truthful reporting of what actually ran.
Inspect
Review architecture, semantics, error handling, sensitive-data boundaries, and failure modes.
Explain
Ask AI to teach the code in plain language. Replace explanations that require the reader to already understand the trick.
Refactor
Use AI to split oversized modules, clarify types, preserve public APIs, and reduce the cost of understanding.
Operate
Use AI to investigate incidents, correlate evidence, summarize timelines, compare strategies, and improve runbooks.
Learn
Feed production evidence back into design.
AI should participate in the whole lifecycle.
Human ownership should govern the whole lifecycle.
Principle 8: Evidence beats confidence
AI can sound certain when it is wrong.
Humans can too.
Owned software prefers evidence:
- explicit contracts;
- typed outcomes;
- append-only events;
- normalized errors;
- reproducible tests;
- traceable decisions;
- measured behavior;
- documented limitations;
- comparison against alternatives;
- drills for failure and recovery.
A system should be able to say:
The first provider timed out. The policy retried once. The second response failed schema validation. Fallback succeeded. The execution completed as degraded after 2.4 seconds.
That is better than:
The AI acted weird.
Evidence turns disagreement into investigation.
It also makes AI assistance safer because generated claims can be checked against recorded behavior.
Principle 9: Never invent guarantees
Distributed systems punish confident wording.
A lease is not exactly-once execution.
An abort signal does not prove a provider did nothing.
Encryption with environment keys is not production key management.
A successful HTTP response does not prove valid structured output.
A passing unit suite does not prove the system survived a worker crash.
A replayed response is not automatically semantically equivalent.
A lower token count is not automatically better.
Owned software states what it knows, what it infers, and what remains ambiguous.
Useful phrases include:
- observed in this time window;
- unavailable evidence;
- degraded success;
- provider outcome unknown;
- best-effort cancellation;
- prototype key management;
- no universal winner asserted;
- authenticated actor unavailable.
Honest limitations are part of the design.
Principle 10: Security boundaries require human comprehension
We should never accept:
The encryption code passed.
as the entire security review.
We need to understand:
- what is encrypted;
- when plaintext exists;
- which key encrypts which purpose;
- what forms the authenticated context;
- who may read or delete the data;
- when the payload expires;
- what remains in logs;
- what survives backups;
- how rotation works;
- how tenant isolation is enforced;
- what fails closed.
Sensitive execution commands and replay capsules may both contain prompts, but they have different purposes and lifecycles.
Execution command:
exists temporarily so accepted work can run
Replay capsule:
exists only when policy allows later reproductionAI may implement both correctly.
The owner must still know the difference.
Principle 11: Public interfaces should remain stable while internals improve
Ownership includes changing structure without casually breaking users.
A refactor may move:
core/src/index.tsinto:
core/src/execution/execution-service.tswhile preserving:
import { ExecutionService } from "@example/core";The public address remains stable.
The internal city gains street signs.
Before and after major refactors, compare:
- exported symbols;
- API schemas;
- database migrations;
- event wire shapes;
- behavior tests;
- generated declarations;
- consumer type checks.
AI is excellent at moving volume.
Humans must protect the contract.
Principle 12: Documentation is part of the software
There are several audiences.
Builders need
- architecture;
- codebase maps;
- system flows;
- TypeScript patterns;
- ADRs;
- test strategy;
- operating limits.
Integrators need
- API contracts;
- examples;
- authentication and error behavior;
- versioning.
Operators need
- what the product does;
- how to run an experiment;
- how to interpret a timeline;
- how replay differs from playback;
- how to compare variants;
- how to investigate signals;
- what unavailable evidence means.
Future owners need
- why the system exists;
- where responsibilities live;
- which tradeoffs were deliberate;
- what should be reconsidered next.
If the product requires its author standing beside every user, the documentation boundary is unfinished.
Principle 13: Human review should test comprehension
A review should include “find it” exercises.
Can an engineer quickly locate:
- request acceptance;
- event creation;
- retry delay;
- fallback selection;
- structured-output validation;
- replay capability;
- durable job claim;
- lease fencing;
- comparison projection;
- investigation signals;
- saved-case scope;
- the API route that exposes the feature?
If the answers require search archaeology, the source tree is not communicating the architecture.
This test is qualitative.
It is also real.
Principle 14: AI should increase ambition without eliminating restraint
AI makes larger systems cheaper to begin.
That does not make every possible feature worth building.
We should still ask:
- Does this solve a demonstrated need?
- Is the current slice complete?
- Are we building product value or platform furniture?
- Is the dependency justified?
- Is another abstraction necessary?
- Are we predicting schemas ten steps ahead?
- Can this wait?
- Does the next feature deepen the product’s identity?
AI can generate a queue, policy DSL, plugin framework, event bus, and Kubernetes deployment before lunch.
Restraint remains an engineering skill.
Sometimes the best AI-assisted decision is:
Do not build that yet.
Principle 15: Ownership is demonstrated through change
The final proof is not explanation alone.
It is the ability to modify the software safely.
An owner can:
- diagnose a semantic mismatch;
- locate the relevant module;
- explain the invariant;
- change the implementation;
- update tests;
- preserve public contracts;
- update documentation;
- verify the result;
- state the remaining limitation.
That is the difference between touring generated code and maintaining a system.
Our working agreement with AI
We will ask AI to:
- explore;
- challenge;
- generate;
- test;
- review;
- explain;
- refactor;
- document;
- investigate;
- help us learn.
We will not ask AI to carry responsibility it cannot carry.
We will verify important claims.
We will reject code we cannot justify.
We will replace cleverness that obscures the domain.
We will preserve evidence.
We will state limitations honestly.
We will keep the architecture proportional to the problem.
We will pause feature growth when comprehension falls behind capability.
We will use AI to build more ambitious software.
We will still own the machine.
The test
Before calling AI-assisted software complete, ask:
Useful
Does it solve a real problem?
Correct
Does evidence support its behavior?
Safe
Are security, privacy, and failure boundaries understood?
Maintainable
Do names, modules, contracts, and tests communicate intent?
Explainable
Can a competent engineer trace the important flows?
Modifiable
Can we change one responsibility without disturbing unrelated systems?
Honest
Does the software state what it does not know?
Owned
Can a human accept responsibility for this system?
If the final answer is no, the work is not finished.
Closing
AI changes the economics of software construction.
It lets one engineer explore more, build faster, test wider, and reach designs that previously required a larger team or a longer calendar.
That is extraordinary.
But faster construction does not eliminate engineering ownership.
It makes ownership more important.
The future should not be humans typing every line by hand.
It should not be humans approving opaque generated systems with a green checkmark.
It should be humans and AI building together, with software that is more useful, more ambitious, more observable, and more understandable than either could produce alone.
Working software runs.
Owned software can be trusted, explained, repaired, and changed.
Build with AI.
Own what you build.