Prosecutors’ Vivid Accusations Against Maduro Belie a Complex Case

© Sara Hylton for The New York Times

© Sara Hylton for The New York Times
Liverpool forward will face his former teammate Sadio Mané in Afcon semi against Senegal after arguably the Pharaohs’ best performance since 2008
It is a long time since Egypt had a night this good. There have been two World Cup qualifications since their golden age of three successive Cups of Nations came to an end in 2010, and they’ve got to the finals of two Cups of Nations since, but this had a different feel to the knockout phases in 2017 or 2021 (played in 2022). This wasn’t grinding through, doing just enough (across the knockouts in 2017 and 2021, Egypt won one game without needing extra time or penalties; a grim 1-0 against Morocco in the 2017 quarter-final). It was taking on one of the giants of African football and beating them well. A 3-2 victory over Côte d’Ivoire was probably Egypt’s best single performance since they beat the same opposition 4-1 in the semi-finals of Ghana 2008.
That game in Kumasi was always going to cast its shadow over this quarter-final. Saturday’s coaches were on opposite sides when Egypt beat Côte d’Ivoire on penalties in the 2006 final in Cairo – Hossam Hassan as a 39-year-old squad captain and unused sub and Émerse Faé in the centre of midfield – but it was the semi-final two years later this game most resembled. The 4-1 hurt Côte d’Ivoire far more than the final had, the image of a bewildered Kolo Touré running away from Amr Zaki as he scored Egypt’s third a symbol of the Pharaohs’ superiority that night. Within four minutes on Saturday, Odilon Kossounou had got in a similar mess, legs tangled as Omar Marmoush sped by him to put Egypt ahead.
Continue reading...
© Photograph: Siphiwe Sibeko/Reuters

© Photograph: Siphiwe Sibeko/Reuters

© Photograph: Siphiwe Sibeko/Reuters
Why is the film of Ireland’s 2002 World Cup falling-out not a documentary but a drama that takes liberties with events?
All history is to some extent narrative. You cannot tell a story without in some way editing it, reducing it, compressing it. Which means that anybody telling a story about a historical event, particularly one from the relatively recent past, risks outraging those who have studied it or who remember it. Often those complaints are pedantic, trivial, but sometimes they are not. It’s one thing to elide two minor characters or to tweak the timeline to simplify a story, quite another to imply misleading motivations.
Saipan, Glenn Leyburn’s and Lisa Barros D’Sa’s film about the cataclysmic row between Roy Keane and Mick McCarthy shortly before the 2002 World Cup, came out in Ireland on Boxing Day and will be released in the UK on 23 January. It is obsessed by detail: the tracksuits, the sweatshirts, the kits are all right. It’s startling when the film cuts between reproductions of interviews and press conferences and actual footage to realise just how accurately these scenes have been recreated. Which raises two questions. What is the point? And how can such care have been taken over the look of the film when there are such grotesque inventions and inaccuracies in the plotting and motivation?
Continue reading...
© Photograph: Aidan Monaghan/PA

© Photograph: Aidan Monaghan/PA

© Photograph: Aidan Monaghan/PA

© Adriana Loureiro Fernandez for The New York Times

© PA Wire

© PA Wire

