AGPL-3.0-or-later · forever.

Thibaut Melen · Origins | Language · retrospective · · published · 4 min

The file came before the language

The first durable Nika decision fit in two words: a file. Syntax, graphs and providers came later.

Before anyone argued over syntax, one boundary had already been drawn: the useful part must become a file.

Not YAML. Not Rust. Not even a workflow language yet. First, AI work had to leave the chat and become an object a person could keep.

That object separated three things chat products kept mixing together:

  1. the conversation used to discover a method;
  2. the method itself;
  3. one execution of that method.

A transcript can contain all three, but it cannot reliably tell them apart. It keeps the correction beside the instruction, the result beside the request, and the final method beside the dead ends that produced it.

A file creates a boundary. It says: this is the part meant to survive.

The object had to describe work #

The early mental model was short enough to write without syntax:

text
read these inputsrun these stepsuse a model herecall a tool therewrite the result here

No transcript. No simulated team. No invisible planning ritual.

This is why the language later became task-shaped. A task has an identity and an effect. Dependencies form a graph because real work already has dependencies, whether the author names them or leaves the runtime to guess. Outputs are named because the next task needs an object, not a memory of what appeared three messages ago.

YAML came after that. It was a practical container for a document people could read without first learning a compiler. The deeper choice was that the document would describe intent while the runtime remained responsible for execution.

A file changes when review can happen #

Putting the method in a file does more than preserve it. It moves review ahead of execution.

A teammate can inspect the inputs before a model sees them. A diff can show that one host or output path changed. A checker can reject a broken reference without paying for a model call. The run can retain the identity of the bytes it received instead of pointing vaguely at a mutable chat thread.

This was the first version of a rule Nika would keep sharpening: authority should be visible before the effect it authorizes. The November idea did not yet contain a permits grammar or a static checker. It created the place where those mechanisms could later live.

The file also makes refusal ordinary. A chat product tends to reward forward motion. A source file can fail a review, sit unchanged for a week and return with the exact same bytes. That pause is a feature when the file may spend money, run a process or write to disk.

Portability started as a writing rule #

Provider independence is often described as an adapter feature. Here it started earlier, as a test for the file.

If a method only makes sense inside one chat product, it is not yet portable. The durable parts are the inputs, the graph, the boundaries and the expected output. A model is one selection inside that description. It may change because a better model appears, a local model becomes sufficient or a provider disappears.

The work should still be recognizable.

That rule remains visible in a Nika workflow. Changing model: does not require a second language. Moving from a laptop to a server does not require a second graph. The runtime may change where the work happens without changing what the work is.

Portability does not mean identical outputs from every model. It means the declared plan remains legible when the execution seat changes. The provider may answer differently. The workflow still says what was asked, what fed it and what may happen next.

The first public echo #

The first public nika.sh commit arrived on December 30. Its landing page already showed a file named workflow.nika.yaml, a Rust command-line runner, task ordering and more than one model provider.

That commit does not prove a complete language existed in November. It proves the file decision had survived long enough to become the public center of the product a month later.

The page also carried syntax and claims that would be removed. This is exactly why the file must be more durable than any one representation of it. A container can survive while its grammar gets stricter and its promises learn restraint.

The evidence boundary #

This is a retrospective, not a recovered November changelog. There is no public November commit to cite. The evidence is the October note on one side and the first nika.sh page on the other.

So November does not receive an invented parser, a perfect first syntax or a tidy sequence of milestones. It receives the narrower decision the surviving record supports: AI work worth repeating should become a durable object, readable without the service that executes it.

The syntax would change. The file would not.

Once the work had an object, it needed a public face. The first one arrived in December, carrying a real idea and more confidence than the code had earned.