1. Finding the Wall
I was trying to call the GitHub API from within an AI chat session when it happened. The connection failed. Network restrictions. api.github.com was blocked.
My first instinct was to file it under "things that can't be done." But a different question surfaced almost immediately: what about github.com itself — the git protocol? I tried it. It worked. git clone, git push, git pull — all of it, without issue.
That asymmetry — API blocked, git open — determined everything that followed.
2. Mapping the Terrain
Once the boundary was clear, the picture snapped into focus:
✅ What works:github.com(git clone / push / pull)
❌ What doesn't:api.github.com(REST API / GraphQL / Projects API)
Without direct API access, there's no way to manage GitHub Projects, no way to update task statuses, no way to create issues. It looks like a dead end — until you remember that GitHub has a mechanism that listens for pushes and runs arbitrary scripts in response. GitHub Actions. And Actions can reach the API.
AI chat → git push → Actions trigger → API call → write back to private repo → AI chat → git pull
If the AI chat can't reach the API, hand off to something that can. A public repository becomes the bridge.
3. The Full Architecture
The system runs on two repositories: a public one that acts as the engine, and a private one that holds the memory.
Public repo (engine)
· GitHub Actions workflow definitions
·agent/request.json— where the AI writes its instructions
· Triggers on every push; bridges to the API
Private repo (memory)
· Daily logs, project cache, skill definitions
· Actions write here; AI chat reads via git pull
· The personal brain, invisible to the outside
When the AI needs to do something, it writes a JSON instruction to agent/request.json and pushes. That push triggers Actions. Actions call the API and write the result back to the private repository. The AI pulls and has its answer.
The API is never reached directly. But everything it offers is fully available.
4. The Request-Response Pattern
The instructions the AI writes are simple JSON:
{"action": "fetch_project", "payload": {}}
{"action": "update_task", "payload": {"updates": [{"task_id": "xxx", "new_status": "Done"}]}}
{"action": "write_memory", "payload": {"path": "daily/2026-03-26.md", "content": "..."}}
The Actions workflow reads the action field and branches accordingly — fetching project data, updating task statuses, writing files, creating issues. Each maps directly to an API call the AI chat couldn't make on its own.
To ensure every push triggers a fresh workflow run, a timestamp is automatically added to request.json. Even identical instructions produce a file diff, so Actions always fires.
5. Why Public and Private Do Different Jobs
The split between public and private isn't just about visibility. It solves two problems at once.
GitHub Actions runs without limit — and for free — on public repositories. Private repositories have a monthly cap. So the engine lives in public. The memory, on the other hand — daily logs, project state, personal skill definitions — shouldn't be visible to the world. So it lives in private.
Cost optimization and privacy protection fall out of the same decision. A structure born from constraint accidentally produced the ideal division of responsibility.
6. The Strength of Being Asynchronous
This architecture is asynchronous. The AI pushes, Actions processes, the AI pulls. Nothing is real-time.
That's not a weakness. Most daily work — updating a task, saving a log, checking project status — doesn't require instant results. What it requires is reliability and continuity. The async gap is measured in seconds to a minute; the reliability is structural.
Because it's async, processing continues even after the AI session ends. If the network hiccups, as long as the push gets through, Actions will finish the job. Fewer single points of failure. Automatic recovery. The system runs itself.
7. Memory That Accumulates
The most valuable thing this system does is externalize memory. An AI chat has no memory between sessions by default. But if you pull from a private repository at the start of each session, all prior context becomes available instantly.
Read the daily log, read the project cache, and you can pick up exactly where you left off — not because the AI remembers, but because git does. The memory lives outside the model and accumulates with every session. The more you use it, the richer the context becomes. It doesn't wear out. It grows.
Tools wear out. Infrastructure grows.
8. Constraints Ask the Right Questions
"It can't be done" is a starting point, not an ending point. Understanding why something can't be done reveals exactly what the system does and doesn't allow. That boundary, mapped precisely, is where the design begins.
API blocked — use git. Only git works — use it as a trigger. Trigger it — let Actions do the API work on the other side. Each question opens the next one, and the detour becomes the main road.
The difference between a wall and a design element is perspective. Seen as an obstacle, a constraint produces resignation. Seen as terrain, it produces architecture. What I found in this project wasn't a clever hack. It was a reminder that the shape of a limitation is also the shape of the solution.
If api.github.com won't connect, route through github.com. That single line of reasoning built a self-running GitHub ecosystem at zero cost.
TokiStorage is a project dedicated to preserving voice, image, and text for 1,000 years — the democratization of proof of existence. The system described in this essay runs on TokiStorage's own infrastructure.
Discover TokiStorage Read all essays