Blog

Mar 2022

Travelling while brown: Mexico visa edition

Wondering how to apply for a temporary resident visa to Mexico as a person of colour in a “third world country” (Kenya) as a citizen of a different third world country (India)? Buckle up! This guide will lay out the dos and donts, with detailed instructions on how best to avoid rejection. Failing that, it will remind you your place in the world.

Shed your self-respect

This is the most important step in this (and any) visa application process. Find a small cardboard box (A dirty shoebox will do) and place your self-respect and expectations of civility and equality in it. If it’s been a while since your last visa application, your self-respect may have regrown and it may be hard to fit it in the box. You can reclaim your self-respect from the box when the visa process is done, but it’s best if you just throw away the box.

Read the visa rules carefully

Go to the consulate website and read the visa page. Take care to note the requirements for your type of visa. In case of the temporary resident visa, the consulate requires

  • Proof of residency in the country you’re applying from
  • Bank account statements for the last six months

Double-check with the consulate

Just to be sure you don’t get your hopes up of getting a visa after reviewing the website, contact the consulate, stating the visa you’re interested in and confirming the documents you plan to apply with. This will almost certainly be met with an automated reply linking you to the very website you got all the information from but if you’re lucky, you might get a passive-aggressive response from a human linking you to the website instead! 😍

This is a good reminder to temper your expectations and practise stoicism - remember, nothing in this world is for sure, not least the possibility of your getting a visa despite meeting all the requirements.

You want privacy? What are you, a terrorist?!

Take a stab in the dark, and send an email to the consulate with all your documents and ask if they’re in order. You may not know who (or how many people) have access to the email, but it doesn’t matter - people who have nothing to hide don’t expect their bank statements and the personal transactions they contain to be private. Privacy is for other people who distinctly don’t look like you.

Expect the unexpected

You didn’t think that the requirements you saw on the website would be everything, did you? No, of course not. You know better than that - There are always hidden requirements! It would be no fun if consulates listed out all of them on their websites or responded to your emails/phone calls with the real list of requirements.

I followed the requirements on the website and emailed the consulate a bank statement for the last six months, generated by the online statement generation tool of my international bank (Standard Chartered) only to be told that I need to submit a statement for the last twelve months. Surprise!

What if you switched banks eight months ago and cannot obtain a bank statement from your previous bank? No problem, the consulate has you covered - Just submit a letter from your employer instead, as well as your payslips for the last six months. Just to be sure that you’re not making up an entire organization, its payroll system, contact information, and address, make sure to include the passport bio-data page of the person who signs the letter confirming that you work for the organization. Easy peasy!

Strengthen your bond with your boss

You may not have read this in your run-of-the-mill “How to be a manager” book, but the true sign of a healthy relationship with your manager is having a copy of their passport bio-data page! After all, nothing says “I trust you” than sharing personal IDs with your reports.

I reached out to my boss and explained my predicament and how I was running out of time before some upcoming travel plans that would take me out of Kenya, and in the course of a day, she shared a signed letter with the organization letterhead stating my job role and tenure at the org, as well as my salary and her passport details. She also included a photo of passport bio-data page! In unrelated news, my current role at Maisha Meds has been the longest of my career.

Embrace radical candour

Think you’re an open book? Consulates have a new free service to aid you in your journey towards simple, transparent living - Doxxing your salary!

Remember that signed letter from my boss, with the organization letterhead? It contained an email. A public-facing email address that we share with external parties, which forwards all emails to five people across the org. See where I’m going with this?

To make sure that I did not make up an organization, payslips from the org, a signed letter from my boss and a photo of her passport, the consulate decided to contact that public email address. It included my payslips for the last six months in the very first email and asked for verification.

Understandable, really. You can never be too sure of the legitimacy of documents these days.

Encryption, you say? Stamps and signatures on paper are the true sign of security

Speaking of legitimate documents, don’t forget to get your bank statements and your payslips doodled on beautified bedazzled certified by professionals - bank managers and your org’s finance team respectively. Everyone knows that even a truly hardened criminal who has found a way to forge the bio-data page of a passport and set up a fake organization website and Google Workspace to intercept emails sent to its public-facing email address to confirm the legitimacy of their payslips cannot crack the certification rubberstamps of a bank.

