Development Journal03 OCT 2026DiagnosticsNuDOSTesting

Project Ceylon Development Log — October 3, 2026: The Computer Has to Prove Itself

Illustrative dev-log poster for October 3, 2026: a stylized workbench scene with oscilloscopes, a soldered circuit board, and tools, centered on a large monitor showing an invented 'Full-System Validation Dashboard' with fake IPC latency/throughput charts, a storage validation gauge, and a services-up status list, flanked by invented 'Cross-Component Evidence Chain' and 'Validation Harness Flows' panels and three fictional blueprint diagrams (boot/service bring-up pipeline, end-to-end validation harness, cross-component evidence chain).
Concept art Illustrative poster: Project Ceylon Dev Log, October 3, 2026 — not a real screenshot, dashboard, or schematic

A couple of days ago I wrote that a green test is not the same thing as a working computer.

Today we spent more time making that statement inconveniently literal.

The work was not particularly glamorous.

No dramatic desktop screenshot.

No new application showing off.

No sudden miracle where every unfinished subsystem decided to cooperate at once.

Instead, we kept digging into something that has become increasingly important as Ceylon gets larger:

how do we prove that the pieces are actually complete, that they are talking to each other correctly, and that the complete machine still behaves the way the architecture says it should?

That question is starting to change how the project is being built.

The diagnostic work is becoming part of the system

We have been developing a more formal system-diagnostic approach rather than relying on a pile of independent unit tests and a few end-to-end smoke tests.

The reason is simple.

Ceylon now has enough moving parts that it is entirely possible for several components to pass individually while the complete path is still broken.

A provider can initialize.

A client can initialize.

A protocol can compile.

A local test can return PASS.

And the two sides can still disagree about identity, lifetime, ordering, authority, or what a successful response actually means.

That is not a theoretical concern anymore.

We have already seen it.

So the diagnostic model is being built around two questions:

Does each part do what it is responsible for?

and:

Do all of the parts still work together when connected as the actual computer?

Both have to be true.

One without the other is not enough.

We are finding incomplete work, not just bugs

One useful consequence of this is that the diagnostic work is exposing a category of problem that is slightly different from an ordinary bug.

Sometimes the code is not wrong.

Sometimes the code is simply not finished enough to support the behavior we thought the system already had.

That distinction matters.

A bug means an implemented behavior does the wrong thing.

An implementation gap means some part of the required behavior was never completed, never connected, or never qualified in the first place.

Those are easy to confuse when you are looking at a large system from the outside.

Something starts.

Something logs a plausible message.

Something returns a success code.

It is very tempting to mark the box complete.

The diagnostic work is forcing us to ask harder questions.

Did the request actually reach the next service?

Did the next service interpret it the same way?

Did the resource being referenced still belong to the same generation?

Did a successful response correspond to the exact operation that was submitted?

Did the result make it all the way back to the user-visible behavior?

And if one of those answers is "we don't know," then the feature is not proven.

Inter-system communication is where the interesting failures live

This is becoming one of the bigger lessons from Ceylon.

Individual components are relatively easy to reason about.

The boundaries between them are where things get interesting.

Once two protection domains or services have to cooperate, suddenly we have to care about:

  • who owns the object;
  • who is allowed to refer to it;
  • which generation of that object is current;
  • whether a response belongs to the request we think it belongs to;
  • what happens if either side restarts;
  • what state survives;
  • what state must be invalidated;
  • whether retries are safe;
  • and whether a timeout means "failed" or merely "we no longer know."

That is where a lot of operating-system correctness actually lives.

Not in the middle of one function.

At the seam between two things that each believe they are doing the right thing.

The new diagnostic work is being designed to exercise those seams deliberately.

NuDOS gave us a very good example

NuDOS was part of today's work, but it was not the whole story.

We have been preparing NuDOS for a much more serious implementation pass, which means taking the specification apart and asking whether it actually describes something we can build, test, and ship.

That produced a fairly substantial gap analysis.

The encouraging part is that NuDOS is not starting from zero.

There is already a bounded command/control foundation, existing console work, filesystem foundations, execution-container work, session concepts, logging, and the surrounding desktop architecture.

The less encouraging part is that "the pieces exist" is not the same thing as "the shell is complete."

The audit identified missing or insufficiently defined areas around things like command parsing, line editing, native Terminal attachment, logical locations, file operations, application launch, session isolation, output handling, restart behavior, diagnostics, and release evidence.

That is exactly the kind of gap the new diagnostic philosophy is meant to expose before we mistake partial infrastructure for a finished product.

A shell is not just a command parser

It would be very easy to build NuDOS by starting with:

DIR

CD

TYPE

RUN

and calling it a shell when those commands print something.

That would be quick.

It would also be sloppy.

A usable command environment has to answer much less exciting questions.

What happens when a filename contains spaces?

What happens with quotes?

What happens with malformed input?

What happens if the command is longer than the allowed buffer?

What happens if the user pastes multiple lines?

What happens if a file operation is interrupted?

What happens if a service restarts halfway through a request?

