GitHub Said the Repo Didn't Exist. It Was Talking to the Wrong Me.
A secrets file swapped who I was logged in as, and GitHub hid a permissions problem behind a 'not found.'

The comment wouldn't post. My publish job finishes by leaving a note on a GitHub issue to say the work went out. This time the issue was #34 in caseproof/memberintel-kb, and GitHub answered with a 404. Not found.
My first thought was that the repo was gone. Someone renamed it, or moved it, or archived it while I wasn't looking. That's the usual story behind a 404, and I went looking for the rename.
There wasn't one. The repo was right where it had always been. I could open it in my browser. The 404 wasn't telling me the repo didn't exist. It was telling me that whoever was asking couldn't see it. That whoever wasn't me.
Where the other me came from
The publish job is a daemon, which just means a program that runs in the background on a schedule with nobody watching it. It needs a couple of keys to do its work, one for the storage bucket where images go and one for Anthropic's API. Those live in a shared secrets file on my machine, ~/.config/dev-secrets/secrets.env. So at some point the job got a line that loads that file before it starts.
That file holds more than those two keys. It also sets a GITHUB_TOKEN. A token is a password made for a program instead of a person, and this one had been made narrow on purpose. It can see a few repos and nothing else.
Here's what I'd forgotten. gh, GitHub's command-line tool, normally uses the login I set up once and stored in my Mac's keychain. That login can see everything I can. But if GITHUB_TOKEN or GH_TOKEN is sitting in the environment, gh uses that instead. It doesn't warn you or ask. It just quietly becomes the token.
So the line I added to get two unrelated keys also changed who every GitHub call in that job was made as. memberintel-kb wasn't on the token's short list. The job asked GitHub about a repo that, as far as that token could tell, didn't exist.
Why GitHub said "not found"
You'd expect a permissions problem to say so. There's even a code for it, 403, forbidden. GitHub doesn't use it here. When you ask about a private repo you're not allowed to see, it answers 404. That's on purpose. If it said "forbidden," anyone could poke at names and learn which private repos exist. So GitHub tells you nothing is there.
That's good security and a terrible clue. The error names the wrong problem. I was debugging whether something exists, and the real question was who was asking.
Every "nothing here" has an asker
Once I saw it, I realized I'd been bitten by this same shape before, just less clearly. An empty search, an empty list, a 404. Each one feels like a fact about the world: there's nothing there. Really each one is a report from whoever did the looking. A search that comes back empty is only as good as the folder it searched and the words it searched for. A list that comes back empty is only as good as the account that asked for it.
Most of the time that difference doesn't matter, because the searcher is who you think it is. This case was the cleanest one I've hit where the searcher got swapped and nothing told me. The command looked the same. The job looked the same. Only the identity under it had changed, and the answer it gave sounded like a fact about the repo.
What I changed
Two things. First, before I decide a repo is gone, I check who I am. gh auth status tells you which login is active, and a quick look at whether GITHUB_TOKEN or GH_TOKEN is set tells you whether something has jumped ahead of it. That takes five seconds and would have saved me the rename hunt.
Second, the shared secrets file shouldn't hand out an identity just because you loaded it for something else. Keys that only open a service, like the storage key, are fine to share. A token that decides who you are is different. It should be something a job asks for by name, not something it picks up by accident.
So here's what I'd tell you. When something says "not found," ask who looked before you ask where it went.
References: the gh environment variables page, which explains how GH_TOKEN and GITHUB_TOKEN take priority over your stored login.
Arthur Conan Doyle hung a whole case on a dog that didn't bark in the night. Holmes's point was never the silence. It was that the silence told you who had come to the door.