max / goingson
3 files changed,
+66 insertions,
-42 deletions
| @@ -1387,7 +1387,7 @@ | |||
| 1387 | 1387 | "libc", | |
| 1388 | 1388 | "option-ext", | |
| 1389 | 1389 | "redox_users", | |
| 1390 | - | "windows-sys 0.59.0", | |
| 1390 | + | "windows-sys 0.61.2", | |
| 1391 | 1391 | ] | |
| 1392 | 1392 | ||
| 1393 | 1393 | [[package]] | |
| @@ -1628,7 +1628,7 @@ | |||
| 1628 | 1628 | checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" | |
| 1629 | 1629 | dependencies = [ | |
| 1630 | 1630 | "libc", | |
| 1631 | - | "windows-sys 0.59.0", | |
| 1631 | + | "windows-sys 0.61.2", | |
| 1632 | 1632 | ] | |
| 1633 | 1633 | ||
| 1634 | 1634 | [[package]] | |
| @@ -3639,7 +3639,7 @@ | |||
| 3639 | 3639 | "png 0.18.1", | |
| 3640 | 3640 | "serde", | |
| 3641 | 3641 | "thiserror 2.0.20", | |
| 3642 | - | "windows-sys 0.60.2", | |
| 3642 | + | "windows-sys 0.61.2", | |
| 3643 | 3643 | ] | |
| 3644 | 3644 | ||
| 3645 | 3645 | [[package]] | |
| @@ -3772,7 +3772,7 @@ | |||
| 3772 | 3772 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 3773 | 3773 | checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" | |
| 3774 | 3774 | dependencies = [ | |
| 3775 | - | "windows-sys 0.59.0", | |
| 3775 | + | "windows-sys 0.61.2", | |
| 3776 | 3776 | ] | |
| 3777 | 3777 | ||
| 3778 | 3778 | [[package]] | |
| @@ -5195,7 +5195,7 @@ | |||
| 5195 | 5195 | "errno", | |
| 5196 | 5196 | "libc", | |
| 5197 | 5197 | "linux-raw-sys", | |
| 5198 | - | "windows-sys 0.59.0", | |
| 5198 | + | "windows-sys 0.61.2", | |
| 5199 | 5199 | ] | |
| 5200 | 5200 | ||
| 5201 | 5201 | [[package]] | |
| @@ -5252,7 +5252,7 @@ | |||
| 5252 | 5252 | "security-framework", | |
| 5253 | 5253 | "security-framework-sys", | |
| 5254 | 5254 | "webpki-root-certs", | |
| 5255 | - | "windows-sys 0.59.0", | |
| 5255 | + | "windows-sys 0.61.2", | |
| 5256 | 5256 | ] | |
| 5257 | 5257 | ||
| 5258 | 5258 | [[package]] | |
| @@ -5792,7 +5792,7 @@ | |||
| 5792 | 5792 | checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" | |
| 5793 | 5793 | dependencies = [ | |
| 5794 | 5794 | "libc", | |
| 5795 | - | "windows-sys 0.60.2", | |
| 5795 | + | "windows-sys 0.61.2", | |
| 5796 | 5796 | ] | |
| 5797 | 5797 | ||
| 5798 | 5798 | [[package]] | |
| @@ -5991,7 +5991,7 @@ | |||
| 5991 | 5991 | ||
| 5992 | 5992 | [[package]] | |
| 5993 | 5993 | name = "synckit-client" | |
| 5994 | - | version = "0.9.0" | |
| 5994 | + | version = "0.9.1" | |
| 5995 | 5995 | dependencies = [ | |
| 5996 | 5996 | "apple-native-keyring-store", | |
| 5997 | 5997 | "argon2", | |
| @@ -6564,10 +6564,10 @@ | |||
| 6564 | 6564 | checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" | |
| 6565 | 6565 | dependencies = [ | |
| 6566 | 6566 | "fastrand", | |
| 6567 | - | "getrandom 0.3.4", | |
| 6567 | + | "getrandom 0.4.3", | |
| 6568 | 6568 | "once_cell", | |
| 6569 | 6569 | "rustix", | |
| 6570 | - | "windows-sys 0.59.0", | |
| 6570 | + | "windows-sys 0.61.2", | |
| 6571 | 6571 | ] | |
| 6572 | 6572 | ||
| 6573 | 6573 | [[package]] | |
| @@ -6589,7 +6589,7 @@ | |||
| 6589 | 6589 | "parking_lot", | |
| 6590 | 6590 | "rustix", | |
| 6591 | 6591 | "signal-hook", | |
| 6592 | - | "windows-sys 0.60.2", | |
| 6592 | + | "windows-sys 0.61.2", | |
| 6593 | 6593 | ] | |
| 6594 | 6594 | ||
| 6595 | 6595 | [[package]] | |
| @@ -7071,7 +7071,7 @@ | |||
| 7071 | 7071 | "png 0.18.1", | |
| 7072 | 7072 | "serde", | |
| 7073 | 7073 | "thiserror 2.0.20", | |
| 7074 | - | "windows-sys 0.60.2", | |
| 7074 | + | "windows-sys 0.61.2", | |
| 7075 | 7075 | ] | |
| 7076 | 7076 | ||
| 7077 | 7077 | [[package]] | |
| @@ -7106,7 +7106,7 @@ | |||
| 7106 | 7106 | dependencies = [ | |
| 7107 | 7107 | "memoffset", | |
| 7108 | 7108 | "tempfile", | |
| 7109 | - | "windows-sys 0.60.2", | |
| 7109 | + | "windows-sys 0.61.2", | |
| 7110 | 7110 | ] | |
| 7111 | 7111 | ||
| 7112 | 7112 | [[package]] | |
| @@ -7636,7 +7636,7 @@ | |||
| 7636 | 7636 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 7637 | 7637 | checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" | |
| 7638 | 7638 | dependencies = [ | |
| 7639 | - | "windows-sys 0.59.0", | |
| 7639 | + | "windows-sys 0.61.2", | |
| 7640 | 7640 | ] | |
| 7641 | 7641 | ||
| 7642 | 7642 | [[package]] | |
| @@ -8493,10 +8493,6 @@ | |||
| 8493 | 8493 | "winnow 1.0.4", | |
| 8494 | 8494 | ] | |
| 8495 | 8495 | ||
| 8496 | - | [[patch.unused]] | |
| 8497 | - | name = "ops-status" | |
| 8498 | - | version = "0.1.0" | |
| 8499 | - | ||
| 8500 | 8496 | [[patch.unused]] | |
| 8501 | 8497 | name = "quasi-axum" | |
| 8502 | 8498 | version = "0.56.0" | |
| @@ -8512,3 +8508,7 @@ | |||
| 8512 | 8508 | [[patch.unused]] | |
| 8513 | 8509 | name = "quasi-store" | |
| 8514 | 8510 | version = "0.1.0" | |
| 8511 | + | ||
| 8512 | + | [[patch.unused]] | |
| 8513 | + | name = "ops-status" | |
| 8514 | + | version = "0.1.0" |
| @@ -285,8 +285,8 @@ | |||
| 285 | 285 | let conn = conn(app)?; | |
| 286 | 286 | let waiting = directory::pending_confirmations(&conn) | |
| 287 | 287 | .map_err(|error| RouteError::internal(error.to_string()))?; | |
| 288 | - | let refreshed = | |
| 289 | - | directory::refreshed_at(&conn).map_err(|error| RouteError::internal(error.to_string()))?; | |
| 288 | + | let refreshed = directory::pending_confirmations_refreshed_at(&conn) | |
| 289 | + | .map_err(|error| RouteError::internal(error.to_string()))?; | |
| 290 | 290 | drop(conn); | |
| 291 | 291 | ||
| 292 | 292 | if waiting.is_empty() { | |
| @@ -339,21 +339,17 @@ | |||
| 339 | 339 | Node::list(rows), | |
| 340 | 340 | ]; | |
| 341 | 341 | ||
| 342 | - | // Stated, and stated as the number it actually is. `directory::refreshed_at` | |
| 343 | - | // is `MIN(refreshed_at)` over `sync_groups`, so it is the group list's | |
| 344 | - | // freshness; `sync_invitations` carries its own `refreshed_at` and synckit | |
| 345 | - | // exposes no reader for it (filed on synckit-client). The two move together | |
| 346 | - | // on a good cycle, because invitations are fetched on the same pass, and | |
| 347 | - | // they come apart on a bad one: `write_invitations` is scoped per group | |
| 348 | - | // precisely so one group's failed fetch does not blank the others. | |
| 349 | - | // | |
| 350 | - | // So the wording says which list the timestamp belongs to rather than | |
| 351 | - | // implying it covers this one. A section whose whole job is a security | |
| 352 | - | // decision should not overstate how current it is. | |
| 342 | + | // The age of this list, not of a neighbouring one. | |
| 343 | + | // `pending_confirmations_refreshed_at` is the freshness of exactly the rows | |
| 344 | + | // `pending_confirmations` returned, and it reports the stalest group it drew | |
| 345 | + | // from: `write_invitations` is scoped per group so one group's failed fetch | |
| 346 | + | // does not blank the others, which is also the cycle where a number about | |
| 347 | + | // the group list would overstate this one. A section whose whole job is a | |
| 348 | + | // security decision should not do that. | |
| 353 | 349 | if let Some(at) = refreshed { | |
| 354 | 350 | nodes.push(Node::text(format!( | |
| 355 | - | "The group directory was last refreshed {at}. Invitations arrive on the same \ | |
| 356 | - | cycle, so somebody who accepted since then is not here yet." | |
| 351 | + | "This list was last refreshed {at}. Somebody who accepted since then is not \ | |
| 352 | + | here yet." | |
| 357 | 353 | ))); | |
| 358 | 354 | } | |
| 359 | 355 |
| @@ -1082,12 +1082,11 @@ | |||
| 1082 | 1082 | ); | |
| 1083 | 1083 | } | |
| 1084 | 1084 | ||
| 1085 | - | /// The only staleness reader synckit exposes is `MIN(refreshed_at)` over | |
| 1086 | - | /// `sync_groups`, so the section can state the group list's freshness and not | |
| 1087 | - | /// the invitation list's. It says which one it is rather than implying the | |
| 1088 | - | /// stronger claim. Filed on synckit-client as `0e8af5b2`. | |
| 1085 | + | /// The section dates the list it is drawing. `pending_confirmations_refreshed_at` | |
| 1086 | + | /// is the freshness of exactly the rows above it, so the sentence is about them | |
| 1087 | + | /// and not about the group list, which refreshes on a different schedule. | |
| 1089 | 1088 | #[tokio::test] | |
| 1090 | - | async fn the_confirmations_section_says_which_list_its_timestamp_is_about() { | |
| 1089 | + | async fn the_confirmations_section_dates_the_list_it_is_drawing() { | |
| 1091 | 1090 | let state = state().await; | |
| 1092 | 1091 | known_group(&state, 1, "The Firm", true); | |
| 1093 | 1092 | known_invitation( | |
| @@ -1101,12 +1100,41 @@ | |||
| 1101 | 1100 | ); | |
| 1102 | 1101 | ||
| 1103 | 1102 | let pane = sharing(&state); | |
| 1103 | + | assert!(pane.contains("This list was last refreshed"), "{pane}"); | |
| 1104 | 1104 | assert!( | |
| 1105 | - | pane.contains("The group directory was last refreshed"), | |
| 1106 | - | "{pane}" | |
| 1105 | + | !pane.contains("The group directory was last refreshed"), | |
| 1106 | + | "the group list is a different list on a different schedule: {pane}" | |
| 1107 | 1107 | ); | |
| 1108 | + | } | |
| 1109 | + | ||
| 1110 | + | /// The case the per-list reader exists for: the group list refreshed on a cycle | |
| 1111 | + | /// where this group's invitation fetch failed. The section must report the older | |
| 1112 | + | /// number, because that is how old what it is drawing actually is. | |
| 1113 | + | #[tokio::test] | |
| 1114 | + | async fn the_confirmations_timestamp_is_the_invitation_lists_not_the_groups() { | |
| 1115 | + | let state = state().await; | |
| 1116 | + | known_group(&state, 1, "The Firm", true); | |
| 1117 | + | known_invitation( | |
| 1118 | + | &state, | |
| 1119 | + | 1, | |
| 1120 | + | 11, | |
| 1121 | + | synckit_client::InvitationState::Accepted, | |
| 1122 | + | Some("aa:bb:cc:dd"), | |
| 1123 | + | None, | |
| 1124 | + | &far_future(), | |
| 1125 | + | ); | |
| 1126 | + | { | |
| 1127 | + | let conn = state.db.conn().unwrap(); | |
| 1128 | + | conn.execute( | |
| 1129 | + | "UPDATE sync_invitations SET refreshed_at = '2026-01-01T00:00:00.000Z'", | |
| 1130 | + | [], | |
| 1131 | + | ) | |
| 1132 | + | .unwrap(); | |
| 1133 | + | } | |
| 1134 | + | ||
| 1135 | + | let pane = sharing(&state); | |
| 1108 | 1136 | assert!( | |
| 1109 | - | !pane.contains("Invitations last updated"), | |
| 1110 | - | "no claim about a number nothing reads: {pane}" | |
| 1137 | + | pane.contains("This list was last refreshed 2026-01-01T00:00:00.000Z"), | |
| 1138 | + | "{pane}" | |
| 1111 | 1139 | ); | |
| 1112 | 1140 | } |