ExoCode
A practical daily cycle that turns programming into systematic theory building.
Objective
Provide a development loop suitable for AI integration: code is generated while the architecture remains clearly understood.
Result
Since programming can be viewed as theory building [1], i.e. knowledge creation, a development loop that integrates Popper's and Lakatos' views on knowledge growth has been defined.
It is simple enough to be applied for day-to-day programming and suitable for AI-assisted programming. It is aimed at small teams of up to 10 people and additional AIs. The development loop is:
ExoCode
- Start:
dev(developer or AI) MUST creates a short-lived branch from trunk and SHOULD add an iteration toiterations/dev.org. - Work: build refined objectives and candidates using a temporary
discussion.orgfile to accumulate prompts. - Integrate: distill key refutations from
discussion.orginto the iteration's Retrospective section. Open PR (CI-gated). Fast review (human + AI). Rebase to trunk then delete the branch.
RFC 2119
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
Iteration
An iteration is a template used to guide the growth of a code base toward reaching a new objective. Once agreed upon, it allows some degree of concurrent development. Provided that the objectives of each iteration do not overlap, they may occur concurrently. An iteration scope is defined by the interfaces it requires and the interfaces it provides.
All sections are optional except Objective and Result. Judgment should be applied to keep the process as light as possible. A plan is the analog of a proof, albeit much less rigorous [2]. The template is:
* TODO 🞎 :PROPERTIES: :TYPE: d0305c80-3399-4e07-b4ba-ee8c22eacb19 Iteration :EFFORT: 0:00 :END: ** Context - MAY define a list of materials or references to materials that clarify the following content. ** Objective - MUST define WHAT we want. ** Test - SHOULD define new assertions to be verified, provided the objective is claimed to be reached. ** Plan - MAY define steps — i.e. a tree of assertions — at the end of which the objective is reached. ** Risks - MAY define a list of risks — i.e. assertions that MUST NOT be verified. ** Log - MAY define a list of notable propositions discovered during this iteration execution. ** Checklist - [ ] Stakeholders updated. - [ ] Time has been logged. ** Result - MUST provide a quick summary of the result and links to artifacts, if any. ** Review - Demo is reproducible by the client - Feedback ** Sign-off - Client acceptance: [YES/NO] - If milestone → invoice issued - Next iteration planned ** Retrospective - Liked: what went well - Learned: new insights / techniques - Lacked: what was missing / painful - Longed for: what we wish we had - Action Items: what should be carried forward
iterations/*
iterations/dev.org is a file that accumulates iterations sequentially on trunk
authored by one developer or AI. Given N developers or AIs, we would have N files. We
call them: iterations/*.
Prompt
A prompt structures the content emitted by developers and AIs while executing an iteration. It forces the externalization of the tacit theory-building process. Here is the prompt template:
* Prompt ** Context - MAY define a list of materials or references to materials that clarify the following content. ** Objective - MUST define /what/ we want. ** Test - MUST define new assertions to be verified, provided the objective is claimed to be reached. ** Plan - MAY define steps — /i.e./ a tree of assertions — at the end of which the objective is reached. ** Candidate - The candidate solution so far. In practice, this section is replaced by an implicit $ git diff or equivalent. ** Discussion - Merciless criticism: What flaws exist in this candidate? - *Record of Refutation:* If this candidate is rejected, briefly note WHY here. This knowledge must be transferred to =iterations/dev.org= before the branch is merged. ** Circuit Breaker Before executing the candidate, evaluate its structural impact: - [ ] This solution only requires implementation logic changes: proceed. - [ ] This solution requires altering =architecture.org=. *HALT*: Suspend this prompt and initiate a broader architectural iteration.
architecture.org
architecture.org specifies WHAT the program does and HOW it does it using various
specialized languages (e.g. Type Theory, Actor Model). Sections act as documentation
for the associated code. Bidirectional links between specification and implementation
ensure non-ambiguous correlations.
Platform
Something like github.com, codeberg.org.
License
A contribution, i.e. added materials through merges, uses the same license as the
project: mplv2, lgplv3+, gplv3+. It is owned by its author; no copyright assignment
required. Does not include non-trivial code from other projects unless the
contributor is the original author.
Branches and commits
Given an iteration in iterations/dev.org named "TODO 🞎", then the matching branch
name is "dev/🞎" and the first line of the commit is "DONE dev/🞎". Same
cross-referencing as in architecture.org using UUIDs mays be used if necessary. The
commit history looks like:
DONE ai/updated-ui DONE dev/image-processing-steps …
Example
Consider the task of adding support for SEPA Instant Credit Transfers to a payment orchestration system written in Rust.
On a short-lived branch the following iteration entry is added to iterations/dev.org:
* TODO sepa-instant :PROPERTIES: :TYPE: d0305c80-3399-4e07-b4ba-ee8c22eacb19 Iteration :EFFORT: 0:00 :END: ** Objective Support SEPA Instant payments with end-to-end processing under 10 seconds while maintaining idempotency and regulatory compliance. ** Risks - Breaking changes to payment routing logic - Increased load on fraud detection service ** Result Added =PaymentProviderSEPAInstant= implementing the =InstantPayment= trait. Updated routing table in =architecture.org=. All latency and compliance tests pass. Merged after 4-hour branch lifetime.
During the Work phase, a temporary discussion.org on the same branch contains
three successive prompts that refine error handling and idempotency guarantees
before any code is written. The surviving candidate is implemented, tests are added,
the architecture guard is verified (no change to architecture.org required beyond
a small routing-table update), and the branch is merged via squash after fast CI
and human+AI review.
Discussion
A prompt's objective corresponds to Popper's P₁ step. A prompt's candidate corresponds to Popper's TT step. A prompt's discussion corresponds to Popper's EE step. The next prompt's objective corresponds to Popper's P₂ step. The prompt's diagnostic corresponds to Lakatos' distinction between progressive and degenerative programs.
Together, the files iterations/*, architecture.org and the source code itself
ground Naur's "Programming as theory building" into different points of view, each
expressed in its own formal language.
While iterations/* provides a dynamic view of the program evolution, pursuing
ever more ambitious objectives, architecture.org provides an integrated view of what
the program does and how it does it after a given sequence of iterations.
In particular, architecture.org answers most questions starting with Why, What
and How using simple, mathematically grounded languages that yield reasonable code.
This offers a common ground for AIs and developers. While tacit knowledge cannot be
fully captured, enough should be made explicit so that a shared picture of the system
can be maintained.
Conclusion
This Development Loop externalizes the tacit theory-building process of programming
into explicit, version-controlled artifacts. By combining short-lived branches with
persistent evolutionary (iterations/*) and structural (architecture.org)
documentation, it enables high-velocity AI-assisted development without sacrificing
architectural clarity or conceptual integrity.
The integration of Popper's critical rationalism and Lakatos' research programme framework provides a rigorous yet practical scaffold for knowledge growth in software systems. The result is a method that scales from solo developers to small teams augmented with multiple AIs, while keeping the cognitive overhead low enough for daily use.
The stated objective is achieved: code is generated rapidly, yet the theory behind the system remains explicit, understandable, and evolvable.