To the consulate’s credit, it always referred to “certified bank statements” and “certified payslips”, but I did not pick up on that until it was explicitly flagged, in the seventh round of correspondence with the consulate. No problem though, all it took was a visit to a bank branch and reaching out to my very accommodating mostly-remote colleague who, recognizing the limited time I had to get a visa before my travel, invited me to drop by their house with printouts of my payslips so they could quickly sign the documents. Download a scanner app, take photos of a lot of pages adorned with signatures and stamps and voilà, certification complete!

Practise patience

So you’ve submitted all your documents, and the consulate has finally confirmed that they’re all in order, but there has been radio silence since then. Time for another reminder that the only thing you can control in this world is your mind (and some of us need medication to have some semblance of control). Never mind that it has been more than a month since you established contact with the consulate. Or that you only have two weeks before your travel plans that will keep you out of the country for a month.

Don’t even think about emailing the consulate informing them that you don’t live in Nairobi, the city the consulate is located in, and that you would appreciate their accommodating a visa appointment before your upcoming travel plans. Not unless you want a generic response with a link and a quote from the website stating that the processing of documents can take up to 10 days from the submission of all documents. This time, the word on the website is the law.

Know your priorities

What would you do if a consulate emails you at 1pm informing you that your appointment had been scheduled for 9am the following day? If you answered, “I’d emphatically accept and show up the next day, because I’d put the rest of my life on hold for the visa appointment anyway”, you are clearly a person who has accepted your place in the world. I had not, especially as I had already travelled to Rwanda at the time, so I replied that “9am tomorrow would not work for me” and requested an appointment at the end of March, when I expected to be in Nairobi for a few days.

Are we sure that samsara is not about obtaining a visa?

Maybe Lumbini had restrictive visa policies?

After following up a second time, the consulate wrote back to inform me that my visa appointment had been scheduled for the first week of April. You’d think seeking an appointment a full 25+ days in advance for the end of March would ensure that appointments were still open and you’d be able to get the date that works best for you (hard to imagine a clamour among folks in Kenya to travel to Mexico), but it is not your allotment in life to question the decisions beyond your control. Well, maybe sometimes it is, as I did, asking if the consulate could accommodate my preference for end of March. It worked - I was informed that my appointment had been set for the date I requested.

Was it that simple, you ask? No, of course not. The consulate informed me that because my visa appointment would be a full month after the date it had initially set for me, I would need to submit fresh bank statements and payslips. All certified of course.

Will this ever end?

We’re getting there, I promise. Long story short, I made it to my appointment with freshly signed and stamped payslips and bank statements, passport copies, signed letter from my employer (needed a new one, just in case I’d been fired in the month since I’d last emailed the consulate), visa application form, passport photos in a specific dimension (which weren’t needed in the end because a digital photo was taken at the consulate instead).

After two in-person visits to the consulate and additional documents to prove my “economic solvency”, I finally got a shiny temporary resident visa sticker in my passport!

I hope I’ve demonstrated how easy it is to apply for this visa! All it takes is a little bit of patience.

Goodbye Kisumu

Early morning Lake Victoria boat ride

After two years of (mostly) staying put in Kisumu, I’m getting back on the road!

Of all the places in the world, I would not have guessed that I’d break my nomadic streak for life in Kisumu. I’m glad to have spent all this time in the slow pace of a small city - definitely dodged the intense lockdowns around the world.