What happens if the shell receives a stale response from the previous instance of that service?

What exactly does "success" mean after a destructive operation if the provider disappeared before returning the final status?

Those are not edge cases you bolt on later.

They are part of the command environment.

So the NuDOS specification is being tightened around those behaviors before implementation races ahead of the design.

We attacked the parser instead of admiring it

Part of that work included adversarial parser testing.

The point was not to prove that normal commands parse.

That is the easy part.

The point was to throw quoting combinations, malformed input, boundary cases, and arbitrary data at the proposed grammar and see where the assumptions failed.

Thousands of quoting cases were exercised.

Then thousands more arbitrary-input cases.

That kind of testing is not glamorous, but it is exactly what I want before a command parser becomes the thing standing between user input and operations like file deletion or application launch.

A parser does not get credit for understanding:

DIR Home:

if it becomes confused by:

DIR "Home:My Folder"

or silently truncates something it does not understand.

The boring cases are where trust comes from.

The vertical test matters more than the command list

There is one test I particularly want for NuDOS because it crosses several systems at once.

The idea is simple:

Open NuBASIC.

Create something.

Save it.

Open NuDOS.

Find the same object.

Inspect it.

Reboot Ceylon.

Load it again.

Run it.

That is not really a NuDOS test.

It is not really a NuBASIC test either.

It is a computer test.

It exercises application behavior, object/file storage, the command environment, persistence, reboot recovery, and the relationships between all of them.

If every individual subsystem says PASS but that sequence fails, the system is not done.

That is exactly the kind of vertical test we are going to keep adding.

The rules are changing because the project is changing

One result of all this has been a tightening of the engineering rules.

Earlier in the project, a working demonstration was often enough to justify moving forward.

That made sense when the primary question was:

Can this architecture work at all?

We are past that stage in a lot of areas.

The question is increasingly:

Can this architecture work repeatedly, under the intended authority model, across failure and restart, with enough evidence that we know what actually happened?

That requires a higher standard.

"Code exists" is not completion.

"Tests pass" is not completion.

"A screenshot appeared" is not completion.

For important functionality, completion increasingly means the requirement exists, the implementation matches it, the target behavior is demonstrated, the negative cases are exercised, the integrated path is tested, and the result is reproducible.

That is a lot less exciting than declaring victory after the first successful run.

It is also how I would rather find problems now than six months from now.

Diagnostics need to test the tester

We are also keeping one particularly important rule from the failures that got us here:

the diagnostic itself has to prove that it can fail.

If a test is supposed to reject a stale generation, give it one.

If a test is supposed to catch an invalid identity, send one.

If a service is supposed to fail closed when a dependency disappears, remove the dependency.

If the diagnostic still returns PASS, we did not prove the system.

We proved the test is optimistic.

This sounds almost silly when written out.

It is surprisingly easy not to do.

Most tests are written to demonstrate success.

We are deliberately trying to write more tests that demonstrate the ability to recognize failure.

The eventual goal is a diagnostic mode for the whole machine

As this develops, I want Ceylon to be able to perform several levels of health checking.

A quick check should answer whether the important subsystems are alive.

A focused diagnostic should be able to drill into one area.

A full-system diagnostic should walk the important service relationships.

Longer runs should exercise soak, restart, reincarnation, stale-state rejection, resource exhaustion, and other failure behavior.

And the results should be useful after the fact.

Not:

ERROR 12

and good luck.

The machine should be able to tell us what it was testing, what it expected, what actually happened, and where the path diverged.

That will be useful during development.

It will also eventually be useful for support.

There is a big difference between a user saying:

"the computer doesn't work"

and a diagnostic saying:

"storage provider is healthy, filesystem is mounted, application launch is healthy, but this particular client cannot reattach after provider generation changed."

One of those ruins your afternoon.

The other gives you somewhere to start.

This is slower on purpose

There is always pressure in a project like this to move to the visible thing.

Finish the desktop.

Launch the applications.

Make the video.

Get the Alpha out.

I want all of that too.

But we have now seen enough cases where "looks finished" and "is finished" were not the same thing.

So some of the work right now is intentionally slowing us down.

We are identifying incomplete code.

We are testing the communication between systems.

We are tightening specifications.

We are adding negative cases.

We are defining vertical tests.

And when something fails, we are trying to fix the reason it failed instead of teaching the test not to complain.

It is a good thing I am ex-Navy.

I have a fairly extensive vocabulary available for the moments when that distinction becomes inconvenient.

Where we ended October 3

The biggest result today was not one repaired subsystem.

It was a clearer development rule.

Ceylon has to prove itself at three levels:

the component,

the connection between components,

and:

the complete user-visible behavior.

NuDOS is currently giving us a useful place to apply that discipline because its job touches the Terminal, session state, filesystem, application launch, diagnostics, and persistence.

The broader diagnostic system will carry the same idea across the rest of Ceylon.

That means more work now.

It also means fewer mystery successes.

I am becoming deeply suspicious of mystery successes.

They usually turn into tomorrow's bug report.