3 Commits
Author SHA1 Message Date
AnachronautandClaude Opus 5 eaeb473176 ls says in green what the shell will start
Directories were already blue. Something the shell will run is green now,
and it is asked by LOOKING rather than looked up.

This was priced once as needing a runnable bit in the directory entry,
set by the filesystem from a list of magic numbers it would have to be
taught - declined twice, for putting format knowledge in the filesystem
and giving two implementations a registry to keep in step.

It costs nothing of the sort any more. The shell decides what to run by
reading a file's first block, so "will this run" is a question with an
answer already, and this asks the same one the shell would: SBEX for a
program, "#!" for a script. Nothing is written down and nothing has to
agree about anything.

The price is a block read per file, which is exactly what the bit existed
to avoid: a listing of thirty seven files went from 260,593 cycles to
635,321. It is paid in ls and not in dir on purpose - dir is the listing
you audit and is built into the shell, this is the one you read and was
loaded off the disk anyway. The fast one stays fast.

plain.script is the proof on the test disk: it sits among a dozen scripts
that are green and is not one, because it is the fixture with no shebang
and the shell will not start it. The extension is decoration and the
colour is the truth, which is the whole of what running by content means,
finally visible.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-09-06 19:53:33 -04:00
AnachronautandClaude Opus 5 afda6ca83b Finishing says nothing, which is what finishing looks like
The shell printed "finished" every time a program gave the machine back.
That made sense when starting a program and getting the machine back was
most of what the machine did and the prompt was the only other thing on
the screen. Under a listing, between two commands, it is noise.

And it was printed whatever the program made of it, so a program that had
just explained what went wrong was answered with the word "finished" -
"there is no such directory: nowhere" and then, immediately, "finished".

The prompt coming back is what says a program is over. It is the same
argument osLastStatus is made of: a program that failed has already said
so in words, and anything the shell adds beside that is the shell talking
over it. A program that FAULTED still says so, because the fault screen
printed in red above and a program that is gone should not look like one
that ended.

A NEWLINE ONLY IF ONE IS WANTED. A program that stopped part way along a
line would leave the prompt sitting in the middle of its last output,
which the word used to prevent by accident. The console knows which
column the cursor is in, so the shell asks - where a blank line printed
every time would be right about half of the time, and an empty directory
listed with ls would be followed by a blank line for no reason.

Fifty nine recorded sessions lose the word. Two of them move a cursor up
a row with it, which is the same fact seen from the screen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-09-06 19:49:43 -04:00
AnachronautandClaude Opus 5 a13bbeb4db ls, a listing laid out to be read
> ls
  Copy.sbx   Say.sbx    Where.sbx  Walk.sbx   ls.sbx     Lander     where.sh

dir says what is there one line each, with sizes and a tally of the disk.
This says the names in columns and nothing else, which is what you want
ninety times in a hundred. Two programs rather than one with a switch,
because they answer different questions and neither answer is a worse
version of the other.

AND THIS IS A PROGRAM WHERE DIR IS BUILT IN, which is the difference that
matters when the disk is what you are doubting: dir is already in memory
and this has to be loaded off the disk it is about to list. The daily
driver and the diagnostic.

Two passes over the directory and no buffer at all. Columns need the
longest name before the first line can be printed, which usually means
holding every name - twenty four bytes each against a format that allows
1,024 entries. Walking twice costs a read of each directory block, into a
buffer that is already there.

Across and not down. Real listings go down the columns so that names next
to each other alphabetically are next to each other on the screen, and
that reason depends on sorting - which nothing here does. With the order
arbitrary, down-and-across buys nothing and costs a division.

Directories in blue and wearing a separator, unfinished saves in red,
everything else plain: whether a file is runnable cannot be known without
opening it, and opening every file in a directory to colour a listing is
a price nobody agreed to pay. The colour reaches a terminal as well as
the screen, so it is one mechanism and not two.

---- Three bugs, and one of them is this machine's oldest trap ----

nameLength answered in A, and a RET puts A back the way the caller had
it. So it answered with nothing, and every gap between the columns came
out the same width because the padding was subtracting whatever A
happened to hold. Q is the ALU's output and nothing puts it back, which
is why every answer here comes home in it.

The padding subtracted the other way round - the name from the cell -
which borrowed on every name that was not the longest, so all of them
took the "wider than its cell" path and the listing came out separated by
one space.

And padding after a name left trailing spaces on every line that did not
fill its last column. It goes before the next name now, so spaces only
ever fall between two things and a line ends on a name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
2026-09-06 19:29:02 -04:00