Skip to content
Draft
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
547 commits
Select commit Hold shift + click to select a range
b6e2cff
fix(imports): importing a file with no `ns` says so, instead of crashing
claude Aug 3, 2026
ea48a18
docs: probe the PUnify surface gaps — five of seven are stale
claude Aug 3, 2026
f197e55
docs: the 12 batch-isolation failures no longer reproduce
claude Aug 3, 2026
d12c2f7
docs: `<` check predicates work in WS files — one of two CIU T6 gaps …
claude Aug 3, 2026
1e00ac9
feat(string): Unicode normalization — String Library Phase 4b
claude Aug 3, 2026
62f7ccb
docs: fill in the normalization commit hash
claude Aug 3, 2026
8c50ea3
feat(string): common prefix/suffix — String Library Phase 4c, partially
claude Aug 3, 2026
4bc01a5
feat(string): edit distance and "did you mean?" — Phase 4c complete
claude Aug 3, 2026
e61437e
feat(string): grapheme clusters — String Library Phase 4a
claude Aug 3, 2026
25cb5ff
docs: the into-* runners exist and are importable — correcting my own…
claude Aug 3, 2026
39ae305
feat(string): regex bridge — String Library Phase 4d, partially
claude Aug 3, 2026
5cf6017
fix(parser): from-int/from-nat are unary, not binary
claude Aug 3, 2026
6f996ae
docs: three IO Library phases are done and tested; a fourth is half s…
claude Aug 3, 2026
f957e42
docs: probe Session Types, HKT and the Collections stragglers — all t…
claude Aug 3, 2026
0e39d95
docs: probe Spec System, Galois and Reduction Cache Cells — all confi…
claude Aug 3, 2026
3168e6a
docs: open the 2026-08-03 dailies for this session
claude Aug 3, 2026
226452a
parser: name the real fault when an fn bracket swallows a `let`
claude Aug 3, 2026
86daea6
docs: dailies for the LET residual close
claude Aug 3, 2026
bd1afc6
an empty group is located at its bracket, and "nowhere" is not a merg…
claude Aug 3, 2026
447d114
docs: dailies for the empty-group fix
claude Aug 3, 2026
19f7a53
a higher-order stdlib call works on a def RHS
claude Aug 3, 2026
0e1aad8
docs: dailies for the HOF def-seam fix
claude Aug 3, 2026
f75fff2
a removed ~N literal costs one command, not the file
claude Aug 3, 2026
50253c5
docs: dailies for the tilde per-command fix
claude Aug 3, 2026
7fa17a6
.pnet: register 31 nodes that were missing by SIBLING
claude Aug 3, 2026
79ff881
docs: dailies for the .pnet sibling-registration sweep
claude Aug 3, 2026
2b94721
whnf: vindex computes
claude Aug 3, 2026
8960502
docs: dailies for the vindex computation rules
claude Aug 3, 2026
829b9b9
foreign-fn: a partially-applied node's type is the REMAINDER
claude Aug 3, 2026
88733ad
docs: dailies for the foreign-fn arity fix
claude Aug 3, 2026
d5c1108
redex: the Vec/Fin QTT usage rules, and vindex reduction
claude Aug 3, 2026
951b7b3
docs: dailies for the Redex Vec/Fin usage rules
claude Aug 3, 2026
42e25f5
run the Redex model from the ordinary suite
claude Aug 3, 2026
834ae97
docs: dailies for wiring the Redex model into the suite
claude Aug 3, 2026
c0deee4
branch-result hint: derive arm binder types, and thread the expected …
claude Aug 3, 2026
44eb087
docs: dailies for the branch-result residual fix
claude Aug 3, 2026
3b4630e
diagnose the inline-validate match scrutinee, and pin the boundary
claude Aug 3, 2026
a7f2a15
docs: dailies for the inline-validate scrutinee diagnosis
claude Aug 3, 2026
8eff6e7
defn: an unbracketed body says so, instead of naming a lambda you nev…
claude Aug 3, 2026
57ce3fd
docs: dailies for the unbracketed defn body fix
claude Aug 3, 2026
aa3a7d8
census the spec-store clobber: 12 names, order-dependent, silent
claude Aug 3, 2026
7c201d9
docs: dailies for the spec-store clobber census
claude Aug 3, 2026
5c3d30b
DEFERRED: the multi-arity relation zero-arg path is not reproducible
claude Aug 3, 2026
dd303f5
verify the IO-J binder-name claim: true, but not an IO defect
claude Aug 3, 2026
8a6368a
docs: dailies for the two verification passes
claude Aug 3, 2026
d461972
DEFERRED: name what the Seq trait migration would actually cost
claude Aug 3, 2026
d2ade5c
DEFERRED: the .pnet cache is built — and serves WRONG ANSWERS on a de…
claude Aug 3, 2026
87a1c05
docs: dailies for the .pnet stale-dependency defect
claude Aug 3, 2026
72ce62c
pnet: a dependency edit invalidates the cache
claude Aug 3, 2026
14dd93b
docs: dailies for the pnet dependency-staleness fix
claude Aug 3, 2026
23bcf08
spec: :examples are actually checked
claude Aug 3, 2026
89cc64c
docs: dailies for the :examples checker
claude Aug 3, 2026
1d0dabe
spec: the grammar describes the POL syntax cluster
claude Aug 3, 2026
9cb6810
pin the 0-tuple OOB branch: it IS reachable, via an empty tuple slice
claude Aug 3, 2026
3a7e112
select: a selection-typed subject says WHY it refuses
claude Aug 3, 2026
541da2b
docs: dailies for the D4 spin-off batch
claude Aug 3, 2026
e56717e
select: `k^:x` gets the rename-target message
claude Aug 3, 2026
5b41b3a
defmacro: $set-literal and $mixfix are sentinels, not pattern variables
claude Aug 3, 2026
fb4fadf
DEFERRED: probe the three group tags — silent garbage, blocked by tod…
claude Aug 3, 2026
586f768
defmacro: invert the template pattern-variable polarity
claude Aug 3, 2026
14340ac
pp-datum renders access sentinels; form-deps filters them structurally
claude Aug 3, 2026
e0c5a63
binder walkers: a select block in a parameter position says so
claude Aug 3, 2026
3112625
groupers: share has-matching-rangle? so `<` means the same at both la…
claude Aug 3, 2026
57c0465
pin the `.( )` tree-layer divergence as a known defect
claude Aug 3, 2026
f7c96de
DEFERRED: record that the `.( )` divergence is now pinned
claude Aug 3, 2026
221d2b3
def seam: the goal-head diagnostic reaches a `def`
claude Aug 3, 2026
8060a8c
DEFERRED: narrow the row-annotation gap and cross-link its two entries
claude Aug 3, 2026
c590527
DEFERRED: measure the eq?-keyed whnf cache hit rate
claude Aug 3, 2026
e7f7d82
DEFERRED: measure zonk-at-depth's re-shift — negligible, no fix warra…
claude Aug 3, 2026
fe04f0a
occurs?: a meta inside a container is no longer invisible
claude Aug 3, 2026
cfbd95c
DEFERRED: record the occurs? soundness fix
claude Aug 3, 2026
1b959f9
conv-nf: containers see hole-as-wildcard, like everything else
claude Aug 3, 2026
4d03b63
DEFERRED: close the un-arm'd-node lesson entry — both actions already…
claude Aug 3, 2026
c9e8034
module-load errors name the file, line and variable
claude Aug 3, 2026
fd970da
let: a continuation-line value no longer swallows the body
claude Aug 3, 2026
4efbed6
tree builder: one pass and a binary search, not two quadratics
claude Aug 3, 2026
6bef504
docs: A4 re-verification, and catch the dailies up on the sweep
claude Aug 3, 2026
ddb7baa
DEFERRED: mark the tropical-addendum entry RETIRED in its header
claude Aug 3, 2026
3815bc8
ordinal/keyword domain mismatches name the mistake
claude Aug 3, 2026
6da3f05
projections off a non-row carrier, and the check door, get the hint too
claude Aug 3, 2026
083b5c1
pin the cross-module SCHEMA staleness case, and close its DEFERRED gap
claude Aug 3, 2026
f589ef4
runtime validate descends into nested schemas
claude Aug 3, 2026
881ff15
schema field types check their ELEMENTS, not just their head constructor
claude Aug 3, 2026
57140a8
PVec, Set and Map fields check their elements too
claude Aug 3, 2026
a125937
dailies: the projection diagnostics and the validate descent work
claude Aug 3, 2026
c42056d
a deep `:requires` path is enforced, top hop and all
claude Aug 3, 2026
61cfa67
a selection whose declaration failed no longer validates everything
claude Aug 3, 2026
282fc60
DEFERRED: re-probe the nested-seal traversal bound and state its cost
claude Aug 3, 2026
41d5470
dailies: the deep :requires work and the stub-selection finding
claude Aug 3, 2026
36c5552
a failing seal nested in a list or a map is caught at commit
claude Aug 3, 2026
1744976
a wildcard `:requires` path parses in a .prologos file
claude Aug 3, 2026
760e8a3
the presence marker moves to a position the lexer reserves
claude Aug 3, 2026
277fcff
W3001: two of your own imports binding the same spec name is now repo…
claude Aug 3, 2026
ec5f8a8
dailies: the charter close, W3001, and the two measurement corrections
claude Aug 3, 2026
e5e9548
a qualified call reaches its own module's spec
claude Aug 3, 2026
ad60fd7
pin the prelude's shadowing order, and correct what it means
claude Aug 3, 2026
ce063bb
census the trait registry: it is silent where impl raises
claude Aug 3, 2026
1c0676f
the derive skip set is four different problems, and `join` proves it
claude Aug 4, 2026
9de1ad7
dailies: the qualified lookup, and the join finding
claude Aug 4, 2026
9a55223
pin the higher-order narrowing gap, and correct what the suite proves
claude Aug 4, 2026
88b9634
DEFERRED: record the examples-corpus A/B for the reduce skip
claude Aug 4, 2026
003e0c4
a resolved numeric literal no longer collapses to a malformed node
claude Aug 4, 2026
2800517
W3001 stops claiming a consequence it cannot demonstrate
claude Aug 4, 2026
7762f3d
DEFERRED: the derive skip set is mechanizable, and 24 failures become 4
claude Aug 4, 2026
3dd4b23
dailies: the corrections stretch
claude Aug 4, 2026
c1e73fe
a malformed declaration no longer takes the whole file down
claude Aug 4, 2026
4e6c214
dailies: the preparse containment
claude Aug 4, 2026
704cb9d
the derive skip list goes from four hand-written names to one
claude Aug 4, 2026
492994d
dailies: the derive mechanization
claude Aug 4, 2026
10cdd65
DEFERRED: diagnose the PUnify row-type residual to its real cause
claude Aug 4, 2026
d2f75bd
DEFERRED: record the corpus A/B for the derive mechanization
claude Aug 4, 2026
8ac49c2
float sqrt/NaN/rounding land, and the FFI's float marshalling stops b…
claude Aug 4, 2026
cfcbf3c
dailies: the float residuals and the dead FFI marshalling
claude Aug 4, 2026
ed3d929
if-nan lands, and Float<->Posit was never missing
claude Aug 4, 2026
2a19da0
DEFERRED: verify the :pre/:post state and record that it is unblocked
claude Aug 4, 2026
96930f1
dailies: the Phase 4 residual close and the :pre/:post verification
claude Aug 4, 2026
cee2b43
:pre and :post contracts actually run
claude Aug 4, 2026
78db12b
dailies: the contract wrapping
claude Aug 4, 2026
ee37f9e
the Gen trait lands, and shows Spec Phase 2 is gated on N6d-i item 3
claude Aug 4, 2026
d33dc86
dailies: Gen, and the Spec Phase 2 / N6d-i item 3 connection
claude Aug 4, 2026
a342b0f
result-position trait params derive a wrapper; N6d-i item 3's diagnos…
claude Aug 4, 2026
44975c6
file: prologos::core::csv cannot be imported, and two green tests cov…
claude Aug 4, 2026
ddba19a
DEFERRED: the csv import failure, root-caused to a capability-form split
claude Aug 4, 2026
55b2ff5
dailies: item 3's wrong diagnosis, and the csv capability split
claude Aug 4, 2026
1fcd8c3
DEFERRED: csv's import failure is a load-ORDERING bug, with a one-lin…
claude Aug 4, 2026
06b280a
DEFERRED: reordering csv's own requires does not fix it either
claude Aug 4, 2026
3b2a618
DEFERRED: the csv E2001 is a deferred-constraint problem, not a scopi…
claude Aug 4, 2026
c660f74
DEFERRED: trace the csv constraint's discharge condition
claude Aug 4, 2026
8b79dbe
dailies: the csv investigation and what each wrong turn was worth
claude Aug 4, 2026
f217438
DEFERRED: withdraw the csv workaround — it was a stale cache
claude Aug 4, 2026
237ef26
a capability in a spec is a type, not an auto-generalized type variable
claude Aug 4, 2026
b7912be
DEFERRED: record the capability spec-form fix and why defect 2 is held
claude Aug 4, 2026
598abce
a multiplicity error no longer prints "Declared multiplicity: declared"
claude Aug 4, 2026
e465537
DEFERRED: csv's blocker is .pnet CONTEXT-DEPENDENCE, not QTT
claude Aug 4, 2026
dd57c7b
WS `:mixfix` metadata registers the operator; unicode symbols work
claude Aug 4, 2026
36a9dfb
DEFERRED: HKT-9 is built and tested behind a flag, not unstarted design
claude Aug 4, 2026
06369fc
file: a non-exhaustive match returns a junk value at zero errors
claude Aug 4, 2026
ba69e79
W3002: a non-exhaustive match is reported, and it found a real bug im…
claude Aug 4, 2026
a5beb0e
DEFERRED: re-probe two Mixfix entries — both accurate, one worse than…
claude Aug 4, 2026
e27d178
dailies: the triage stretch, WS mixfix, and W3002
claude Aug 4, 2026
7866f4c
DEFERRED: re-probe the explain restructure — accurate, guard verified
claude Aug 4, 2026
dee81be
DEFERRED: "Architecture A+D NOT STARTED" is stale — it is substantial…
claude Aug 4, 2026
7f9fec5
DEFERRED: two Propagator-First entries have obsolete premises
claude Aug 4, 2026
291809c
DEFERRED: Collections Phase 3g (Length-Indexed Vec) is built, not not…
claude Aug 4, 2026
8f338d0
the parameter lint rusted again, and six of the eight flags were mine
claude Aug 4, 2026
6f7fe63
wire the parameter lint into pre-commit — the guard that rusted twice
claude Aug 4, 2026
943905f
file: the cell lint has rusted too — 11 new unregistered sites since …
claude Aug 4, 2026
041d8b1
regenerate the dep table — it had rusted and was mis-selecting tests
claude Aug 4, 2026
cc6af79
DEFERRED: correct my own cell-lint filing — 11 sites reduce to 1 real…
claude Aug 4, 2026
7cdab85
fix the cell lint's two accuracy problems: 11 flagged sites become 6
claude Aug 4, 2026
9de050e
dailies: the guard sweep — parameter lint, dep table, cell lint
claude Aug 4, 2026
fa830a5
the staleness banners were themselves going stale — make them date-free
claude Aug 4, 2026
cd0517c
`do` joins the marker-seat family — no more whole-file aborts
claude Aug 4, 2026
75509ae
a `do` error names what the user wrote, not the reader's internal marker
claude Aug 4, 2026
ef459bb
DEFERRED: P3a item 15 is stale, item 17 confirmed still true
claude Aug 4, 2026
b9002e4
a dynamic key may hit any label, so every field's type widens
claude Aug 4, 2026
e1cede6
the prelude-drift warning was telling you to delete working bindings
claude Aug 4, 2026
96317c0
dailies: item 18 + the prelude-drift guard
claude Aug 4, 2026
38ab4bb
a row annotation names the `{...}` collision instead of blaming Int
claude Aug 4, 2026
1ef2d25
a module that is both a library and a test file has an unstable test …
claude Aug 4, 2026
6ea34b8
dailies: item 19 + the generators/test split
claude Aug 4, 2026
01ba6d4
fold access sentinels before head-macro dispatch, not after
claude Aug 4, 2026
8873edb
POL.9c: the "ungated" fourth direction was already gated
claude Aug 4, 2026
e81d346
item 17: record the example-corpus A/B result; dailies
claude Aug 4, 2026
a305481
Nat-in-computations: deliver the audit, and what it turned up
claude Aug 4, 2026
0ca15a3
the unannotated-param hint was advertising a remedy with a corner
claude Aug 4, 2026
ff19ecc
a defn body that is just `.field` silently dropped its spec
claude Aug 4, 2026
e551280
dailies: the spec-dropped-by-projection soundness fix
claude Aug 4, 2026
80a07d5
allocation-efficiency audit: two of its top-3 already shipped, one is…
claude Aug 4, 2026
7f266d0
cross-module go-to-definition: the blocker had already been built
claude Aug 4, 2026
a2ed2fb
srcloc precision: real, but one shape, and not for the stated reason
claude Aug 4, 2026
1810488
dailies: cross-module go-to-definition + srcloc characterisation
claude Aug 4, 2026
5c8e572
FREE_ORDERING entry: both code citations had drifted
claude Aug 4, 2026
e4b6e4b
correction: srcloc imprecision is caused by SPEC INJECTION, not layout
claude Aug 4, 2026
e166a44
dailies: the srcloc cause correction
claude Aug 4, 2026
bb4f98a
a spec'd defn now reports the token, not the whole defn
claude Aug 4, 2026
94873a5
dailies: the srcloc precision fix
claude Aug 4, 2026
0e274d6
batch cell allocation has no deployment target; compound cells supers…
claude Aug 4, 2026
913af79
the path FFI list boundary was inverted in both directions
claude Aug 4, 2026
0a068ab
the containment tripwire's "Until SUB.3" is stale — SUB.3 landed
claude Aug 4, 2026
b23b05d
a recursive process silently type-checked as terminating
claude Aug 4, 2026
6ec2031
"battle-tested" oversold the diagnosis result, not its plumbing
claude Aug 4, 2026
e2b172f
dailies: process recursion + the diagnosis qualification
claude Aug 4, 2026
6f58694
a branch documented as "never fires" now says so out loud
claude Aug 4, 2026
de33232
dailies: the never-fires assertion + session close on the DEFERRED goal
claude Aug 4, 2026
822d5e6
sorted collections: the blocker is PERSISTENCE, not "a backend"
claude Aug 4, 2026
7d1e092
build the persistent ordered-map backend the Collections entry named
claude Aug 4, 2026
ac65c3b
DEFERRED: record the ordered-map backend (missed in 7d1e0922)
claude Aug 4, 2026
934be86
session recursion: the type half is broken too, and it is ONE gap
claude Aug 4, 2026
93573a3
F-row minimal version: built, measured unsound, reverted
claude Aug 4, 2026
57b0348
F-row: scope the proper fix so its size is known before anyone starts
claude Aug 4, 2026
8b66dbe
dailies: refresh the STATE head and add the handoff
claude Aug 4, 2026
3587c4a
collect the four open owner rulings into one document
claude Aug 5, 2026
fbcc049
Merge origin/main — ARROW T1, D4.P4b/P4c, the prelude retirement
claude Aug 5, 2026
9a12cb7
fix both CI gates: restore --file-timeout, pin the OCapN suite
claude Aug 5, 2026
a155cc8
the type-naming hint is back — and it needed no ruling
claude Aug 5, 2026
67824e6
importing a book chapter now says what a chapter is
claude Aug 5, 2026
cdcc2e5
pitfall #35 is stale: `->` in identifiers is legal now
claude Aug 5, 2026
b41712b
netstring framing needed research, not a ruling — it's answered
claude Aug 5, 2026
c34eb34
DEFERRED: the first staleness sweep in four months
claude Aug 5, 2026
d1e13e0
separate the core compiler work from the OCapN port it grew out of
claude Aug 5, 2026
c785df1
a held-back residue was a duplicate — re-probed, corrected, archived
claude Aug 5, 2026
9136207
the POL cluster gets Level-3 coverage of its own
claude Aug 5, 2026
585201a
the last structural residue gets a gate, not a redesign
claude Aug 5, 2026
5a68421
the union-type hang: the carrier was not a lattice, the join was inno…
claude Aug 5, 2026
e8ecec9
the fuel bound was switched off exactly when speculation was on
claude Aug 5, 2026
259e04c
I guessed a retry loop; a ten-minute probe says it is one fire
claude Aug 5, 2026
94e6330
check the lattice contract; it finds two more on the first run
claude Aug 5, 2026
45616b4
the wakeup cells are write-only, so the merge question dissolves
claude Aug 5, 2026
5207ddc
tried the wakeup retirement; the scope was wrong and the suite said so
claude Aug 5, 2026
65e89d2
retire the write-only wakeup cells, second attempt, with the real scope
claude Aug 5, 2026
7fc8293
clean the comment drift my own retirement left, and warn at the source
claude Aug 5, 2026
368ddcd
a union value now says why you cannot look inside it
claude Aug 5, 2026
2d7e5ef
bring the docs up to date with what this branch actually is
claude Aug 10, 2026
bf756b3
the law test's own comment was the defect it exists to catch
claude Aug 10, 2026
d1af3a9
close the law table's coverage gap to 8, and name why those 8 are stuck
claude Aug 10, 2026
1299b51
four registered cell merges are not lattices, and three of them are r…
claude Aug 10, 2026
7e37ed6
the gate the last commit promised: 560 files / 10942 / 0
claude Aug 10, 2026
9563088
every registered cell merge is covered — and my coverage figure was n…
claude Aug 10, 2026
b849a00
the merge-law drift guard, third attempt — and it caught itself twice
claude Aug 10, 2026
20339e5
the re-run guard now knows what a suite run is
claude Aug 10, 2026
b88f135
the gate, and the guard verified in the direction that could have bee…
claude Aug 10, 2026
a18813c
remove two setup unknowns from the OCapN entries, and say why one is …
claude Aug 10, 2026
1ec6748
I had been repeating "OCapN 24/24" without running it
claude Aug 10, 2026
574462f
the Peano kind tags are gone, and writing the code found a silent wro…
claude Aug 10, 2026
4c327ba
narrow the multi-arity nullary bug to where I actually stopped
claude Aug 10, 2026
08e058d
root cause: the parser cannot split `| ka ka ->`, and brackets fix it
claude Aug 10, 2026
e7eb764
fix the multi-arity dispatch bug, and correct two wrong root causes I…
claude Aug 10, 2026
9e44a7a
adopt netstring framing, and the blocker I filed was a false dilemma
claude Aug 10, 2026
1ed2f42
the F-row scope holds, and now says WHY it is a track
claude Aug 10, 2026
89b1d3c
"session recursion is unusable" was my overstatement, not the entry's
claude Aug 10, 2026
b35ed8c
dailies: the compiler bug, the netstring adoption, and the scoreboard
claude Aug 10, 2026
2413462
session nodes were unregistered for .pnet — the stdlib broke on a war…
claude Aug 10, 2026
390c7a4
dailies: the warm-cache stdlib bug, and what its greenness was worth
claude Aug 10, 2026
c2e6251
merge origin/main — and three conflicts were two fixes for one problem
claude Aug 10, 2026
a32ed6f
the merge gate was red: a third pin fired on the round-trip fix
claude Aug 10, 2026
82480f0
merge gate green: 564 files / 11161 / 0
claude Aug 10, 2026
81c0cbf
gaps §0.2: the crossed-hellos tie-break moves into Prologos
claude Aug 11, 2026
5088b83
gaps §0.2: op:abort has one encoder again
claude Aug 11, 2026
1c73865
gaps §0.2: pin the two side-id implementations to each other
claude Aug 11, 2026
e9ff2d4
gaps §0: re-verify all three structural gaps against code
claude Aug 11, 2026
a8fef72
dailies: §0 structural gaps re-verified; crossed hellos migration
claude Aug 11, 2026
62bef1a
correct a false claim about state in Prologos
claude Aug 11, 2026
9d236ce
correct two more claims: gift monotonicity, and the table count
claude Aug 11, 2026
93cfc61
dailies: carry the monotonicity + table-count corrections
claude Aug 11, 2026
93cf9b0
SH step 1: byte-oriented frame IO on the TCP handle table
claude Aug 11, 2026
3b40762
SH step 2: a linear World token puts effect ordering in the dataflow
claude Aug 11, 2026
8e66c8d
SH step 3: an event loop written in Prologos, and the reason it hung
claude Aug 11, 2026
c488574
SH step 4: many connections, one Prologos loop, one state value
claude Aug 11, 2026
d8c6eb5
dailies: the event loop moves into Prologos (SH 1-4)
claude Aug 11, 2026
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
32 changes: 32 additions & 0 deletions .claude/rules/prologos-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,38 @@
```
Body at the **same** indent as `|` is a layout violation (currently produces a hard parser error; tracked in issue #27 for diagnostic improvement). Body indent must be **strictly greater than** the `|` column.

- **Never write three-deep nested `match` as a single function body.** Three-deep nested `match` inside a single function body fails to elaborate at *import time* with "Unbound variable" errors in Prologos's current elaborator. The fix is mechanical: factor into a chain of single-match helpers. Each helper does one `match`, returns to the caller, the caller does the next `match`. Same semantics for the user, no elaborator failure. OCapN Phases 15 and 21 both shipped this workaround; codified after the second occurrence. Until the underlying elaborator bug is fixed, this is the safe pattern.
```
;; WRONG — fails at import time
defn pipeline-deliver [target args v]
match [lookup-actor target v]
| some _ -> send-only target args v
| none ->
match [lookup-promise target v]
| none -> v
| some pst ->
match pst
| pst-unresolved msgs -> ...
| _ -> v