© Karsten Moran for The New York Times
Cette dépêche raconte un vieux bug que j’ai eu sur un satellite. L’identification, la reproduction, la correction. C’est le bug qui m’a le plus intéressé/marqué dans ma carrière (jusqu’ici), C’est pourquoi cela pourrait aussi vous intéresser.
Il y a bien longtemps, dans une galaxie lointaine. Ah non, pardon. Un long weekend de 14 juillet, sur une plage, je reçois un coup de fil : « Un des satellites a rebooté, à cause d’une erreur logicielle, est-ce que tu es disponible pour venir comprendre ce qu’il s’est passé ? A priori, il fonctionne toujours, mais il est passé tout seul sur le calculateur redondant. »
Quelques mois avant, on avait lancé une première grappe de six satellites ; d’autres lancements sont prévus pour compléter une constellation dans les mois/années à venir. Comme tout marche bien depuis des mois, personne de l’équipe logiciel de bord n’est d’astreinte. Sur ces satellites, j’étais surtout sur la partie validation. En gros, ce jour-là pour moi, ce n’était pas possible, mais j’y suis allé le lendemain, un samedi ou dimanche.
Si nos managers nous ont appelé, c’est parce quand un satellite bugue en prod (on va dire en vol, plutôt), c’est comme pour n’importe quel autre logiciel, des gens veulent des réponses à des questions comme :
Par contre, les moyens sont potentiellement différents de ce que vous avez dans d’autres environnements (ou pas, j’imagine que ça dépend des gens) Ce qu’on a :
Premier élément, qui a mené au fait que c’est nous (du logiciel) qui avons été appelés, c’est que le matériel qui gère le mode (2 -> 3) peut changer de mode pour plusieurs raisons, mais il sait pourquoi il le fait. Et la raison c’est « le logiciel m’a dit de le faire ». Donc ça vient de nous.
Comme tout va bien, on va regarder le contexte sauvegardé. Ce n’est pas un core dump qu’on peut passer à gdb, mais ça contient quelques infos :
ILLEGAL CPU INSTRUCTION
Program Counter %pc qui nous donne l’adresse de l’instruction exécutée au moment de l’erreur%npc (ici c’est l’adresse juste après %pc, rien de surprenant)Problème résolu donc ? on est à l’adresse %pc, on l’exécute et le CPU nous dit que l’instruction n’est pas légale. Qu’est-ce qu’il y a ici ? Une instruction légale, quelle que soit la valeur des registres. Pareil pour un peu plus haut et un peu plus bas, rien qui provoque cette erreur. Que s’est-il passé ?
On est dans l’espace, donc l’explication facile (dès qu’on n’explique pas un truc) : l’instruction a dû avoir un Single Event Upset (SEU), un bit flip. Ça a transformé une instruction légale en instruction illégale. C’est simple ? Sauf que non, on est dans l’espace, en conséquence, on a tout un mécanisme de protection contre les SEU. C’est pas infaillible (par exemple si on a deux bits inversés, on ne peut pas corriger) mais ce n’est pas la bonne signature. Si c’était ça, ça dirait DOUBLE EDAC ERROR, pas ILLEGAL CPU INSTRUCTION.
Donc la cause de l’anomalie n’est pas un SEU.
Je suis sûr que vous êtes intéressé, donc je vais vous décrire la protection contre les bit flips. C’est un mix de matériel/logiciel (en plus d’avoir une boite autour qui diminue la probabilité). En mémoire (RAM, ROM) pour 4 octets de données “utiles”, on consomme 5 octets. Le 5ᵉ octet contient un code de contrôle calculé à partir des 4 autres (EDAC). Si un bit change (sur les 5 × 8 = 40 bits), on peut non seulement le détecter mais aussi reconstruire la valeur correcte. Si deux bits changent (ou plus, mais il y a une limite), on peut détecter l’erreur mais pas la corriger (cf: le DOUBLE EDAC ERROR mentionné plus haut)
C’est complètement transparent vu du logiciel (code source, ou assembleur), tout ça est calculé par le matériel. Quand on écrit en mémoire 0x12345678 il calcule le code et écrit 0x12345678XY avec la bonne valeur de X et Y. Quand on lit, pareil, le matériel commence par lire 0x12345678XY, calcule la somme de contrôle sur les 4 octets, si c’est le bon, il nous donne 0x12345678.
Là où ça se complique, c’est quand il y a un changement. Disons qu’on a maintenant 0x02345678XY. (1 --> 0). Il se passe deux choses ici :
0x12345678 (il corrige, mais uniquement la valeur envoyée au software. Pas la valeur enregistrée en mémoire)SINGLE EDAC ERROR.C’est là que le logiciel intervient, dans le point 2. Ce signal est lié à une trap qui corrige la mémoire. Schématiquement c’est lié à une fonction qui ressemble à ceci (en assembleur SPARC en vrai, mais j’ai tout oublié)
; adresse vient du contexte, c’est l’adresse qui a été lue en dernier, qui a généré la trap
disable_edac_trap: ; Désactiver la trap. Sinon on déclencherait la trap depuis la trap
load [adresse], reg ; Lire 4 octets (lecture = correction auto)
enable_edac_trap: ;
store reg, [adresse] ; Réécrire la valeur corrigée
On lit la valeur, c’est corrigé vu du logiciel par le matériel, on réécrit la valeur, tout est corrigé.
Cette trappe peut être déclenchée par n’importe quelle instruction qui lit de la mémoire (ou par le fait de charger une instruction elle-même depuis la mémoire), et on a même une tâche de fond (plus basse priorité, qui tourne en permanence quand il reste du temps de calcul disponible) qui fait
// en gros. En vrai légèrement plus compliqué
void background_task(void) {
int address = MEMORY_START;
volatile int value;
while (1) {
value = *address; // s’il y a un bit flip en mémoire, ce sera corrigé par la trap
address += 4;
if (address >= MEMORY_END) {
address = MEMORY_START;
}
}
}
L’idée de cette fonction c’est de lire la mémoire régulièrement. Si on ne faisait pas ça, peut-être que certaines cases mémoires auraient deux bit flips, car pas corrigé après le premier si on ne lit pas la mémoire avant qu’un autre arrive. Ce n’est pas très fréquent d’avoir des bit flips, mais sur les 6 satellites, en cumulé, on en détecte quelques-uns par jour.
De retour à la case départ donc. On exécute apparemment l’instruction stockée dans %pc, valide. Et le CPU nous dit qu’elle est invalide, mais clairement, elle est valide. On tourne en rond, on est samedi ou dimanche, fin d’après midi, et le satellite, lui aussi il tourne en rond, sans problèmes. Tout à coup, quelqu’un a l’idée de dire « bon, on ne résoudra pas ça aujourd’hui. On se revoit lundi ? ». On rentre, je bois un verre avec mes colocs (enfin, je suppose. C’était une activité habituelle pour un weekend, ça, au moins)
Retour au bureau, et là (surement plus tard, pas lundi 9h) on a David (un collègue) qui propose : "Comme clairement %pc est valide, est qu’on exécute quelque chose d’invalide, est-ce qu’on est sûr qu’on a bien enregistré %pc?". On vérifie, le code qui fait ça a l’air correct. En plus le contexte général, ce qu’il y a dans les registres est correct. Toujours David "OK, le logiciel est correct, mais est-ce qu’on est sûr que %pc c’est bien toujours l’instruction qu’on exécute ?".
Donc, on vérifie, par acquit de conscience et on remarque que non, pas nécessairement. Si on est dans une trap, le %pc qu’on enregistre pointe vers l’instruction qui a provoqué la trap, pas l’instruction de la trap qu’on exécute. Bon, OK, ça ne nous avance pas nécessairement (mais si j’en parle…)
Nouvelle question donc : Si on est à %pc, quelles sont les traps qui peuvent s’exécuter ? Il y a plein de possibilités, la plupart viennent de causes extérieures (timer matériel, plein d’autres évènements extérieurs) et potentiellement aussi la trap de l’EDAC si on lit une valeur (et l’instruction à %pc lit une valeur).
Donc techniquement, on pourrait aussi être n’importe où dans le code (assembleur) de toutes les traps. Avant on cherchait pourquoi c’était illégal d’exécuter %pc, maintenant on cherche pourquoi ça serait illégal d’exécuter %pc ou n’importe quelle ligne d’une trap active/activable à ce moment-là.
Sauf que le code des traps, c’est pas nous qui l’avons écrit. C’est bien du code qui vient de l’entreprise, mais il existe depuis plusieurs années, est utilisé sur le même processeur depuis plusieurs années, et il a plusieurs dizaines d’années de vol (cumulé, en additionnant les satellites) sans problème.
En suivant les principes bien connus du développement logiciel, si on utilise un logiciel sur étagère, pas besoin de le valider (surtout ça coute de l’argent. Cela dit même si on avait essayé, je ne pense pas qu’on aurait trouvé de problème), vu qu’il marche. Par acquit de conscience, on demande, et on nous répond "bah chez nous ça marche" (la légende veut qu’une histoire similaire soit à l’origine de Docker, je ne sais pas si c’est vrai, mais le fameux "it works on my desktop, ship my desktop"…)
Vous avez peut-être lu le titre de l’article, donc vous imaginez où je vais. On se demande « OK, pourquoi ça marche pour eux, et pas pour nous ? » Quelles sont les différences ?
Ok, on a changé de compilateur, les traps sont en assembleur, mais le reste du code est dans un langage bien plus courant (non, je rigole, en vrai c’est en Ada…), peut-être que l’interaction entre les traps et le reste du code a changé ?
Pourquoi est-ce qu’on a décidé de changer de compilateur ? Ah pour des histoires de taille mémoire (640 kB should be enough? On avait même plus, genre 2 Mo de ROM, 4 Mo de RAM, large… ou pas). D’ailleurs, au moment du changement, on en a profité pour faire quelques optimisations. Non pas des flags genre -O1 ou -O2. Plus des choses sur le layout mémoire, on a ajouté __attribute__((packed)) qui est supporté, on a un peu changé le linker script…
Par exemple, le packed, ça nous permet de gagner de la place, avant toutes les variables étaient alignées sur une adresse multiple de 4, que ça soit un nombre sur quatre octets, ou un char d’un octet, ils prenaient au moins quatre octets. Maintenant, on a mis les data types multiples de quatre au début de la structure, bien alignés, puis les types qui prenent deux octets, on en met deux dans quatre octets (au lieu d’un et de gacher deux octets pour rien), puis les types de un octect, on en met 4.
D’ailleurs, par exemple, l’instruction à %pc, elle charge une donnée d’un seul octet qui est dans une adresse du type XXX+3, où X est un multiple de 4. C’est pas illégal de faire ça (donc non, toujours pas d’instruction illégale ici)
Après quoi, c’est là où David revient (dans mon souvenir en tout cas, ça venait beaucoup de lui, mais on était beaucoup à échanger sur le sujet). "Ok, %pc lit une donnée non alignée, et il le fait correctement. Mais s’il y a un bit flip, il se passe quoi ?. Bah rien, EDAC détectée, trap, on exécute le code assembleur qui marche sur les autres satellites.
Ah oui, mais non. Si on lit un octet, on peut lire XXX+3, mais si on lit 4 octets, c’est interdit. Il faut lire une adresse multiple de 4. Et donc on a une EDAC, et quand on rentre dans la trap
; adresse == XXX+3
disable_edac_trap: ;
load [adresse], reg ; Lire 4 octets
enable_edac_trap: ;
store reg, [adresse] ;
Ah oui, mais non. load ça lit 4 octets, c’est illégal de lui passer une adresse non multiple de 4, c’est une illegal instruction. Donc ça pourrait être ça :
XXX (l’EDAC est toujours calculé sur 4 octets d’une adresse alignée, même si on lit décalé)%pc
XXX+3
XXX+3
ILLEGAL CPU INSTRUCTION, allez en prison sans passer par la case départSur le papier, ça marche. On peut même faire un petit logiciel sur le banc, qui fait juste un load [XXX+3], reg et qui génère une ILLEGAL CPU INSTRUCTION. Mais évidemment nos managers (et notre client) voudraient un peu plus qu’un « sur le papier, c’est ça, trust me bro ».
Donc la question "c’est possible de reproduire exactement comme dans l’espace, plutôt que de juste exécuter une instruction illégale à la main ?". Avec le vrai logiciel qui était dans l’espace, pas un logiciel de test ?
Bien sûr, il suffit d’attendre d’avoir un bit flip, sur le banc, juste au bon endroit, au bon moment. Vous avez combien de siècles devant vous ? Ou alors est-ce qu’on peut mettre le banc à côté d’un réacteur nucléaire ? Ça devrait accélérer les choses (du bon côté du mur de confinement. Ici, “bon”, ça veut dire mauvais pour les humains)
On va quand même regarder si on peut provoquer un bit flip autrement. Bon, a priori, en interne, au logiciel, on ne sait pas comment faire. La doc du processeur (qui vient avec l’edac) ne nous aide pas non plus. On demande à ceux qui nous ont dit que « chez eux, ça marche » qui nous répondent que la trap de l’edac, ils ne l’ont jamais testé, c’est juste une revue de code.
Bon, on envoie quand même un courriel au fabricant du proc, au cas où. Réponse rapide « je reviens vers vous dès que je sais ». Quelques jours (2, 3 semaines ?) plus tard : "Ah oui, c’est possible. D’ailleurs c’est documenté. Page WSYZ sur 5000, il y a **un* paragraphe qui explique comment faire*".
Le TL/DR du paragraphe : Il est possible de désactiver l’EDAC en écriture. Par contre il faut faire des choses spécifiques, donc on a pas de commande prévue pour le faire “simplement” depuis l’extérieur, il faudrait une nouvelle fonction.
void generer_bit_flip(int address, int valeur) {
*address = valeur; // écrit la valeur correcte avec l’edac normal
manipulate_specific_register_to_disable_edac(); // on a dû écrire la fonction, c’est pas aussi simple
*address = valeur ^ 0x00000001; // écrit la valeur avec un bit changé, mais sans changer le checksum enregistré
manipulate_specific_register_to_enable_edac();
}
Ça tombe bien, le logiciel qui est dans l’espace a deux fonctionnalités qu’on a testé, mais jamais en vrai avec un truc vraiment utile
Donc on peut créer une fonction comme ça (en gros)
void generer_bit_flip(int address, int valeur) {
static int actif = TRUE;
if (actif) {
*address = valeur; // écrit la valeur correcte avec l’edac normal
manipulate_specific_register_to_disable_edac(); // ou a dû écrire la fonction, c’est pas aussi simple
*address = valeur ^ 0x00000001; // écrit la valeur avec un bit changé, mais sans changer le checksum enregistré
manipulate_specific_register_to_enable_edac();
actif = FALSE; // on ne veut le faire qu’une fois
}
}
Une fois qu’on a la fonction, on la compile. Ensuite on charge le logiciel normal sur le banc, on se met en conditions « avant l’anomalie », on uploade la fonction, on l’active et…
Le banc change de mode, passe du mode 2, au mode 3, sur le calculateur redondant. On vérifie le contexte, même signature que l’anomalie en vol. C’est bon on a fini. (Ouf, mon journal est déjà trop long)
Oui, non, pas exactement. On a une explication, il faut une correction maintenant. Bon, c’est simple. Pour lire une adresse alignée sur 4, il suffit de mettre deux bits à 0. Finalement, voilà le patch
address = address & ~0x3 ; ** Cette ligne est le patch **
disable_edac_trap: ;
load [adresse], reg ;
enable_edac_trap: ;
store reg, [adresse] ;
Oui, c’est un patch d’une instruction dans le binaire. (Techniquement, 5 instructions, parce qu’il faut décaler les 4 instructions existantes de 1, mais on avait des noop en dessous, donc ça rentre)
La dernière question, c’est quelle stratégie d’ update appliquer. On a techniquement quatre familles de satellites à considérer :
Ce qui a été décidé : La première catégorie : Techniquement, on pourrait discuter du fait qu’il y a un bug ou non. Mais même si on considère qu’il y a un bug, il ne peut pas être déclenché. Donc on ne touche à rien. La catégorie 4, c’est facile. Ils sont au sol, on fait une nouvelle version complète du logiciel, on reflashe la rom en entier, et on vérifie.
Il reste les deux autres catégories. Bon la seule différence, c’est qu’un, toujours en mode 3, tourne pour l’instant sur le calculateur redondant (on peut revenir en mode 2, manuellement, si on veut). Donc on décide « on va faire la même chose », et on va corriger le problème (on aurait pu ne rien faire et dire « bah, si ça arrive, on connaît et on revient à chaque fois manuellement en mode 2 »)
Là encore, même si on corrige, on a plusieurs choix :
La solution 2, retenue, c’est un mécanisme (déjà dans le logiciel) qui permet de mettre les infos dans une autre mémoire (partagée par les deux calculateurs). Au boot, la ROM est copiée dans la RAM (on exécute le code depuis la RAM), et « avant de démarrer » on vient regarder dans cette table, si l’on doit patcher la RAM. Cela donne quelque chose comme :
ROM (logiciel original) --> Copie vers la RAM --> RAM (logiciel original) --> fonction de patch au boot, vient modifier la RAM --> RAM (trap corrigée) --> boot du logiciel.
Qu’est-ce que je retiens principalement ?
Voila, en quelques pages, une vieille histoire qui m’a marqué. Je suis probablement une des personnes qui a participé à un des patchs le plus haut du monde (plus de 1 000 km d’altitude)
Bon en vrai, la NASA fait des mises à jour logicielles sur des rovers sur Mars, donc c’est clairement pas le record mais c’est pas trop mal (ils ont même peut-être des mises à jour sur leurs sondes plus loin de la terre)
Note : cette histoire date maintenant d’il y a plus de dix ans. Il y a donc forcément des simplifications, des imprécisions, et probablement des erreurs. Aucun satellite n’a été maltraité pendant cette enquête. Il y en a bien un qui est tombé à terre, mais ça c’était avant le lancement.
Commentaires : voir le flux Atom ouvrir dans le navigateur
At last, Morocco have arrived at the tournament they are hosting. For four games they had played scratchy, crabbed football. Finally, in a spiky, ill-tempered quarter-final, there was something more like the Morocco that reached the semi-finals of the World Cup two years ago. If the game wasn’t fluent, that was largely Cameroon’s doing as they spoiled and delayed and sought treatment for injuries. But the hosts, for the most part, retained their cool, protecting a lead earned with verve in the first half with maturity in the second.
In previous games, Morocco had looked tense, limbs leadened by the expectation of a country that last won the Cup of Nations 50 years ago and that has spent a vast amount on football-related infrastructure as it prepares to co-host the 2030 World Cup. The coach, Walid Regragui, was even booed in the last-16 victory over Tanzania, his football deemed overly cautious despite a record of only four defeats in his 46 games as national coach before this quarter-final. “I always say that we are a family,” said Regragui. “Even if many people don’t believe in us or in me … that’s OK. We play for the country and for the supporters who want to see Morocco at the top.”
Continue reading...
© Photograph: Visionhaus/Getty Images

