Why I moved formseal to a GitHub organisation
At first, formseal lived entirely under my personal GitHub account. That worked when it was just one project. Then it became three, and eventually I realized I wasn't maintaining a single repository anymore - I was maintaining a small ecosystem: formseal-embed, formseal-fetch, and formseal-decrypt, each with a separate responsibility, each evolving independently. My personal account stopped making sense as the home for all of it.
So I moved everything into a GitHub organization.
This post isn't a dramatic "startup journey" story. It's mostly about architecture, naming mistakes, release pipelines, and realizing that infrastructure projects need a different kind of structure than regular side projects.
Why the personal account stopped making sense
The first problem was identity. A repo under a personal account tends to read as "random side project," even if the code is serious. Once the tools became interconnected I wanted a shared identity, shared documentation, and a single place for releases and references. An organization solved that naturally.
The bigger realization, though, was about what formseal actually is. My mental model kept shifting:
- First: "formseal is the CLI"
- Then: "formseal is the pipeline"
- Eventually: "formseal is really just a payload format and a workflow"
The tools are reference implementations. The actual system is:
Once I framed it that way, keeping everything tied to a personal profile felt wrong. After moving to the org, the structure became:
useFormseal/
├── embed
├── fetch
├── decrypt
├── inbox (archived)
└── .github
Each repo has a focused purpose, isolated releases, and clearer issue boundaries. It went from "one developer account with several random repos" to "one system with separate components." That distinction matters more than it sounds.
The naming problem
The migration exposed something I hadn't fully reckoned with: naming mistakes compound over time.
The biggest example was formseal-inbox. I imagined the decryptor becoming a sort of terminal inbox - messages, viewing, maybe a TUI. That never happened because it was never the right idea. The tool's actual job was always just:
ciphertext → structured output
But the name kept me entertaining features that had no business being in a decryption tool. I eventually renamed it to formseal-decrypt (fsd), and that one change clarified the architecture more than any amount of feature work did.
[!NOTE] A bad name quietly creates bad scope.
inboxvsdecryptchanged what features felt justified and what didn't.
The PyPI issue
I'd already published formseal-inbox on PyPI before I realized package names are permanent - you can't just rename them. Deleting the package was off the table; that breaks old installs, creates naming holes, and removes history. So instead:
- Keep
formseal-inbox, mark it deprecated - Archive the repo
- Create
formseal-decryptand move forward cleanly
Infrastructure tooling should preserve history. The deprecated package stays up, it just points people elsewhere.
Migrating GitHub Actions
The org move broke publishing workflows in a way that's easy to miss. GitHub Actions + PyPI trusted publishing are tied to a specific owner/repository/workflow path, so once ownership changes, old trusted publishers stop working and publishing fails silently. I had to update the trusted publisher config, re-point PyPI to the org, and verify OIDC permissions were still intact.
If you're moving repos to an org and you use PyPI trusted publishing, update the trusted publisher config before you transfer - not after. Publishing will fail silently otherwise.
The actual repo transfer was easier than expected - GitHub preserves stars, issues, PRs, and sets up redirects automatically. It was the CI/CD side that needed careful attention.
Why I didn't build a full UI
During all this I kept circling back to one question: should the decryptor have an inbox-style TUI or dashboard? It sounded cool. Then I realized it completely conflicted with the philosophy of the system.
The pipeline already composes naturally with existing tools:
fsd > data.jsonl
fsd --format csv > data.csv
Open the CSV in Excel, pipe JSONL into jq, automate with cron - formseal doesn't need to own any of that. The moment it tries to, it also has to own the trust assumptions that come with it. The decryptor's job is decrypt and output structured data. Nothing else.
The flexibility question
One thing I kept second-guessing during the migration was whether I'd given developers too much freedom. formseal is intentionally flexible - you can use your own backend, write your own fetcher, bypass the CLI entirely. At first that worried me.
But the real issue wasn't flexibility. It was whether the core contract was clearly defined. As long as the payload structure, metadata format, and decryption output stay stable, flexibility at the edges is fine. The contract is the thing that needs to be locked down, not the tooling around it.
What the org actually represents
The organization isn't a startup, a company, or a big team. Right now it's literally just me. But creating it changed the framing of the project in ways that were probably overdue - it forced me to think seriously about long-term structure, release consistency, naming stability, and the difference between a specification and an implementation.
The ecosystem currently looks like this:
| Tool | Responsibility |
|---|---|
| formseal-embed | browser-side encryption |
| formseal-fetch | fetch ciphertexts |
| formseal-decrypt | decrypt locally |
That's enough. The goal was never to build a platform or a hosted service. It was encrypted form handling with minimal trust assumptions - and weirdly, moving to an org clarified that more than any feature work did.