Things I’ll miss from my life in Kisumu

  • walking down the quiet Okore Road or Ridoch Road as the sun sets and the heat of the day lets up

  • cycling or running along the Lake Victoria shore in the direction of Dunga beach, noticing the water hyacinths surrendering or gaining turf as the “seasons” change.

  • grabbing a booth and working from Java House at West End Mall in the afternoons - Going to Java was the one COVID risk I allowed myself for the sake of keeping my sanity and having a reason to get out of the apartment. Debatable if I held on to my sanity, but it became such a comfort that I’d visit Java at least once a week, and get one of the few vegan/vegatarian options in the menu, so much so that the waiters knew exactly what I’d get. “Green smoothie and a garden salad?”. All I had to do was nod.

  • the stunning views of the hills around Kisumu - I was lucky to be in a fifth floor apartment, and seeing the orange and purple hues of dawn over the hills was an experience.

  • the one-hour (minimum) wait times at most restaurants and how it teaches you to embrace Kisumu’s quirks and work with it - I’d call in my order an hour in advance and would have to wait only 5 - 10 minutes when I got there 😛

  • rushing to Chandarana/Food Plus before closing time for groceries that cannot be found elsewhere in Kisumu (hummus, kombucha, vegan pesto/ice cream/wine, fresh tofu)

  • being accosted by the same group of boda drivers outside West End Mall who know exactly where to drop you off, all jostling to be the one to make 50 shillings. I’ve been told that real Kisumu folks pay only 20 shillings to go to most places, but 50 is the minimum price for foreigners.

  • the long rains - the howling winds, the lightning storms over the lake, the sheer intensity of rain.

  • the dodgy instant electric heaters - Can you really say you’ve lived life on the edge if you haven’t showered under an electric showerhead that instantly heats water, as you contemplate high-voltage electrocution and bodies charred beyond recognition? Just kidding, this probably belongs in the next section.

  • the elaborate greetings. As someone familiar and very comfortable in the brusque, utilitarian, seemingly rude (by Western standards, not mine) ways of urban Indian customer service at grocery stores, and small shops and restaurants, the social ritual of greeting absolutely everyone before engaging with them initially drove me crazy (So inefficient). This is a real transcript of a phone call from an unknown number

    Me: "Hello?"
    Person: "Hello, how are you?"
    Me: "I'm fine, how are you?"
    Person: "I'm fine too"
    *Awkward pause
    Me: "Yes?"
    Person: "I'm calling you from DHL. There is a package at our office...."
    

    But now? Kisumu has done a number on me. I was in India briefly last year, and I got strange looks because I started all interactions with “Hi, how are you?”

  • making small talk with a stranger and discovering that they run a “ministry” on weekends and collections have been down in recent months. The odds that that has happened to me 2 - 3 times!

  • watching the sunset in the weirdly segregationist, melanin-free environs of Dunga Hill Camp on a Friday night, and greeting folks whom you’ve only ever seen with a bottle of beer in their hands (and presumably not their first for the evening). Alcoholism is a real thing, Kisumu!

  • taking a boda to the airport, and catching your flight even when you get to the airport 15 minutes before takeoff.

View of the hills near Kibos Road, Kisumu

Things I won’t miss

  • The garbage burning and the filthy air (sometimes)! Don’t get me started (I’ve written about it before).
  • The drunk-driving! If you see someone driving past midnight on a Friday, I promise you they’re not sober. It blew my mind when I learnt that drunk-driving was just the norm in Kisumu.
  • Maybe it’s just me and my complete lack of social media and/or social skills, but it felt like there was absolutely nothing to do in Kisumu but to go to church or drink to get hammered. At this point in my life (and, I hope, always), I don’t need someone shouting at me that “the fiery depths of hell await you for your sinful ways” in the hope of scaring me into committing to a tithe, nor do I want to run away from an existential crisis by numbing my mind with alcohol (I prefer travelling, i.e, literally running away, instead). That meant..spending a lot of time reading and watching stuff online. And resentfully finding meetup.com and Alliance Française events in Nairobi
    • That said, I’m leaving with a tinge of regret that I didn’t use my time in Kisumu to travel to the places around it. I’ve been learning more about permaculture and natural farming lately, and after spending days trying to find a permaculture farm accessible to me that would be willing to give me a tour, I found one an hour’s drive away from Kisumu 🤦. I also don’t feel like I’ve seen much of Kakamega and beyond, not to mention Mount Elgon National Park!
  • The madenning chorus of church loudspeakers on the weekends, starting as early as 8AM and stretching all the way to about 6PM.

Exciting times for Kisumu

I’m cautiously optimistic about all the upcoming changes in Kisumu - A waterfront promenade is under construction, the Kisumu port is being revived, many parts of the city have been spruced up and new bicycle lanes created in preparation for the Africities summit in a few months, and the colonial-era train is finally functional again, if your definition of functional accommodates a train that averages about 20 km/h and takes 12 hours from Nairobi to Kisumu.