© Photograph: Visionhaus/Getty Images

© Photograph: Visionhaus/Getty Images
Trump’s admission that he recognises no constraint outside his own morality was a horrifying moment of truth. It should galvanise all those who oppose him
For a serial liar, Donald Trump can be bracingly honest. We’ve known about the mendacity for years – consider the 30,573 documented falsehoods from the president’s first term, culminating in the big lie, his claim to have won the 2020 election – but the examples of bracing candour are fresher. This week both began and ended with the US president speaking the shocking truth.
At a press conference to celebrate his capture of the Venezuelan dictator Nicolás Maduro, Trump announced that from now on the US would “run” that country, before moving in the very next breath to Venezuela’s oil. There was no pious talk of democracy, scant mention even of the drug trafficking that earlier served as a pretext for military action. Instead, Trump said out loud what had once been a slogan on leftist placards in protest at past US interventions, admitting that it really was all about the oil. It was as transparent a revelation of Trump’s true motive as you could have asked for.
Jonathan Freedland is a Guardian columnist
Guardian newsroom: Year One of Trumpism: Is Britain Emulating the US? On Wednesday 21 January 2026, join Jonathan Freedland, Tania Branigan and Nick Lowles as they reflect on the first year of Donald Trump’s second presidency. Book tickets here or at guardian.live
Continue reading...
© Photograph: Evan Vucci/AP