;; RIGHT — helper chain
spec deliver-to-promise Nat SyrupValue PromiseState Vat -> Vat
defn deliver-to-promise [pid args pst v]
match pst | pst-unresolved msgs -> ... | _ -> v

spec deliver-to-promise-or-drop Nat SyrupValue Vat -> Vat
defn deliver-to-promise-or-drop [target args v]
match [lookup-promise target v]
| none -> v
| some pst -> deliver-to-promise target args pst v

spec pipeline-deliver Nat SyrupValue Vat -> Vat
defn pipeline-deliver [target args v]
match [lookup-actor target v]
| some _ -> send-only target args v
| none -> deliver-to-promise-or-drop target args v
```

## Application style

- **Uncurried** -- `defn foo [x y z] body`, `spec f A B -> C`. Multiple arguments in one bracket group.
Expand Down
3 changes: 2 additions & 1 deletion .claude/rules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
- **Full suite**: add `--all` flag. Also: `--jobs N`, `--timeout N`, `--no-record`, `--no-skip`
- **Targeted tests (CRITICAL — use this, not bare `raco test`, after any production edit)**: `racket tools/run-affected-tests.rkt --tests tests/test-X.rkt --tests tests/test-Y.rkt` runs specific files with SCOPED PRECOMPILE (driver.rkt + the listed tests, ~0.5s incremental). This keeps test `.zo` linklets fresh after export changes in production modules, which `raco test FILE` alone does NOT do. Repeat `--tests FILE` per file (conventional command-line multi-arg pattern). **When to use targeted mode**: any time you've edited production code AND want to run specific tests — e.g., iterating on a failing test during development, verifying a fix hits the right paths, confirming a subset of tests before running the full suite. Avoids the class of "passes individually, fails in batch" / "reference to a variable that is not exported" (linklet mismatch) errors. Observed failure pattern: `raco make typing-propagators.rkt` + `raco test tests/test-X.rkt` → test's cached `.zo` holds a stale linklet snapshot of typing-propagators's exports; when exports changed, linklet-mismatch or silent wrong-results. The targeted runner's scoped precompile closes this gap. Origin: PPN 4C Phase 3c retrospective (2026-04-20) — the earlier sessions' runs didn't hit it because changes were internal (no export-surface changes); Phase 3c added multiple new provides and surfaced the gap.
- **Reporting**: `racket tools/benchmark-tests.rkt --report` / `--trend FILE` / `--compare REF` / `--slowest N`
- **Skip list**: `tests/.skip-tests` -- 2 pathological perf tests skipped by default (use `--no-skip` to include)
- **Skip list**: `tests/.skip-tests` -- pathological perf tests + batch-worker-incompatible tests skipped by default (use `--no-skip` to include). When a test is genuinely incompatible with the batch worker (e.g., spawns subprocesses with `(exit 0)` skip-guards that kill the worker, exceeds the 120s per-file timeout for legitimate reasons), partition rather than patch the worker. The OCapN track skipped 9 tests (`test-ocapn-vat.rkt`, `test-ocapn-acceptance-l3.rkt`, plus 7 Node-spawning interop tests) and ran them via `raco test` directly in a separate CI workflow (`.github/workflows/interop.yml`). Patching the batch worker to handle subprocess-spawning would have been 1+ days of compiler infrastructure work; the partition was 30 minutes. Rule: **when test infrastructure mismatches a test's needs, partition rather than patch**; document in `.skip-tests` with the reason and the alternate runner.
- **Microbench from Phase 1 in protocol stacks** -- protocol stacks (codecs, wire serializers, parsers over byte streams) have asymmetric latency hidden in tight inner loops. A microbench at the encode/decode boundary catches it during Phase 1 instead of Phase 9. OCapN's decoder shipped slow through Phases 1–8 because every test was a single small case; Phase 9's pipelined RPC was the first thing fast enough to expose the regression, and Phase 13 needed a tail-recursive accumulator + inline destructure for a 25× speedup. **Operational rule**: when implementing a codec/serializer/parser, every Phase 1 should include `tools/bench-ab.rkt` runs of encode + decode at varying message counts (1, 10, 100). Catching the perf bug at Phase 1 saves the multi-phase regression chain.
- **Guideline**: Keep test files under ~20 test-cases / ~30s wall time for good thread-pool parallelism
- **Delimiter check after .rkt edits**: Run `tools/check-parens.sh <file>` after EVERY edit to a `.rkt` file, BEFORE `raco make`. Instant (~100ms, read-only). Catches mismatched `()`, `[]`, `{}` with exact line:column. Eliminates trial-and-error bracket-balancing during compilation.
- **Pre-compilation**: Both runners call `raco make driver.rkt` AND all test files before tests (skip with `--no-precompile`). The suite runner's `precompile-modules!` compiles BOTH — test files are NOT in driver.rkt's dependency graph, so `raco make driver.rkt` alone does NOT recompile them.
Expand Down
4 changes: 4 additions & 0 deletions .claude/rules/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@
- **All tests green before moving on** -- never proceed to the next phase with failing tests. A failing test is a signal, not noise. Investigate immediately. If a failure is genuinely pre-existing and unrelated, document it explicitly with a tracking reference before proceeding.
- **Update Master Roadmap on design docs and PIRs** -- writing a track design document or a PIR is a signal to update `docs/tracking/MASTER_ROADMAP.org`. Link the new design doc and/or PIR in the relevant track's row. Update track status (⬜ → 🔄 → ✅). If the design reveals new tracks or cross-dependencies, add them. The Master Roadmap is the single source of truth for all work — if it's not linked there, it's invisible.
- **Review PIR methodology before writing a PIR** -- before writing any Post-Implementation Review, read `docs/tracking/principles/POST_IMPLEMENTATION_REVIEW.org` to refresh on the 16 questions, the template structure (§1–§9+), format principles, and anti-patterns. The Track 4 PIR was initially written as a sparse 7-section summary; reviewing the methodology revealed it was missing Bugs Found and Fixed, What Went Well/Wrong/Lucky/Surprised, Architecture Assessment, What's Next, Key Files, and cross-references to prior PIRs. A PIR written without consulting the methodology will systematically omit the evaluative and meta-learning sections that make PIRs genuinely valuable. §16 must include a longitudinal survey of the **10 most recent PIRs** (not just 2-3) — the value of longitudinal analysis is in spotting slow-moving trends.
- **Read your own pitfalls log before each phase** -- when a track has produced a pitfalls/issues log (e.g., `2026-04-27_GOBLIN_PITFALLS.md`), grep it for syntactic constructs the next phase will use BEFORE writing code. The log is index, not just record. OCapN Phase 21 retried multi-arity defn with `nil` ctor pattern despite pitfall #18 being on file from Phase 0 — wasted ~10 minutes. Same applies to language-bug logs across tracks: scan for relevant entries during phase BARs.
- **Codify a 2-occurrence pattern within a track immediately** -- the existing rule "patterns spanning 3+ PIRs are codification-ready" is for cross-track patterns. For *intra-track* recurrence, **2 occurrences is enough** to codify. OCapN's nested-match-import-error fix shipped at Phase 15 without being added to syntax.md or the pitfalls log; Phase 21 rediscovered the same bug and re-derived the same helper-chain workaround. When a workaround is needed twice in the same track, add it to the pitfalls log AND to the relevant rule file (e.g., `prologos-syntax.md`) immediately, not after the third occurrence.
- **Pitfalls-log second-pass scrutiny before merge** -- when a track produces a pitfalls/issues log, schedule a "second-pass scrutiny" phase before merge. Re-test each entry against the current toolchain; delete entries that are false (out-of-scope, env-specific, first-pass diagnoses that were wrong). OCapN's pitfalls log started at 30 entries and shrank to 17 after re-testing (commits `447379a`, `b9c33ba` deleted 12 false claims). A 30-entry catalogue with 12 false entries is misleading; an 18-entry catalogue with all real entries is actionable. Tracks ending without this scrutiny pass leave noise in the project's permanent record.
- **External cross-impl gates are mandatory test infrastructure for protocol ports** -- when a track ports a protocol against an external counterparty (e.g., `@endo/ocapn`, an XMPP server, a Matrix server), a foreign-generated golden + drift gate is mandatory Phase 1 work, not optional. Pattern: write a generator script that runs inside the foreign implementation, commit its output as a fixture, add a CI step `git diff --exit-code` on the fixture. Hand-written wire vectors are a last-resort substitute. OCapN's drift gate caught 4 of 5 interop bugs that hand-written tests would have missed. The D:I ratio target (1.5:1 longitudinal) is **conditional on external validation existence** — with an external counterparty + drift gate, low D:I is fine; without one, low D:I is technical debt.
87 changes: 87 additions & 0 deletions .github/workflows/interop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Interop (cross-runtime Syrup byte-equality)

# Runs the Phase-4 cross-impl test:
# - regenerates the Syrup fixture from `@endo/ocapn` (the JS reference)
# - asserts the regenerated bytes match the committed fixture (drift gate)
# - runs the Racket cross-impl test that pins Prologos's encoder against
# the JS bytes
#
# This catches:
# - drift in Prologos's wire codec (existing fixture catches it)
# - drift in @endo/ocapn's wire format (regenerate-then-diff catches it)
#
# Design doc: docs/tracking/2026-04-29_OCAPN_INTEROP_DESIGN.md

on:
push:
branches: [main]
pull_request:

jobs:
syrup-byte-equality:
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- uses: actions/checkout@v4

- name: Install Racket
uses: Bogdanp/setup-racket@v1.11
with:
version: '9.0'

- name: Install Node 22
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install JS interop deps (@endo/ocapn + @endo/init)
run: |
cd tools/interop
npm install --no-audit --no-fund

- name: Regenerate Syrup fixture from @endo/ocapn
run: |
node tools/interop/gen-syrup-vectors.mjs > /tmp/regen.txt

- name: Drift gate — committed fixture must match @endo/ocapn output
run: |
if ! diff -u racket/prologos/tests/fixtures/syrup-cross-impl.txt /tmp/regen.txt; then
echo ""
echo "FIXTURE DRIFT — @endo/ocapn output no longer matches the"
echo "committed fixture. Either:"
echo " - the JS reference impl changed its wire format (genuine"
echo " upstream change — investigate before regenerating)"
echo " - or someone bumped @endo/ocapn locally and forgot to"
echo " refresh the fixture: re-run"
echo " \`node tools/interop/gen-syrup-vectors.mjs > racket/prologos/tests/fixtures/syrup-cross-impl.txt\`"
echo " and commit the result."
exit 1
fi

- name: Install Prologos deps
run: cd racket/prologos && raco pkg install --auto --skip-installed

- name: Pre-compile modules
run: cd racket/prologos && raco make driver.rkt

- name: Run cross-impl test (Phase 4 — static byte-equality)
run: cd racket/prologos && raco test tests/test-ocapn-syrup-cross-impl.rkt

- name: Run live-interop test (Phase 5 — real TCP exchange Racket↔Node)
run: cd racket/prologos && raco test tests/test-ocapn-live-interop.rkt

- name: Run handshake test (Phase 6 — bidirectional op:start-session)
run: cd racket/prologos && raco test tests/test-ocapn-handshake.rkt

- name: Run conversation test (Phase 7 — 3-frame multi-op exchange)
run: cd racket/prologos && raco test tests/test-ocapn-conversation.rkt

- name: Run RPC test (Phase 8 — conversational state machine)
run: cd racket/prologos && raco test tests/test-ocapn-rpc.rkt

- name: Run pipelined test (Phase 9 — multi-turn RPC)
run: cd racket/prologos && raco test tests/test-ocapn-pipelined.rkt

- name: Run abort test (Phase 10 — graceful op:abort teardown)
run: cd racket/prologos && raco test tests/test-ocapn-abort.rkt
8 changes: 7 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@ jobs:
- name: Pre-compile modules
run: cd racket/prologos && raco make driver.rkt

- name: Run full test suite
- name: Run full test suite (skipped: heavy OCapN tests + interop)
run: cd racket/prologos && racket tools/run-affected-tests.rkt --all --no-record

# Heavy OCapN tests skipped by run-affected-tests because they
# exceed the batch-worker's 120s per-file timeout. `raco test`
# has no such limit. Total wall ~5 min, well under our 30 min budget.
- name: Run heavy OCapN tests directly
run: cd racket/prologos && raco test tests/test-ocapn-vat.rkt tests/test-ocapn-acceptance-l3.rkt
Loading
Loading