Depending on how the election in August ~is decided~ goes, the next President may have strong ties to Kisumu - Hopefully that translates to a greater focus on the region, if only for the purposes of voter appeasement.

What’s next?

I’m looking forward to doing a bit of travelling - Yes, it’s inconvenient to look up COVID restrictions and take PCR tests, but after a long time in Kisumu, the scale has tipped in favour of travelling despite the inconveniences. I feel silly that I haven’t seen much of east Africa in all this time in the region, so I have Rwanda on my mind.

What I’d really like from this year is to find a small house on a permaculture farm, in a part of the world with a mild climate, spending hours outdoors everyday, working on the farm alongside people willing to teach me their farming practices and put up with my remote work, somewhere I can go cycling or wandering off every weekend.

Jun 2021

Larynx - A viable Linux TTS

I spent some time over the weekend experimenting with voice2json and rhasspy, trying to set up a fully offline voice assistant system using Mozilla DeepSpeech for speech recognition, a template file containing all known phrases and their mappings to intents, an intent recognizer and a local shell script to parse the recognized intent and invoke commands (think opening a website or folder when an intent is recognized). Rhasspy was easy to use and really fun. It’s amazing how far we’ve come in terms of open-source tools in the TTS/speech recognition space.

Along the way, I discovered Larynx, a TTS system for Linux with high-quality voices from Glow-TTS and others, with intonations that sound human. I’ve kept an eye on the Linux TTS space for years and have been disappointed by the limited consumer-use options. Often, the pre-trained TTS voices sound all too robotic for everyday use. I suppose that’s understandable given the dearth of open-source voice datasets (which is why projects like Mozilla CommonVoice are so exciting!). It’s nice to have a pleasant pre-trained TTS model natively available on Linux.

My use case is to copy text in a browser/Thunderbird RSS article, hit a shortcut and have the TTS system read the selected text aloud so I can look away from the screen and just listen.

Setup

I followed the Debian installation instructions, and downloaded and installed the tts, lang-en_us and Harvard Glow TTS files.

# cd Downloads # (or /path/to/downloaded/deb/files)
sudo apt install ./larynx*.deb

TTS Shortcut

To create a shortcut that invokes Larynx on selected text, I added aliases in my ~/.bash_aliases file. They use xclip to access clipboard and selection data. On Debian-based systems, you should be able to install it with sudo apt install xclip.

# Speak text passed as argument
# Usage: speak "This is a test"
alias speak="larynx --voice harvard-glow_tts --interactive"

# Speak clipboard text
# Usage: speak-clipboard
alias speak-clipboard="xclip -out -selection clipboard | speak"

# Speak currently selected text
# Usage: speak-selection
alias speak-selection="xclip -out -selection primary | speak"

Under Settings –> Keyboard on GNOME, I added a custom keybinding for Super+S to invoke bash -i -c "speak-selection". This lets me select any text and hit Super+S to invoke larynx

References

Apr 2021

Jodi Sudoku

Happy to share that I’m working on Jodi Sudoku, an open-source (AGPLv3), Sudoku progressive web app with the goal of implementing multiplayer support using WebRTC!

I’ve been following the adoption of WebRTC (now supported on all major platforms except Safari, infamous for dragging its feet) and the decentralized web for years, but haven’t had the opportunity to work with it, so I decided to use it in a hobby project.

Frontend

The frontend code uses the standard React + Typescript setup, with React Router and Redux. So far, the web app features

  • Starting a new game with a level of difficulty of your choice
  • Keyboard and mouse/touch input
    • Changing the mode of entering values into cells - Choose a digit first, and then click a cell to enter the digit, or vice versa
  • Responsive cross-platform layout, tested on Firefox and Chrome (desktop and mobile)
  • Undo and redo using redux store history

I’m a big fan of internationalization and supporting regional languages, so the basic one-player implementation currently supports Kannada, English and Polish using react-i18n.

Backend