© Photograph: Evan Vucci/AP

© Photograph: Evan Vucci/AP
It is one of the most tantalising – and entertaining – puzzles in art, stretching from the Louvre to the Loire via, well, Norfolk. And our critic thinks he has just worked it out
Increased security after the recent heist has made the queues at the Louvre even slower, yet on this rainswept, very wintry morning, no one grumbles. After all, the Mona Lisa is waiting inside for all these tourists who have come from the world over. Leonardo da Vinci’s woman – swathed in dark cloth and silk, smiling enigmatically as she sits in front of a landscape of rocks, road and water – draws crowds like no other painting. But if the Mona Lisa can attract such attention fully clothed, what would the queues be like if she was nude?
Strangely, this is not just amusing speculation – because in 18th-century Britain, she was. An engraving issued by a publisher called John Boydell gave libertine Georgians the opportunity to hang “Joconda” in their boudoir. It must have been popular because many copies survive. This Mona Lisa sits in a chair with her hands crossed in front of a fading view of distant rock formations. And, like the Mona Lisa in the Louvre, she smiles enigmatically. But there is one key difference. She is naked from the waist up.
Continue reading...
© Photograph: Album/Alamy

© Photograph: Album/Alamy

© Photograph: Album/Alamy
Only one club are sitting pretty at the top of the Premier League, but the supporters’ anxiety after 22 years without the title risks infecting the players
Full-time and handshakes. A little Tears for Fears tinkles over the public address system. Beyond that … what, exactly? How to describe this swirling, velvety anti-noise? The sound of no gloves clapping? The sound of time physically disappearing down a vortex? The sound of no emotions?
It began with North London Forever and by the end we felt as though we had been in north London for ever: stuck on an endless loop of William Saliba passing to Jurriën Timber, of Virgil van Dijk pausing as he tried to bait a press that would never come. Long periods of this game were played at literal walking pace.
Continue reading...
© Photograph: Tom Jenkins/The Guardian

© Photograph: Tom Jenkins/The Guardian

© Photograph: Tom Jenkins/The Guardian
Trump sounds off on Venezuela’s future, Taiwan’s security and his aims for Greenland, days after operation to seize Nicolás Maduro
Just days after launching an unprecedented operation in Venezuela to seize its president and effectively take control of its oil industry, Donald Trump sat down with New York Times journalists for a wide-ranging interview that took in international law, Taiwan, Greenland and weight-loss drugs.
The president, riding high on the success of an operation that has upended the rules of global power, spoke candidly and casually about the new world order he appears eager to usher in; an order governed not by international norms or long-lasting alliances, but national strength and military power.
Continue reading...
© Photograph: Yuri Gripas/EPA

© Photograph: Yuri Gripas/EPA

© Photograph: Yuri Gripas/EPA

© Mimi d’Autremont for The New York Times

© Jefferson Siegel for The New York Times

© Eric Lee for The New York Times