Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 116 additions & 23 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1232,31 +1232,56 @@ with errors` section is gone**, so this really is the test
interpreter. *The void run and this one differ in nothing but which
binary ran them, and that is the cleanest control this suite can
give.*
**`socket_inet.test` HAS LEFT THE FAILING-FILE LIST ENTIRELY**, and
sockets are half of the measured blast radius -- `sockaddr_in`
24 -> 16, `in_addr` 8 -> 4, `sockaddr_storage` 112 -> 110. *The
refutation condition was written down before the switch -- "a NEW
socket failure means something is computing a length it should not"
-- and the opposite happened in the one file named.* `socket.test`
still fails, which is the `_resettimer`/timer-process story and
predates this.
**AND THE SOCKET CONFIRMATION IS WITHDRAWN: THERE IS NO
`socket_inet.test`.** This round recorded *"`socket_inet.test` has
left the failing-file list entirely"* as the behavioural evidence that
`-J` had not broken the socket half of its own blast radius
(`sockaddr_in` 24 -> 16, `in_addr` 8 -> 4). **That file does not exist
and never did**: the suite has one `socket.test`, whose body is
`foreach {af localhost}` with `test socket_$af-1.1 ...`, so every
`socket_inet-*` name is GENERATED with `$af` = `inet`, and a grep for
`socket_inet-5.1` matches no file in the tree. *Its absence from the
list could not have been anything else under any outcome* -- and the
substance fails too: **`socket_inet` has four failures, 2.11, 5.1,
5.3, 7.3**, which is exactly the "`socket_inet` 4" already listed as
unread below. **A name absent from a list is not a measurement until
you have checked the name could ever have appeared there** -- an
absence has two explanations, the thing passed or it was never called
that, and only one is a result.
*The eighteen stand on `Total` and `Skipped` being identical with
`Passed` +18, which is sound. The ATTRIBUTION to sockets does not* --
so with the pthread half already recorded as skipped (`197 thread`,
`12 testmutex`), the behavioural confirmation of `-J` covers neither
family it actually moved.
**THE PTHREAD HALF IS NOT MEASURED HERE, and the skip table says so
rather than leaving it to be assumed**: `197 thread` and `12
testmutex` are SKIPPED, so `pthread_mutex_t` 56 -> 40 and
`pthread_cond_t` 56 -> 48 were barely exercised. *Half the blast
radius is confirmed and half is untouched*, which is a different
statement from "the suite is clean".
**TWO THINGS TO CHECK PER NAME BEFORE THIS IS CLOSED.** The totals
cannot tell 18 fixed from 20 fixed and 2 broken -- this tree's own
rule -- and `event.test` and `main.test` appear in the failing list
where the baseline notes had `event-1.1` and `Tcl_Main-5.10` as
unread singletons, so they are probably unchanged rather than new.
**And `socket_inet-5.1`/`5.3` were recorded as tests that SHOULD
fail** (`notRoot`, and glenda is the host owner): if they are among
the eighteen, that is the leftover-listener false pass returning, not
a fix. *A test that newly passes may be passing for the wrong
reason* -- and this is exactly the file where that has happened
before.
**BOTH PER-NAME QUESTIONS ARE NOW ANSWERED, AND A PER-NAME BASELINE
EXISTS AT LAST** -- `docs/notes/tcl-suite.md` carries all 43 names and
the extraction command, because *its absence is what kept this open
for rounds* while every comparison was made by total.
**`Total 68118 Passed 62159 Skipped 5916 Failed 43`**, marker,
exit 0, 167 files, four minutes, `tcl::test 9.0.3 present`.
- **`socket_inet-5.1`/`5.3` were NOT among the eighteen**: both are
still failing, so the leftover-listener false pass did NOT return.
That was the stated hazard and this is the good answer.
- **`event.test`/`main.test` were unchanged, not new**: by name they
are `event-1.1` and `Tcl_Main-5.10`, the two singletons already on
the list.
**AND 46 -> 43 IS THREE FIXED, NOTHING BROKEN, ALL THREE NAMED**:
`chan-io-41.8`, `expr-old-37.21` and `unixFCmd-2.2.2`, three entries
of the eleven unread singletons. *Three gone and the net is three, so
nothing arrived* -- the only form that confirmation can take, and the
first time this suite's movement has been attributed by name. **None
was predicted or being worked on**, so the vehicle is unidentified and
naming one would be a guess; the baseline makes the next run settle
it. (`io-6.46` and `chan-io-6.46` now both fail, which is the twins
rule working as written; zipfs is **five** `zipfs-password-*` cipher
tests where this file recorded three, one family undercounted from a
prediction rather than a regression.)

**AND THE FIRST REBUILD STOPPED IN bash -- NOT ON `-J`, ON A SHADOWED
HEADER.** `/sys/include/ape/qlock.h:44 syntax error, last name: Lock`,
Expand Down Expand Up @@ -1810,8 +1835,63 @@ live either way.
is reachable by regenerating the macro configuration rather than
by setting switches, and it changes mangling, the ctor/dtor model
and vtable layout. Its own round.
- **NO MKFILE, AND NOTHING HERE HAS BEEN THROUGH pcc.** That is the
next step and the link model is what it will run into.
- **THE MKFILES ARE WRITTEN AND NOTHING HAS BEEN THROUGH pcc YET.**
**It is THREE products, not one**, which `main` settles rather than
taste: `src`'s 75 files hold exactly one (`cfe.c`) so they are one
binary, `cpfe`; `util`'s seven hold six, plus `decode.c` with none
(it is `edg_decode`'s second object); `lib_src`'s 51 hold none, so
they are a LIBRARY. Hence `sys/src/ape/lib/edg` -> `libedg.a`
(`mksyslib`) and `sys/src/ape/cmd/edg` -> `cpfe` (`mkone`); `util`
is six small binaries and blocks nothing.
**DELIBERATELY NOT IN `cmd/mkfile`'s lists** -- one failing entry
aborts the whole tree's `mk`, as `basic` and `c++lib` already
record. By hand first.
**ORDER IS A DEPENDENCY RATHER THAN A PREFERENCE.** lib/edg first,
because an archive sidesteps the link model entirely -- `ar` takes
duplicate members and the clash only arrives at a LINK -- so it
answers "does pcc compile EDG's generated C" with nothing else in
frame. Then cmd/edg, where both remaining questions land.
**AND `mk -k`, NOT `mk`**: Plan 9 mk stops at the first failing
recipe, so a plain run costs one round per bad file across 75;
-k names them all at once. *That is the rule bacon's missing
headers and bacon's missing link symbols both paid for.*
**`src/sys_predef.c` IS 315,616 LINES IN ONE TRANSLATION UNIT**
(`ifc_modules_read.c` 130,330, `expr.c` 120,824; 2.9M lines over
the 133). A `6c` table limit is the likeliest first answer, and it
would be kencc's rather than the port's -- worth knowing before
anything is blamed on EDG.
**`cpfe` HAS NO `LIB=`, AND THAT IS A QUESTION, NOT A CLAIM.**
cpfe is itself a translated C++ program so it may want EDG's own
runtime, and *reading cannot settle it*: `src` holds 145,752
distinct `_Z`-prefixed tokens, nearly all names it defines itself,
with ordinary identifiers like `_ZERO` among them. Only the link
says which are undefined. It is not obviously needed -- EDG is
built `-fno-exceptions -fno-rtti` and `src` references none of
`_Znwm`/`_Znam`/`_ZdlPv`/`_ZdaPv`, `__memzero` or
`__abort_execution` -- so the first link is the measurement and
the fix, if any, is one line naming `libedg.a`.
- **AND THE RUNTIME ADDS NOTHING libap ALREADY PROVIDES, checked
rather than assumed.** `lib_src` holds `exit.c`, `main.c`,
`error.c` and `memzero.c`, which is the shape that cost this tree
the gnulib `strerror` round -- but **every DEFINITION there is
`_Z`-mangled or `__`-prefixed**: `exit.c` defines `_Z4exiti`,
`memzero.c` defines `__memzero`. The plain C names (`memset`,
`memcpy`, `malloc`, `free`, `abort`, `exit`) appear only as
DECLARATIONS and resolve to libap rather than replacing it.
*The filenames read alarmingly and the definitions do not* --
the declaration/definition distinction the `reject` round cost a
build over, asked the right way round this time.
**And EDG bakes in NO struct sizes**, which is the other thing
cfront's C did and the reason its oracle existed: zero
`sizeof X == N` markers against cfront's 132, because EDG emits
real `sizeof` expressions. *kencc computes every layout here*, so
conforming `-J` is exactly what the generated code wants and
`cfrontsz-probe`'s whole class of problem does not recur.
**Both OFILES lists are sound AND complete** -- 51 and 75, no
name missing a file and no file missing from a list, which are
different properties and only one of them was checked the time
the 47-of-97 probe passed its control and measured the wrong
types. `mkcont-sweep` 0.
- **Its staging list doubled as a to-do list for our own headers.**
Eight APE headers could not be included from C++; **four were
fixed on their own evidence** later in the same session
Expand Down Expand Up @@ -1983,6 +2063,15 @@ in the topic file.
`tcl-runall.tcl`; check for it before reading any total.
- **A marker says the run reached the end, not that it was the run you
asked for.** Read the `Total` line beside it.
- **A NAME absent from a list is not a measurement until you have
checked that the name could ever have been present.** An absence has
at least two explanations -- the thing passed, or it was never called
that -- and only one of them is a result. `socket_inet.test` was
recorded as having "left the failing-file list" and offered as the
behavioural confirmation of `-J`; **there is no such file**, the
names are generated inside `socket.test` by a `foreach {af ...}`
loop, and `socket_inet`'s four failures never moved. One `ls` would
have cleared it.
- **And check the log's own `Tests ended at` line before reading
anything from it.** A copied file that was never committed leaves the
previous run in place, and a stale log reads exactly like a real one.
Expand Down Expand Up @@ -2331,8 +2420,12 @@ or a constraint that fails on Linux too). The port's own share is
`focus-6.1`, `geometry-4.7`, `event-9.13`/`9.14` and `visual-3.1`.

**Tcl's suite**: **it finishes and nothing aborts.**
**`Total 68118 Passed 62156 Skipped 5916 Failed 46`** under `-J`,
167 files, marker, exit 0, no `Test files exiting with errors`.
**`Total 68118 Passed 62159 Skipped 5916 Failed 43`**, 167 files,
marker, exit 0, no `Test files exiting with errors`, four minutes.
**All 43 are listed BY NAME in `docs/notes/tcl-suite.md`** with the
one-command extraction beside them -- the first per-name baseline this
suite has had, and the thing whose absence made every earlier
comparison a total. The log is committed at `tmp/tcl-all.out`.
*(The baseline this is measured against is
`Passed 62138 Failed 64`, same Total and Skipped; the eighteen are
discussed in the `-J` section. A run in between reporting `Failed 37`
Expand Down
140 changes: 140 additions & 0 deletions docs/notes/tcl-suite.md
Original file line number Diff line number Diff line change
Expand Up @@ -7185,3 +7185,143 @@ multiplication's range, so `scalbn`'s broken arm was never involved.
Run it with `pcc -o binfloat-test binfloat-test.c && ./binfloat-test`
and read which section fails; that names the cause in one run instead
of by elimination.

---

## The per-name baseline: 43 failing tests, 2026-10-07

**This list exists because its ABSENCE kept one question open for
rounds.** This file's own rule is *compare runs per file, never by
total* -- and every Tcl round so far has been compared by total,
because no per-name list was ever written down. `Failed 46 -> 43`
cannot tell three fixed from five fixed and two broken; the names can.

Provenance, which has to be read before anything else here (the stale
log and the void `tclsh` run are both recorded above):

```
tcl-runall: tcl::test 9.0.3 present -- this is the test interpreter.
Tests began at 2026-10-07 17:50:49 +0200
Tests ended at 2026-10-07 17:54:57 +0200
all.tcl: Total 68118 Passed 62159 Skipped 5916 Failed 43
Sourced 167 Test Files.
tcl-runall: exit called (code 0)
```

The log is committed at `tmp/tcl-all.out`. **It does NOT contain the
four C++-usability header fixes** (`_Noreturn`, `template`, `new`,
`restrict`), which landed after this rebuild; it does contain the
`features.h`, `getopt` and `libnet.h` changes.

The 43, sorted, every one of which already appears somewhere in this
file or in CLAUDE.md:

```
Tcl_Main-5.10 chan-io-28.7 chan-io-40.3 chan-io-6.31 chan-io-6.43
chan-io-6.44 chan-io-6.45 chan-io-6.46 cmdAH-20.5 cmdAH-25.3
env-2.1 env-2.2 env-2.3 env-2.4 env-3.1 env-4.1 env-4.3
env-4.4 env-4.5 event-1.1 exec-19.1 io-29.33b io-40.3
io-52.22.1 io-6.31 io-6.43 io-6.44 io-6.45 io-6.46 lseq-4.21.4
scan-15.1 socket-14.19 socket_inet-2.11 socket_inet-5.1
socket_inet-5.3 socket_inet-7.3 unixFCmd-1.1 unixInit-1.2
zipfs-password-read-cipher-2 zipfs-password-write-cipher-w-2
zipfs-password-write-cipher-deflate-w
zipfs-password-write-cipher-deflate-w+
zipfs-password-write-cipher-deflate-a+
```

To compare the next run, extract the same way rather than by eye --
`grep -oE '^==== [^ ]+ FAILED' <log> | awk '{print $2}' | sort -u` --
and diff against the block above.

### THREE FIXED, NOTHING BROKEN, ALL THREE NAMED

`Failed 46 -> 43` with **`Total` and `Skipped` identical to the
digit**, which is what makes the arithmetic a statement about the same
68118 executions rather than about a different suite. And the three
are exactly three entries of the recorded eleven unread singletons:

```
chan-io-41.8 GONE
expr-old-37.21 GONE
unixFCmd-2.2.2 GONE
```

*Three gone and the net is three, so nothing arrived* -- which is the
only form that confirmation can take, and it is the first time this
suite's movement has been attributed by name instead of by total.
**None of the three was predicted and none was being worked on**, so
which change carried them is unidentified; guessing a vehicle would be
the third such story in this file. The cheap discriminator is the next
run, now that a baseline exists.

### THE TWO QUESTIONS THE `-J` ROUND LEFT OPEN ARE BOTH ANSWERED

- **`socket_inet-5.1`/`5.3` were NOT among the eighteen.** Both are
still failing, so *the leftover-listener false pass did not return*
-- which was the stated hazard, since those two want a port bind
refused and a stale listener had been refusing it. The prediction
was written down before the run and the answer is the good one.
- **`event.test` and `main.test` were unchanged, not new.** Read by
name they are `event-1.1` and `Tcl_Main-5.10`, exactly the two
singletons the baseline already carried.

### AND A CORRECTION THAT MATTERS MORE THAN THE THREE: THERE IS NO `socket_inet.test`

The `-J` round recorded *"`socket_inet.test` HAS LEFT THE FAILING-FILE
LIST ENTIRELY"* and offered it as the behavioural confirmation that
`-J` had not broken the socket half of its measured blast radius
(`sockaddr_in` 24 -> 16, `in_addr` 8 -> 4).

**That file does not exist and never did.** `ls` over the suite shows
one `socket.test`, and its body is a loop --
`foreach {af localhost} {...}` with `test socket_$af-1.1 ...` -- so
every `socket_inet-*` name is GENERATED inside `socket.test`, with
`$af` taking the value `inet`. A grep for `socket_inet-5.1` matches no
file in the tree at all.

So the absence of `socket_inet.test` from `Files with failing tests`
was never evidence of anything: it could not have appeared there under
any outcome. And the substance does not hold either -- **`socket_inet`
has four failures in this run, 2.11, 5.1, 5.3 and 7.3**, which is
exactly the "`socket_inet` 4" this file already listed as unread. They
did not go away and they have not moved.

*The eighteen-test improvement under `-J` stands: it rests on `Total`
and `Skipped` being identical with `Passed` +18, which is sound. What
does not stand is the attribution of it to sockets.* The socket half
of the blast radius is **unmeasured**, not confirmed -- and the
pthread half was already recorded as unmeasured, because `197 thread`
and `12 testmutex` are skipped. So the behavioural confirmation of
`-J` covers neither family it actually moved.

**The rule this breaks is one already in this file**: *a marker says
the run reached the end, not that it was the run you asked for* -- and
its sharper form, which is new. **A file name absent from a list is
not a measurement until you have checked that the name could ever have
been present.** An absence has at least two explanations -- the thing
passed, or the thing was never named that way -- and only one of them
is a result. Same family as *a check whose negative result has two
explanations*, arriving for a FILE NAME rather than a test.

### Still true, and worth keeping beside the list

- **`io-6.46` and `chan-io-6.46` now BOTH fail**, which is the twins
rule working: `io-6.46` was recorded as *flaky not fixed* precisely
because its twin still failed, with "count that group by whether the
twins agree" written down. They agree.
- **`socket_inet-2.11` FAILS rather than hanging**, so the
`_resettimer` repair is still holding -- the suite completed in four
minutes with no file aborting.
- **`chan-io-40.3`/`io-40.3` still fail with `umask()` now working**,
which is correct rather than surprising: the initial mask is
deliberately 0, the file server hands out `perm & (dirperm | ~0666)`
regardless, and the test computes 0666. *A conformance fix that was
deliberately not a default change does not move a test that measures
the default.*
- **zipfs is FIVE, where this file records three.** All five are
`zipfs-password-*` cipher tests with `errorCode TCL ZIPFS PASSWORD`
-- one family, zipfs's own, so the "13 -> 3 CONFIRMED" undercounted
a single cluster by two rather than anything regressing. *A cluster
sized from a prediction rather than counted from the names, which is
the same error as sizing `run-redir` from one section head.*
Loading
Loading