You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/fabric-sync-process-plan.md
+22-2Lines changed: 22 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -415,13 +415,15 @@ Each implementation pull request merges when its required tests and CI pass.
415
415
Silber.cos owns the step 7 activation gate and every release and deployment
416
416
gate.
417
417
418
-
Before any release, run every ignored test that needs a real machine. Record
419
-
the machine, commit, command, and result.
418
+
Before any release, run every named real-machine gate. Some gates are ignored
419
+
tests, and some are matched live measurements. Record the machine, commit,
420
+
command, and result.
420
421
421
422
| Platform | Test | Exact proof |
422
423
| --- | --- | --- |
423
424
| macOS |`a_real_launchd_supervisor_rolls_back_and_removes_its_job`| An isolated real launchd job detects a deliberately broken pair. The pair-aware reader restores both members. The plist and loaded job disappear. |
424
425
| Linux |`a_real_systemd_supervisor_rolls_back_and_removes_its_jobs`| An isolated real systemd timer starts its service over a deliberately broken pair. The pair-aware reader restores both members. Both units disappear. |
426
+
| Linux |`offline_peer_cost_matches_control`| A configured peer that never answers does not move healthy-peer latency, CPU use, or resident memory outside a matched control window. |
425
427
426
428
These tests use isolated paths and services. They do not prove the production
427
429
service names, install paths, home permissions, or service definitions.
@@ -455,6 +457,24 @@ expected exactly one `fabric` member. It changed no executable or staging file.
455
457
This clean refusal enforces the Release A order for that deployed reader. It is
456
458
not a property of the Release A pair-aware reader.
457
459
460
+
The first `offline_peer_cost_matches_control` gate passed on hetz at exact tag
461
+
`v0.2.4+9b425d6` on 2026-09-05. The treatment added one peer that never answered
462
+
and then restored the exact prior file digest. It sent 300 healthy-peer pings
463
+
over 91.663 seconds. All pings passed, and none took more than one second.
464
+
465
+
The matched resource traces each sampled the same daemon PID once per second
466
+
for 379.095 seconds. Treatment used 5.925% of one core and had a 155,824 KiB RSS
467
+
span. Control used 11.942% and had a 196,048 KiB span. Normal machine work was
468
+
larger than the effect under test. Thus, the offline peer's cost was below this
469
+
machine's noise floor. The daemon did not restart during the gate.
470
+
471
+
For each release, run the treatment and control on the same Linux machine and
472
+
deployed commit. Record CPU time, RSS minimum and maximum, and 300 healthy-peer
473
+
ping times. Sample each resource window once per second for at least six
474
+
minutes. Restore the exact prior `peers.toml` digest after treatment. The gate
475
+
fails if treatment exceeds the control by more than the control's own 60-second
476
+
variation. It also fails if a healthy ping fails or exceeds one second.
477
+
458
478
Add each future real-machine test to this named list when the test is added.
459
479
The measurement-only ignored tests are not release gates unless this list names
Copy file name to clipboardExpand all lines: docs/failure-modes.md
+24-5Lines changed: 24 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,11 +3,11 @@
3
3
fabric connects two machines that are not on the same network. Networks fail, so
4
4
this page is about what fabric does when they do.
5
5
6
-
**Every number here was measured**, on one machine running two fabric daemons
7
-
against each other, by the test named in the last column. Where there is no
8
-
test, the row says `NOT PROVEN` and stays in the table. A page that lists only
9
-
the failures we happened to test would read as a complete list of what can go
10
-
wrong, and it would not be one.
6
+
**Every number here was measured.** Most measurements use one machine running
7
+
two fabric daemons, with the test named in the last column. A fleet measurement
8
+
names its machine and window. Where there is no test, the row says `NOT PROVEN`
9
+
and stays in the table. A page that lists only the failures we happened to test
10
+
would read as a complete list of what can go wrong, and it would not be one.
11
11
12
12
## The two questions
13
13
@@ -33,6 +33,7 @@ nothing tells you to look.
33
33
|**The far machine restarts** — you restart your dev server while a browser is connected | The open connection does not survive because the process that owned it is gone. A new request during the outage fails within Fabric's three-second initial-connect bound. A client can then retry. A new request works when the peer returns. See "Whose problem is a page that stops updating" below. | During the outage 3.006 s; after restart 91.681 ms; one 9.87 s focused run on 2026-09-02 |`a_peer_restarting_mid_session_restores_service_without_intervention`|
34
34
| The direct path between the machines dies while a relay is available |`NOT PROVEN.` Two daemons on one machine cannot lose a direct path they never had, so this cannot be forced in a test here. It is not hypothetical: on the three-machine fleet today, 1,569 connections used a direct path and 1,463 used a relay, so both are in constant use. Proving the switch needs two real machines. | Unmeasured |`NOT PROVEN`|
35
35
| A machine's address changes mid-session, as a laptop moving between networks does | The session survives without restarting the process, and the machine keeps its identity. Proven for one kind of tunnel. | Not separately measured |`generic_tunnel_survives_client_endpoint_recycle_without_process_restart`. **`NOT PROVEN` for TCP tunnels specifically.**|
36
+
| A configured peer stays offline | Its failed connection attempt stays isolated. Healthy peer streams still open. Failed probes retain no connection. | Under 250 ms in the regression test. On hetz, 300 of 300 healthy pings passed over 91.663 seconds. |`offline_peer_cost_is_bounded_and_healthy_peer_stays_fast`|
36
37
37
38
## What you see while it is broken
38
39
@@ -79,6 +80,24 @@ network is back, for the same reason, while a new request is immediate.
79
80
application notices is up to the application; fabric restores the tunnel but
80
81
cannot resurrect a socket the far process no longer has.
81
82
83
+
**An offline peer still gets a health probe every 20 seconds.** This is extra
84
+
work, but its fleet cost was not detectable on 2026-09-05. A 91.663-second
85
+
treatment had six failed probes. All 300 healthy-peer pings passed, with no ping
86
+
above one second.
87
+
88
+
Two matched resource traces each used 380 one-second samples over 379.095
89
+
seconds. The offline-peer treatment used 5.925% of one core. The no-offline-peer
90
+
control used 11.942%, because unrelated work made the control busier. Treatment
91
+
RSS spanned 155,824 KiB. Control RSS spanned 196,048 KiB. Both traces crossed the
92
+
daemon's 128 MiB allocator sawtooth. These results show no attributable cost at
93
+
this fleet size. They do not show that a failed probe costs nothing.
94
+
95
+
Remove a truly retired peer from `peers.toml` on every machine. This file is a
96
+
local allow list, so removal on one machine does not remove trust elsewhere.
97
+
`fabric doctor` can report an unreachable peer, but it cannot know that the peer
98
+
was retired. The fleet has no authoritative peer set today. An operator must
99
+
compare every machine's `peers.toml` to find this drift.
100
+
82
101
## Why `send-file` is not shaped like scp
83
102
84
103
`scp` lets the sender choose where a file lands on the far machine. **fabric
0 commit comments