The backend is more esoteric - I’m interested in using Rails + WebSockets. While I primarily wear the Android hat at work, our backend is built with Rails (a framework I had not worked with before) and I’m interested in improving my Rails fu through this project and contributing more than just the occasional pull request. Rails has a thin wrapper over WebSockets called Action Cable, and I’m curious to see how it fares compared to Node ( + socket.io), which seems to be the internet’s go-to recommendation for scalable WebSockets. WebSockets is a great way to achieve peer discovery (your browser tab discovering peers and finding a way to establish a direct connection despite NAT traversal), required for WebRTC. If there’s a lot of traffic and Action Cable/Rails struggles under the load, I’m aware I might need to swap out Action Cable for Node someday, but I think the Rails experimentation will be worth it. Besides, Node feels like home turf and it’ll be fun to try something different :)

Multiplayer

What’s with the idea of multiplayer Sudoku, you ask? Is there any interest in multiplayer Sudoku? I’m not sure - I found a few multiplayer games on different app stores, but I don’t think there’s a big community. This project is honestly just an excuse to find a way to play Sudoku with my mum - Playing Sudoku together is a ritual whenever I’m in Bangalore. With mugs of basil and ginger tea after dinner, and armed with pens at the kitchen table, we pair up (Jodi (ಜೋಡಿ) is the Kannada word for “pair”) on solving the Sudoku puzzle in the daily newspaper (remember those?), trying to get as many digits as possible but also explaining to each other how we “unlocked” the right digits. I miss that, and I see no reason why that should stop when I’m not in Bangalore :) I’d be happy if others find it useful as well.

The idea is to implement URL-based discovery of peers. Like Jitsi calls, users who open the same link will be able to connect to the server using WebSockets, receive information from the server on the users in the “room”, and then establish browser-to-browser WebRTC peer connections, making the server connection theoretically unnecessary after that point.

I’m thinking of building different multiplayer modes

  • Cooperative: all players in a room collaboratively solve the same puzzle together
  • Challenge (same puzzle): all players in a room individually solve the same puzzle, only aware of the number of empty/filled cells of other players.
  • Challenge (puzzle of same difficulty): All players in a room solve different puzzles of the same difficulty level, only aware of the number of empty/filled cells of other players. Could be fun to also add a “Peek player’s board” feature
  • Time challenge? Turn-based games? Some dastardly variant of Sudoku?

Q: Privacy and fault tolerance

I’ve encountered a lot of flaky internet connections and I’d like Jodi Sudoku to be tolerant of and handle edge cases related to flaky connections, users having to refresh their tabs, abrupt drop-offs etc. Given that exploring WebRTC and peer-to-peer systems is one of the goals, it’s imperative that the server know as little as possible about users, rooms or the type and state of the game in a room.

If the server knows nothing about the state of the game in a room, who is the source of truth in case of failure? Should all players in a room store the game state locally (in the browser local/session storage), and send the most recent state (via WebRTC) to any player who re/joins a room? What happens if two players disagree on the most recent state of the game? Should rooms have a leader who is responsible for storing the game state and sharing it with users who enter the room? What happens if the leader’s connection goes down? I have struggled to square the two seemingly contradictory goals of privacy/decentralization, and maintaining a source of truth for fault recovery, and decided to move forward with making the server aware of users, rooms, and game states. Please reach out if you have any suggestions that would keep the server out of the loop after peer discovery.

My current approach is:

Peer discovery

  1. Abbi enters a room (a room is identified by the link, i.e, judisudoku.app/some-room)
  2. Abbi establishes a WebSocket connection with the server.
  3. Abbi receives the list of users in the room via WebSocket. The list does not have anyone except Abbi. The WebSocket connection with the server is kept open.
  4. Ilana enters the room, connects to the server and receives the list of users. The WebSocket connection with the server is kept open.
  5. Abbi and Ilana use a STUN server, bypass their NAT, and establish a peer-to-peer connection.

Gameplay

  1. Abbi and Ilana begin a cooperative game, notifying each other via WebRTC and notifying the server via WebSocket.
  2. Abbi and Ilana send messages directly to each other via WebRTC when they enter values into cells. They would also need to passively notify the server of the state changes via WebSocket
  3. The server passively stores the game state, doing nothing with it.

New player/rejoin

  1. Jaime joins the game late, and is announced to the other users by the server (the updated list of users is shared) via WebSocket
  2. The server shares the latest state of the game to Jaime via WebSocket
  3. Once connected to the other users via WebRTC p2p connections, Jaime follows step 7 to participate in the game.

