The easiest Farstax workspace to make special was our own.
It runs Farstax itself. We know the server. We know the application. We know why the odd files are there and which pieces were temporary. If something gets in the way, we are the people most able to reach around the product and tidy it up by hand.
So we gave ourselves a rule: do not.
Our production workspace had to converge onto the same supported paths we expect a normal customer workspace to use.
That turned out to be much more useful than another clean installation test.
Our own workspace was carrying the product's history
A new workspace starts from today's model.
Ours did not.
The permanent workspace address still pointed at the original hello-world scaffold. The real Farstax application was separately serving farstax.com. That domain pre-dated the newer application-aware custom-domain state. Cloudflare was proxying it, which meant the first version of our domain verifier could not see the origin in the simple way it expected.
The GitHub App private key was another piece of history. Farstax needed a multiline PEM credential before the product had a standard way to manage file-backed application secrets, so production used a temporary bridge to get the key into the application safely.
None of those choices was mysterious to us.
That familiarity was exactly what made them dangerous.
We could explain every exception well enough to keep it forever.
The point of dogfooding was to refuse the explanation
It is easy to say you use your own product when you log into the dashboard or run the software every day.
The harder version is letting the product's constraints apply to you when they are inconvenient.
For the Farstax workspace, that meant no direct database edits to make the new domain state look correct. No manual Caddy ownership as the final answer. No Farstax-specific code path. No ‘we know what this credential is, just leave the wrapper alone’ exception.
If the normal lifecycle could not express the migration, we treated that as a product gap rather than permission to bypass it.
That made our own workspace an unusually awkward customer.
Good.
The private key was the cleanest proof
We had already built the generic file-backed Application secrets path because multiline credentials are not a Farstax-specific problem.
Then we made Farstax consume it.
The existing GitHub App key was 1,674 bytes. The standard application-secret path wrote the managed file with exactly the same bytes and the same hash. The normal application loader supplied it to the Farstax process. After the change, the deployed application could still mint a GitHub App installation token and make a successful read-only GitHub API request.
Only after that proof did we remove the temporary startup wrapper and systemd credential bridge.
The key file did not disappear. It changed ownership: from migration residue we understood personally to a normal managed application secret the product understands mechanically.
That difference matters more than the number of files removed.
The domain refused to be as cooperative
farstax.com gave us a different kind of answer.
The new custom-domain model could adopt an existing application domain rather than asking us to remove a working route and add it back from scratch. That covered the actual shape of our production workspace.
But the first live adoption attempt stopped at DNS verification.
The domain is behind Cloudflare's proxy. Public DNS correctly returned Cloudflare edge addresses rather than the workspace origin address. Our verifier treated that as a mismatch.
We could have switched the record to DNS-only for the migration. We knew that would make the old check happy.
We did not want a product whose migration story was ‘temporarily change your CDN configuration because our verifier only understands one network shape’.
So that step stayed blocked while the generic verifier learnt how to prove a proxied domain safely.
Being our own customer did not mean forcing the dogfood exercise to pass. It meant letting our real setup disagree with the product.
Clean installs answer the easy half of the question
A clean install is valuable.
It proves we can create today's desired state from nothing.
Customers do not stay there. They accumulate repositories, credentials, domains, application data, old defaults and product decisions that were perfectly valid six releases ago. Then the product changes around them.
The harder question is whether we can bring that existing state forward without asking them to understand our architectural history.
Our own workspace compressed several of those problems into one place.
That made it a better test than a pristine demo machine.
Existing state is where product boundaries become real
A migration forces uncomfortable questions.
Who owns this route now?
Is this file still a supported credential or merely something the old deployment happened to leave behind?
Can the new model discover existing state, or does the user have to recreate it manually?
If verification is uncertain, do we preserve the working configuration or destroy it in the name of convergence?
Which compatibility layer is genuinely temporary, and what evidence lets us remove it?
Those are customer questions even when the customer never sees the underlying files.
They show up as trust: did my domain stay online, did my repository still authenticate, did my agent keep working, did the upgrade preserve the thing I had yesterday?
Dogfooding is not a shortcut to confidence
There is a slightly self-congratulatory version of dogfooding where using your own product is treated as proof that the product must be good.
I do not find that very useful.
We are unusually tolerant users. We know the terminology. We know where the logs are. We can distinguish a temporary migration seam from a permanent product feature because we built both of them.
That makes us poor representatives of a normal customer's patience.
The value comes from using our privileged knowledge in the opposite direction: to identify every place where we could take a shortcut, then deliberately ask whether the supported product path can do the job instead.
Sometimes it can.
Sometimes, like the proxied domain, it tells us the product still has something to learn.
I want our own workspace to become boring
The goal is not to make Farstax production a heroic test environment.
It is to make it uninteresting.
A standard application. Standard secrets. Standard domain ownership. Standard guarded releases. No route that survives only because we remember why it is there. No credential path that needs a paragraph beginning ‘for Farstax itself...’.
We are not there yet. The generic paths for retiring workspace-primary routing and verifying proxied custom domains now exist in the repository, but they still need to be deployed and proven on this production workspace.
That incompleteness is part of the lesson.
A clean install can show that the product knows how to begin.
Our awkward old workspace is teaching us whether it knows how to grow up.