Measured first: SheetRun now types into FILIUS' DHCP dialog and keeps rows
in its port forwarding dialog. Java's DHCP server keeps its bounds as typed
(".0.0.1" too), never takes an empty gateway or DNS server, hands out the
device's gateway and DNS server unless its own (a home router always its
LAN address, where "manual settings" do nothing), drops a second static
assignment of a MAC address silently and lets "_" through its MAC pattern;
the port forwarding dialog keeps any row, its firmware forwards only the
valid ones. Here a value passes its rule or is not taken, with a word why.
- doc: DHCP server addresses and flags, static assignments (a MAC address
once, ignoring case), port forwarding rows (TCP or UDP, musterPort, the
LAN address); the sheet shows what the server hands out and which rows
Java's firmware forwards (the core's parsePortForwardingRow, exported)
- editor: Java's dialogs as pages of the sheet with a back button, the
three row tables on one RowsEditor (the forwarding table rebuilt on it);
a sheet per device, so an open page closes when another device is chosen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
packages/editor (React 18, Vite) draws a document as Java FILIUS does: Java's
default hardware icons, the device button of JSidebarButton, cables as
JCablePanel's quadratic curve between the buttons' middles, wireless cables
dashed, documentation items below. The surface moves with mouse and finger
(the pointer captured only once it moved) and zooms with Ctrl and the
wheel, a trackpad pinch, two fingers and the zoom bar; the first view shows
all. German and English catalogs with Java's device names, the dashboard's
colour tokens, the bridge with its origin check. packages/doc gets the
drawing's light view of a document.
Java's Switch.cloud (the Internet in the examples) was lost on reading; it
is now read, kept in the model and written, with FlsOracle and the corpus,
written and exported checks renewed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A web page by its DNS name (internetwork_komplett), an e-mail between two
networks through NAT and MX relay (Internet_Komplett_..._DE), a file found
and fetched with Gnutella across a router (zwei_rechnernetze_komplett):
ExampleRun records frames, tables, program lines and end states; the core
plays the same calls and matches card by card. Equal RIP ties take Java's
choice, RIP beacons are left out, the search's two connections compared
flow by flow. Also: a core test that an equal RIP route from another router
neither replaces nor refreshes the route, and nine stale type errors in
core tests fixed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GnutellaRun adds a line of four peers: a search goes on as a query, each
peer answers with a hit for each matching file and the hits come back the
way the query came; a hit's file is fetched by HTTP on port 6346. The
file type names of the model move from the project export and import into
the core, so that the download uses them too.
Departures from Java: a peer that sent hits keeps its connection, so that
the hits of farther peers come back too (Java closes it and loses them),
and sizes are in characters.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GnutellaRun lets Java's PeerToPeerAnwendung join peers on terminal-net.
The core's gnutella.ts does the same: a ping in Java's text format to
port 6346, a pong back, the ping sent on to the other peers and their
pongs back the way it came, at most the program's number of peers.
Departure from Java: a ping that comes a second time gets no pong and
its connection stays (Java's worker throws on the missing pong).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FileCases does what the windows of FILIUS' file explorer and text editor
do to a host's files: new folder, delete, copy, cut and paste, rename,
import, save and save as. The core's filePrograms.ts does the same on the
node's file system; the file system renames an entry in its place, as
Java's tree does.
Departures from Java: a folder name that comes to no name makes nothing,
a paste onto a name there already is refused, a rename to a name with a
slash or blanks at its ends is refused and one of the case only is done,
save as and import onto a folder's name are refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The account file's writer moves from the export (packages/fls) into the
core, so that the export and the running server write the same. The
server writes the file at its start and whenever its accounts change.
EmailRun now records Java's file as it left it and as Java writes the
accounts it ended with; Java leaves the notice to a local sender out until
its next write.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TerminalRun adds nine stories: traceroute in the LAN, through the router,
unreachable, without a route, to no one, to the host itself, errors and
Ctrl+C; tcpdump on two hosts. traceroute counts failures across hops as
Java does and takes an error that carries its probe; tcpdump tells each
frame's highest capture row with its time of day, at once.
Departures from Java: traceroute tells its summary before the end mark
(Java after it, where its window shows no text) and calls a host at the
20th hop reached. arpsend is not built.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TerminalRun types lines into Java's command line on terminal-net at set
times; the engine types the same lines. New in the engine: an ICMP echo
in a program's thread (the first ICMP message after the send, whatever
it is), Java's route choice, the ARP table with Java's broadcast row, DNS
in a program's thread, ICMP broadcasts of a node's own network, and an
ARP wait that ends after what else happens at that millisecond.
Departures from Java: an echo is answered from the address asked
(RFC 792), network unreachable carries the packet with its sender, ping
names the host and takes only -b before it, arp and netstat list in the
order learned, netstat lists a UDP server's listening socket only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The terminal splits a line as Java's window does and runs ls, cd, pwd,
mkdir, touch, cp, mv, rm, cat, test, help, ipconfig and route on the
node's files, which are the project's own. Its texts are generated from
the bundle Java loads. TerminalCases feeds Java's Terminal without a
network (16 cases, de and en); eight cases name Java bugs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The program sends to its account's SMTP server, one connection for each
recipient, and fetches its mails by POP3; the server now sends mails on
to other domains by MX and returns notices to their senders. The
program's folders are in the snapshot and go back into the project.
EmailClientRun plays six stories with two servers; the mail oracles run
in the language's locale, so Java's notice dates match the core's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SMTP on port 25 stores mails for the domain's accounts as Java reads
them anew and tells a local sender of unknown recipients; POP3 on port
110 hands them out. The mailboxes are in the snapshot and go back into
the project. EmailRun plays four stories over the network; MailCases
feeds Java's workers without one (26 cases, de and en). 18 cases name
Java bugs that the core does not take.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page konfig changes the firewall at run time (into the snapshot, back
into the project through projectWithSimulationChanges). KonfigCases feeds
Java's plug-in directly (25 cases, de and en); RouterWebRun plays two
stories over the network. Ten Java bugs named, not adopted. The web server
answers a method not written GET or POST with 501, as Java does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Routers and home routers start a web server on port 80 with Java's index,
log and routes pages in the project's language (routerPages.ts); the
firewall keeps a log per node that outlives a new start; RIP routes carry
the telling router's public address. TCP counts sequence numbers and
segments in Java's characters, not bytes. RouterWebRun records six stories,
with firewalls now built by ScenarioNetwork. Not taken from Java: its router
server sometimes never listening (a race in setAktiv), and </titel>.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The servers share ServerAnwendung's frame (server.ts); the web server serves
/webserver with virtual hosts, the browser loads a page and its images over
one connection to port 80 (web.ts); HTTP in Java's text form (http.ts).
WebRun records eleven stories on the new web-lan network, with the server's
files; webJava.test.ts plays them card by card. A program's close is a
request, as Java's schliessen. Not taken from Java: /../ serving any file of
the host; an unreadable request closing the connection without a word.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Programs run as generators that yield what they wait for (threads.ts); the
engine resumes them after every event. TCP connect, send, receive, accept
and name resolution exist as such steps; the blocking calls wrap them.
EchoRun records eight stories in Java FILIUS, frames, tables and each
program's window lines; echoJava.test.ts plays them card by card. Not
taken from Java: a connection without a route hangs for ever; a server
switched off leaves its connections' last FIN unanswered.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ExampleRun opens an example as FILIUS opens it (SzenarioVerwaltung.laden
into the window's lists), starts it as the action mode does, plays a
story and writes every card's frames and tables, the calls, the
addresses and the RIP tables' changes. examplesJava.test.ts reads the
same file with this package's reader and runs it in the core
(projectSnapshot, new): routing (internetwork_komplett), DHCP
(einfaches_rechnernetz_komplett), DNS (dns_server), NAT
(nat_with_mapped_port) and firewall (Internet_Komplett_..._DE) match
card by card.
Found and fixed: a host's ipForwardingEnabled, which Java saves and
obeys, was unknown to the reader, the model, the core, the writer, the
export and FlsOracle; and Java's ARP learns only from a request for its
own address or a reply. Named Java bugs: a ping without a gateway throws
a NullPointerException; a home router drops the answer of a second
remote end. Open: Java picks between equally long RIP routes by thread
timing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
captureRows.ts builds Java's rows per frame (Lauscher.datenVorbereiten):
Ethernet; ARP, ICMP or IP; TCP or UDP; the data with Java's protocol
recognition; with addresses and ports or ports only. The comment stays
structured; captureCommentText says it with given words and numbers.
ScenarioNetwork writes Java's finished tables per card (Lauscher.getDaten,
German locale); all runtime runs are recorded again, NatRun has ttlOut.
expectSameCaptures compares both views for every frame. Fixed where the
engine differed: an ARP request's target MAC is the broadcast address,
an ICMP error's identifier and sequence number are 0 (RFC 792), and host
unreachable from a router carries the packet as forwarded. Not taken:
Java's lower-case broadcast address in a reply to 0.0.0.0, and the typo
'Exeeded'. RIP keeps its recordings: Java's staggered router start now
gives a different startup on this machine.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Java's RIPTable.check marks an expired route only at the router's next
beacon, up to some 35 s late. The engine schedules each router's first
expiry, marks the route with 16 hops at that time and sends its table
at once, as after any change (better than Java where Java only samples,
decided 01.10.2026). ripJava's expire story is compared up to the
expiry and then checks that R2 marks the route at its time and R1 a
cable later.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Java's GatewayFirmware.checkNAT and SwitchFirmware.checkSAT look every
second from the start, so an entry goes up to a second late. The engine
expires both exactly at their age: better than Java where Java only
samples, as long as saved files stay compatible (decided 01.10.2026).
The switch did so already; its departure is now named in the code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The engine keeps Java's packet capture (capture.ts): per network card
every frame it sent (when it leaves on the cable) or received (also one
for another card), once, with time and number; switches log nothing;
frames the packet loss dropped are kept apart; the capture outlives a
stop and a new start, as in Java, until clearCapture. Per port instead
of per MAC, at most 10,000 frames a card.
expectSameCaptures compares each card's capture with Java's list of that
card in the ARP, WLAN, DNS, TCP, NAT, RIP and single-client DHCP runs.
It found that ScenarioNetwork ignored a switch's learning time (Java ran
300 s, the core the scenarios' 5 s); the oracle sets it now, and the TCP
and DHCP runs are recorded again. A core test found that a new start
numbers frames from 1 again and the capture took them as seen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WlanRun pings on the new network wlan-lan: over wireless cables, over a
plain cable, and to and from a notebook on the switch's SSID without a
cable. The engine matches Java without a change: it runs the links only.
Swift's wirelessAssociations, which join a host to its SSID's switch at
run time, are not taken. ScenarioNetwork sets wireless cables, wireless
cards and SSIDs; a corpus test pings over the wireless cables of
multicast_server.fls.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The core translates before the IP thread, as Java's NAT threads sit
between card and Ethernet: out, the WAN address and the entry's port (ICMP
keeps its identifier); in, by remote end, port and protocol, else by the
port forwarding, which then makes a dynamic entry; a ping at the WAN
address is answered by the router, packets from outside for the LAN are
dropped, both sides pass the router's firewall, TTL 1 going out gets time
exceeded. Dynamic entries expire at Java's check each second, 300 s times
the delay factor old (55 minutes at 90 %), refreshed only by what comes in.
The home router forwards as a router does.
Measured and not taken: when a LAN endpoint sends to a second remote end,
Java gives it the entry's WAN port but no entry, and the answer stays at
the router; the core adds an entry for each new remote end on that port.
The oracle now records every card of a node (the second card of routers
was missing); the ARP and RIP runs are recorded anew and still match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ScenarioNetwork builds home routers (their first card the WAN port) and
their port forwarding (portForwarding, through GatewayFirmware.setStaticNAT).
NatRun plays six stories on nat-home's network and writes the frames, the
calls and the router's NAT table: a ping, a UDP exchange, the same socket
to a second server (whose answer never reaches the LAN: Java keeps one
entry per LAN endpoint, for the first remote only), a TCP connection out,
a forwarded one in, and pings at the WAN address and past it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RipRun runs rip-chain's three routers in Java FILIUS, each router's random
set by reflection to the core's ripSeed, and writes the frames, every
change of each RIP table and the calls. converge: the tables fill, a ping
at 45 s. expire: R3 falls silent at 10 s; R2 marks its network 16 hops only
at its own next beacon, R1 passes it on at once, the ping gets ICMP 3/0.
Both match: per sending card the same messages at the same times, every
table through the same states. The first 5 s are compared by the state the
tables reach, since Java's routers start one after the other.
Measured on the JDK: Java's pause divides nextFloat() by 3 in float; the
core does too now (a millisecond off in one draw of about 10,000 before).
Scenarios name their RIP routers in the new field rip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Where the Swift template departs from Java's filius.software.rip, Java's
code rules: a learned route gets 16 hops at the router's next beacon after
it expired (RIPTable.check), not when it expires; messages count from any
source port; each router draws its pauses from a random of its own (Java:
an unseeded Random per router), which the core seeds from the scenario and
the router's id (ripSeed), so that the Java oracle can give it the same.
A route of hop count 0 to each own network, the first beacon after a
second, then every 25.2 to 35.2 s; a message per interface without the
routes through it; a new route or a longer one from the same router sends
at once; forwarding by the table alone, fewest hops before longest mask.
Messages are read with Java's parser (javaIpCheck, javaParseInt, moved from
fls to core for it).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The resolver runs on the events now (a query, its dnsQueryTimeout, its
answer at the socket); the blocking resolveDns waits for it, and a
recursive server uses it: its own records, else the zone's name server
from its records, else its own DNS server, else a referral
(DNSServer.answerWithRemoteData).
DnsRun plays five stories on the new dns-recursive network. Measured and
not taken: a server that is its zone's name server asks itself, which asks
itself again, without end (the client times out, then every level floods
its own DNS server); Java guards only the step through its own DNS server.
The core asks itself in neither step. That story is compared up to the
client's query (JAVA_UNTIL).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every packet that comes in goes through its node's IP thread (UDP, TCP) or
ICMP thread (ICMP), as Java's IPThread and ICMPThread: deliver, answer an
echo request or forward, one after the other; while one waits for ARP, the
next wait behind it. A packet a node sends to itself is delivered at once,
as Java's IP.senden does. The transport send threads and these are one
mechanism now (handToProtocolThread).
ArpRun has three stories through the router (routedUdpBehind,
routedPingBesideUdp, routedPingBehindPing); the oracle writes ICMP frames
with type, code, addresses and sequence number. All seven ArpRun stories
match Java FILIUS.
Measured and not taken: Java's ARP wakes one waiter with notify, not the
one whose answer came; the core wakes all that wait for the address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TcpRun loses exactly one frame (loseFirst: the card's output buffer drops
it; the sender's packet log still shows it, as with setDrop) in three new
stories: lostSynAck, lostFin, lostLastFin.
Measured: Java never repeats a SYN+ACK or a FIN. The server gives a
handshake up after one timeout (3 RTT) and closes with a FIN from SYN_RCVD
(its boundary check sometimes lets it wait twice; it means once). After its
FIN a socket waits at most five times, each wait ended by a segment or the
timeout; then it is gone. The core does the same (TCP_CLOSING_WAITS, with
TIME_WAIT in the loop) and shows CLOSED where Java leaves the state
standing (a named Java bug).
One departure: a repeated SYN in SYN_RCVD gets the SYN+ACK once more and
the wait starts anew; Java closes there, but its client never repeats the
SYN. lostSynAck is compared up to the second SYN (JAVA_UNTIL); the rest is
an engine test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A send hands its frame to the card and returns, as in Java; the frames
travel while the clock advances. Swift's send ran the network until every
frame had arrived; the option swiftSends keeps that for the Swift
comparison. Waiting calls (TCP connect, acknowledgement) now run event by
event until the answer instead of to the timeout.
UDP and TCP send through a thread per node and protocol (Java's
TransportProtokoll): one segment after the other; while IP waits for ARP,
the next send blocks and a segment from an event queues behind it. Senders
that wait take their turns in the order they came (a fair lock; Java's
leaves the order to chance).
All four ArpRun stories now match Java FILIUS, including when each call
returns. Tests let frames arrive explicitly with letFramesArrive.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An ARP lookup asks, waits a round trip, asks once more and gives up after
another round trip; then host unreachable, observed at the sender itself or
sent back by the router (for ICMP only for an echo request). A waiting
sender wakes after what else happens at that time. A ping then waits a
round trip for its answer, counted from when it left. Swift asks twice at
once while events run and lets the packet wait without end when the
address exists anywhere in the network; the option swiftArp keeps that for
the Swift comparison, and three scenarios are compared with Swift until the
trace where ARP fails or a ping goes unanswered.
arpJava.test.ts compares ArpRun: both pings match; the two UDP stories wait
for Java's transport thread (next step). DNS without a server now matches
Java too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sends to addresses no card has on the new arp-routed network (ping on the
LAN and behind a router, two UDP datagrams, one behind a failing one):
frames and calls. ScenarioNetwork builds routers and their interfaces.
Measured: ARP asks twice, a round trip each, then host unreachable; the
thread that waits is the ping's caller, the router's IP thread, or the
node's transport thread per protocol, which blocks the next send.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DNS follows Java's DNSServer and Resolver, not Swift's typed format:
Java's text messages (dns.ts), a server on port 53 answering from its
records (no question in the answer, RCODE 0, a referral with NS and A in
the answer section), an iterative resolver that waits five round trips per
query and remembers only the servers it was referred to. Recursion throws
NotPortedError until the next step. The snapshot carries the DNS servers
switched on. receiveUdp returns as soon as a datagram is there, as Java's
empfangen does.
dnsJava.test.ts compares DnsRun's five lookups; four match frame by frame,
the missing server waits for Java's ARP (named as not yet like Java).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A resolver's lookup on the new dns-lan network (A, MX, a referral by NS,
an unknown name, a missing server): every frame and the call's result.
ScenarioNetwork installs a scenario's DNS servers. The Swift comparison
reads only scenarios with a Swift result.
Measured: Java's text messages (ID=... QR=... header, question and record
lines), no question in the answer, RCODE 0 always, a referral in the answer
section, an iterative resolver waiting 5 RTT per query.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Java's SimplexVerbindung sleeps a cable's delay with the port's buffer
locked: frames on one cable leave one after the other, and a frame shows
in the packet log when it leaves. The engine now queues a frame in the
output buffer until the one before has arrived (ethernetLinkDeparture).
Swift sends a cable's frames at once; the option swiftCables keeps that for
the Swift comparison, which goes on checking everything else trace by
trace.
With the queue, the Java comparisons match within 120 ms (was 200); a
state of the TCP stories within 250 ms, where the engine's calls block
one after the other.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TCP follows Java's TCPSocket where it differs from Swift: each attempt and
TIME_WAIT wait three round trips that follow the speed (8250 ms at 90 %),
counted from when the segment is handed down, before ARP; the next segment
ends TIME_WAIT; the other end closes by itself on FIN; data no one
acknowledges closes with FIN; the accepted socket has the listener's
initial sequence number, and the listener takes the next.
Not taken from Java: three SYNs, not one (Java's retry loop ends after
the first timeout), named in tcpJava.test.ts as JAVA_BUGS.
tcpJava.test.ts compares TcpRun's three stories frame by frame and state
by state; the Swift comparison only checks that the TCP scenarios differ.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three stories of socket calls on tcp-lan's network (exchange, closedPort,
lostData): every frame with TCP flags and numbers, when each call started,
returned or failed, and each socket's states. Network building and the
packet log move from DhcpRun to ScenarioNetwork.
Measured: 3 RTT per attempt (8250 ms at 90 %), an orderly close after a
failed send, TIME_WAIT of 3 RTT, the passive side closing by itself on FIN,
one SYN only (Java's retry loop ends after the first timeout).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The client follows Java's DHCPClient instead of Swift: one DISCOVER or
REQUEST per attempt, an answer that does not fit is read and dropped, the
ARP check waits a round trip (an answer for the address ends it at once,
then DECLINE), a timeout repeats the state's message, and the fifth turns
to a link-local address 169.254.1.x/16 (ARP probe, ARP reply to all); no
old address is given back. DHCP round trip times follow the speed as in
Java (50 cables, 2750 ms at 90 %; Swift: fixed 2500 ms).
Not taken from Java: the client gives up after five occupied link-local
addresses (Java searches on without end), and an ARP packet for another
address does not end the check.
dhcpJava.test.ts compares the four DHCP scenarios with DhcpRun's Java
runs; the Swift comparison only checks that they differ.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Builds a core scenario's network in Java FILIUS, starts it as the action
mode does and writes every frame each card saw (the Lauscher) and the
addresses at the end. References for the four DHCP scenarios: one
DISCOVER/REQUEST per attempt, an ARP check that waits one RTT, DECLINE on a
conflict, link-local 169.254.1.x after the fifth failure.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
engine.ts ports Swift's "DHCP server and automatic client": an active
server listens on port 67 from the start and offers a static assignment
before its range, round from the address after the last one offered;
offers last 10 s, dynamic leases a day, and a server whose offer another
server beat blacklists that address for a while. A client starts as an
event: DISCOVER, OFFER, a check by ARP, DECLINE, REQUEST, ACK or NAK,
2.5 s per wait, and after ten failures its old address back. The snapshot
carries the DHCP settings of clients and servers.
Four scenarios match the Swift engine. One Swift error is named in the
oracle test: a client run directly is advanced a second time, to FINISH,
by the server's answer within its own DISCOVER, and the outer run then
writes back its stale copy of the status (Swift's value types); the
address and every trace agree, only the reported status is wrong in
Swift. Swift's three DHCP engine tests are ported, with tests for
stopping and the message format. 15 mutation probes, 14 caught; the other
concerns the home router, which runs only once NAT is ported.
Two departures from Java remain, to be fixed next: from the event queue
the client's ARP check does not wait, so an address conflict is never
found, and each answer that wakes the client makes it send its state's
message again (a second DISCOVER and REQUEST, the second answered with
NAK). Java waits a round trip and sends once per attempt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
engine.ts ports Swift's "Java-compatible TCP sockets" in one piece, since
half a state machine could not be checked: server and client sockets (a
free port from Java's random numbers on their own seed), the three-way
handshake with its result (connected, invalid socket, unreachable, timed
out), segments of 1460 bytes, messages up to the push, a timeout of
3 × 2.5 s with at most three attempts, closing through every Java state
including TIME_WAIT (2.5 s), sequence numbers modulo 2^32.
Three scenarios match the Swift engine trace for trace: a LAN with data
over three segments, closing from both ends, a closed port and an
unreachable host; two networks through a router with a firewall rule,
data lost until the connection closes, and an accepted socket that does
not hold the port of its closed listener; CLOSING, reached by a lost FIN.
The engine delivers a FIN within the same close, so both ends close at
once only with packet loss; an empty message does not arrive in Swift (it
does not advance the sequence number), nor here.
Swift's four TCP engine tests are ported, with tests for stopping, a
foreign SYN+ACK at a listener and the flag names. 17 mutation probes, 16
caught; the other (delivered, not waited, not connected gives unreachable)
cannot be reached through Swift's engine, which never sends a reset and
always acknowledges correctly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
engine.ts ports the UDP part of Swift's "UDP sockets and Router RIP": a
socket bound to a given port or to a free one drawn from 49152–65534 with
Java's random numbers on Swift's seed; sending, also as a limited broadcast
on every interface (or the bound one) with TTL 1; delivery into the queue
of every socket on the destination port, which then answers to the last
sender; receiving, with a timeout that advances the virtual clock; closing.
Stopping forgets sockets and queues. RIP stays not ported; Swift's DHCP
handling of a datagram has nothing to do until DHCP is in the snapshot.
The oracle gets the steps bindUdp, sendUdp, receiveUdp and closeSocket on
both sides and reports the sockets. Two new scenarios — a LAN, and two
networks through a router with a UDP firewall rule and a broadcast that
does not cross it — match the Swift engine trace for trace, the random
ports included. Swift's four UDP engine tests are ported, with a test for
stopping. 11 mutation probes were all caught (one only after the stop test
was added).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
exportProject.ts, step X4a: each installed program of a PC or notebook as
the FILIUS application of its class, keyed by that class name as Java keys
them, with its settings: servers switched on as the model has them, a web
server's port and virtual hosts, the DNS server's recursion on port 53, the
echo server's port, the generic client's target (none as null, as its
constructor leaves it), the peer count, the personal firewall. E-mail
contents are the next step.
The model lost a web server's virtual hosts switch (useVHost, on for 3 web
servers in the corpus); Swift sets it off on import. The core now has
WebServerConfiguration.virtualHosts (Swift's name), the import carries
Java's value, and the Swift comparison names Swift's error.
Checked by Java: every corpus file, imported, exported and written, loads
with the programs of the original, with no new departure. In the synthetic
model the PC has every program with settings away from the defaults, the
notebook programs without settings (Java's defaults, 3 peers), where Java
makes /peer2peer itself. 12 mutation probes, each loaded by Java, were all
caught.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The e-mail client and server of every host come into the model (core:
EmailClientConfiguration, EmailServerConfiguration, EmailMessage), from
Java's view:
- the server's accounts are those of /mailserver/konten.txt, as Java reads
them at every simulation start; without the file those of the bean list,
which Java would drop;
- the client's account is that of /konten.txt; without it the first of an
older file's kontoListe, which FILIUS 2.14 no longer reads;
- messages are numbered per program in folder order, as Swift does; the
sent folder's are sent; a date is taken only when the file gives one.
Departures from Swift: accounts and messages stay where Swift drops what
fails its checks; first and last name stay apart; a port that is no number
is the default, with a warning. On the corpus the model matches Swift's on
all 13 files; the one Swift error is named (it numbers a mailbox's messages
as their received time and writes that into the konten.txt it rewrites).
The Swift dump now carries the e-mail state, and the file system
comparison leaves out only Swift's hidden state files (and the directories
it makes for them) instead of all of /mail, /mailserver and /peer2peer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Java's DNS server reads its records from the text file /dns/hosts on every
query. dnsHosts.ts ports that reading (DNSServer.leseRecordListe,
ResourceRecord, Dateisystem.holeDatei) and keeps in the model the records
Java answers: type exactly A, MX or NS, and a name Java accepted. The file
stays in the file system as it is.
Both oracles read 76 hand-picked hosts files (dns-hosts.cases.txt): the
Java oracle through DNSServer.holeResourceRecords (DnsHostsCases), the
Swift oracle through TopologyDNSHostsFileCodec (--dns-hosts). The Java view
matches Java on every case; the model matches Swift except for 33 named
cases in twelve reasons: Java splits at single spaces and LF only, has no
comments or "IN", turns a TTL that is no int into 3600, keeps duplicates,
and empties names with a leading digit. The Swift dump now carries each
server's records; the corpus comparison covers them on 16 files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
importProject carries a host's installed programs into the model with
the settings Swift keeps (web server port, Gnutella peer limit, DNS
recursion and forwarder, personal firewall) and two it does not (the echo
server's port, the generic client's target), plus Java's "switched on".
The Swift oracle writes programs and settings; they match on the 13 files
Swift reads completely.
Intended differences, named in the test:
- every FILIUS program is kept; Swift drops command prompt, text
editor, file explorer, image viewer, echo server and generic client;
- a web server's files stay in /webserver, its document root; Swift
moves them to /www. No program state goes into a host's files.
- multicast_server.fls: maxTeilnehmerZahl refers to a shared Integer
(a button's icon text gap, 4); Swift falls back to 3.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
importProject turns a PC's or notebook's Java file tree into Swift's
virtual file system, as Swift's registerVirtualFileSystem does: images
by type or extension from Base64, text by type, unknown types as binary
data or text, unsafe names and collisions left out with a warning, and
the whole import rejected over the project quota. NSString.pathExtension
is measured in the oracle, which now writes every imported file system.
On the 13 files Swift reads completely every file matches, images
compared by hash. Intended: a host whose file has no file system stays
empty, as in Java, where Swift adds the demo files of a new device.
Pending the applications step, the comparison reads our /webserver as
Swift's /www and leaves out the e-mail and Gnutella state files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The core gains Swift's virtual file system (paths, case-insensitive
lookup that keeps the spelling, quotas, atomic changes, the defaults of
a new device) and the string behaviour the ported code relies on without
saying so. Both are measured in the Swift oracle: 11 file system cases
(the three Swift tests among them) step by step, and trimming, lower
case, equality, ordering and Base64 case by case — whitespace and control
characters over all of Unicode.
Found by measuring:
- Swift trims NEL and ZERO WIDTH SPACE, not the BOM; JS trim() does the
opposite. The .fls import now trims with swiftTrim.
- lowercased() maps scalar by scalar: a word-final sigma stays σ.
- Foundation decodes "====" and "Y===" as empty data.
- Foundation on Linux counts 24,735 plane-14 scalars as control
characters, a table artefact; the port keeps Unicode Cc+Cf.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
importProject carries the DHCP client switch and server settings (hosts
and home routers), a home router's port forwarding rows and a modem's
pairing into the model; the core gains the types, ported from Swift.
The Swift oracle writes them too, and they match on the 13 files Swift
reads completely. Configuration text is now trimmed throughout, as Swift
trims every value it reads (routes and firewall rules included).
Outside those files Swift switches every DHCP server of the Internet
examples off: their "aktiv" refers to a shared Boolean it cannot follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
importProject carries the system software settings into the model the
core runs: switch SSID and learning time (an SSID Java would roll comes
from the node id, as in Swift), a host's wireless network, manual routes,
RIP and the firewall of every router and home router. The Swift oracle
writes these settings too; they match on the 13 files Swift reads
completely.
A router's default gateway — its first interface's, which Java routes to
(Weiterleitungstabelle.holeTabelle) — is imported into the router's
device configuration. Swift's model drops it; in internetwork_komplett
the way back from 141.99.5.10 depends on it. A test pings across three
routers in the core, with and without it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>