Using the server as the single source of truth allows users who join a game midway or experience connection issues and rejoin the game to continue the (collaborative) game from the latest state (if other users have made changes). Other multiplayer modes may need to handle failure/rejoin scenarios differently.

Next steps

I realise I’ve defined a lot of lofty technical ambitions for a simple Sudoku webapp, and I’d like to take this one step at a time. I’m planning to make small releases to keep up my motivation and get feedback from my target demographic of one - When it comes to hobby projects, I tend to be very excited during the design phase and in the early days of implementation, and lose interest and move on to the next shiny puzzle that needs solving when the problem is more or less “solved” in my head :)

The next release will have peer discovery and cooperative game mode.

European fantasy

For the first time in ten years, I marked one whole year (and counting) living in the same country thanks to Covid, and while I’ve enjoyed liberties in Kenya (open restaurants, only one major lockdown and few restrictions, few cases until recently) that many around the world are still waiting to get back, I find myself longing to escape to Europe.

Of course, the Europe in my mind is completely untouched by Covid, there are no restrictions, all art spaces are active, you can drink a beer by the river, it’s springtime and sunny, and you can travel as you please, because that’s how I last saw it :)

Trigger warning: Privileged person whining about the hardships of others

The relentlessness of Kenyan inequality can be hard to bear at times - I’ve been trying to explore the streets of Kisumu by bike, venturing into neighbourhoods and streets I don’t usually take. Cycling by the lake wearing my $30 helmet and seeing parts of people’s houses flooded after heavy rains, and kids collecting water from filthy ditches or the lake in distinct yellow jerry cans while someone else washes their motorbike a few metres away makes me want to give up.

You’d think India would’ve inured me to the injustices of poverty and poor infrastructure, but I’ve realised India is quite good at ghettoising its poor, politely tucking them away in long-forgotten parts of towns and cities that are avoided by anyone who can afford to do so, certainly politicians. Or perhaps it’s more accurate to say the wealthy have managed to outspend, gentrify and shut out the poor from “their” neighbourhoods. The segregation seems less stark to me here in Kenya.

A few days after I moved into my apartment, someone rang the doorbell - It was a shy young woman, probably in her late teens. She seemed very uncomfortable and struggled to say, “I would be grateful to you if I could have any work to do in your house - cleaning the floor, and doing your dishes and laundry?”.

What was I to say? It looks like it’s common to have housekeepers in Kenya, but it makes me very uncomfortable, not just because of the risks of catching Covid and the dubious ethics of paying someone to clean up after me, but also I get nervous at the very thought of strangers coming into my private space and having nowhere to hide while they’re around, possibly for hours (The joys of living with anxiety!). With a lot of guilt and fully aware that I might be cutting off an opportunity for her to make a few hundred Kenyan shillings a week, I declined.

Such moral conundrums are an everyday occurrence - Last month, I stepped out to get some bananas from a nearby supermarket, and as I walked past an empty plot, I saw a woman sitting at a small folding table with no shade, selling eggs, fried meat and bananas. A child played in the dirt nearby. The sun was setting after a hot day, and the bananas were well on their way to brown. I felt torn - I had stepped out just to get bananas, and I could support the woman and her child by buying bananas from her knowing that the bananas would go bad within a day, or go to the supermarket and buy less ripe ones. I kept walking (with only a tiny bit of hyperventilating), but it was a tough choice. Everyday, very real tests of Kant’s categorial imperative take their toll. All the bananas I’ve bought since then have been from her though (and the nearly brown bananas must have just been due to a bad day - the bananas have been great since then)! :)

Is it possible to respect your own values and preferences and still find a way to help others that doesn’t involve paying for things or services you don’t need, or simply handing people a wad of cash?

I know it’s pure escapism, but I’m craving a respite from guilt for a bit. It would be a dream to be in a place where there might still be plenty of inequality but not the kind that leads to extreme starvation or deprives people of basic infrastructure or access to healthcare. Where the crunch of a snail on a bike path getting crushed under my bike wheels despite my best efforts to avoid it is the only source of guilt pangs. Where I’m not constantly aware of my privilege.

I never thought I’d think fondly of places where, among many xenophobic incidents, someone called me a terrorist, pointed at my blinking red bike light and made the gesture of a bomb blast :D