Preparing today's journal

Please wait a moment.

Back to stories

Opening the Production Domain Began Behind the Screen

Why we checked database approval, authentication boundaries, background workers, and dependency recovery before the visible launch of a new production address.

Read like a book
Normal
A calm operations workbench with a key for opening a new door beside a database ledger, authentication shield, worker clock, and blank checklist

Topic

Haru Space Lab

Opening the Production Domain Began Behind the Screen

Why we checked database approval, authentication boundaries, background workers, and dependency recovery before the visible launch of a new production address.

Summary

Summary

  1. We moved database changes that had quietly run during deployment into a flow of reviewed files, change fingerprints, and human approval.
  2. We separated platform authority from private group membership and strengthened public authentication abuse controls and account lifecycle rules.
  3. We verified not only the domain and certificates, but also scheduled calls, installed runners, repository delivery, and public sites as one complete flow.
12Page
A calm operations workbench with a key for opening a new door beside a database ledger, authentication shield, worker clock, and blank checklist

Summary

At a glance

  • We moved database changes that had quietly run during deployment into a flow of reviewed files, change fingerprints, and human approval.
  • We separated platform authority from private group membership and strengthened public authentication abuse controls and account lifecycle rules.
  • We verified not only the domain and certificates, but also scheduled calls, installed runners, repository delivery, and public sites as one complete flow.

This retrospective reconstructs August 1–2, 2026 from design documents, Git history, and operational incident records. It omits defensive settings that could be misused, internal addresses, account and group information, secrets, and private conversations.

On the day the new production domain was connected, the most visible change was in the address bar. A memorable service address replaced the old deployment address, and the public sites gathered under the same name.

Most of the actual work, however, had nothing to do with the logo or the first screen. We spent it checking when the database could change, what a platform administrator could see, whether scheduled calls and installed runners followed the new address, and who could approve which scope when an external package was needed.

At first, I thought of the domain switch as a deployment task. By the end, it felt more like a test of the entire operating system around the product.

Opening a production domain was not about hanging a door for people to enter. It was about proving that the data, permissions, and background work behind that door all followed the same rules.

The database was the first thing we checked

At the time, Haru Space still had code in several places that checked for required tables or columns during a server request and created them when they were missing. That had been convenient in a small proof of concept. Deploying a new feature naturally prepared the structure it needed.

In production, the same behavior meant something else. A code deployment could exercise database-change authority without giving a person a clear place to review and approve the change. If several serverless instances started together, the same structure checks could repeat and introduce lock or cold-start cost.

We moved database changes from a side effect of code execution into explicit operational artifacts.

  • A change is delivered only through versioned files and a machine-readable description in the repository.
  • The approval scope is bound to an exact source revision and change-file fingerprint.
  • If the content or source revision changes, the previous approval is not reused.
  • The work card shows impact and verification results without exposing connection details or secrets.
  • Application, verification, merge, and deployment remain distinct internal records, while the person evaluates one fixed overall scope.

We also kept the initial automated scope narrow and additive. Changes that were hard to reverse, altered the meaning of existing data, or affected permission and security policy did not enter the same automated flow. We preferred to create a period in which the new structure and application code could safely coexist, then handle riskier transitions as separate work.

While building that flow, serverless packaging failed even though local verification passed. A parser asset available in the local environment did not arrive in the deployment artifact in the expected form. Only after replacing the path-dependent setup with a runtime the build system could trace did the production function stabilize.

It was our first signal that “the build passed” and “the serverless function can actually run” were different checks.

Even the highest platform administrator was not automatically a group member

The next thing we corrected was the meaning of authority.

A platform administrator needs to inspect infrastructure and global settings. That does not mean the role should automatically see every private group’s chat, documents, and activity. If platform operations and group participation live inside the same permission, administrative convenience becomes excessive data access.

We fixed the following rules in one central policy.

  • Platform authority does not automatically grant group membership.
  • Private content rechecks whether the person is a currently active group member.
  • Only a current administrator of a group may change that group’s settings.
  • An inactive or departed membership no longer justifies content access, regardless of a former role.

We reviewed the APIs against the same rules. Automated checks asked whether each route required authentication and, if it was a public exception, why that exception existed. The public home and legal pages could be open while groups, chats, jobs, and operational data remained behind sign-in and membership boundaries.

The resulting operational record was not a surveillance log that copied everything someone read. It connected state changes across work, approval, repository, database, and deployment in chronological order while excluding prompts, tokens, user-authored text, and connection fingerprints. We wanted explainability without collecting more private data for the sake of explaining the system.

A public address also brought authentication abuse

Once the service had a public address, login and signup were no longer internal test features. They were entrances exposed to the internet.

We added defenses against repeated login attempts and automated account creation. At the same time, we did not want those defenses to retain original network addresses for long periods or lock legitimate users out forever.

  • Repeated failures received a temporary restriction that expired.
  • Signup sources were compared only through short-lived, irreversible records derived with a server-held key.
  • Old attempt records were not retained indefinitely.
  • Accounts with any group participation history were conservatively excluded from automatic cleanup.
  • An operator could pause new signup without disturbing existing login and group participation state.

The important part was separating authentication-defense state from account state. A series of wrong passwords did not change a person’s group approval or departure history. A lock was a lock, and membership was membership.

Changing one address revealed every hidden caller

After the production address changed, the first page opened successfully in a browser. That was not the end.

The scheduler, installed AI runner, repository-delivery process, sign-in return flow, web push, public-site canonical metadata, and external request boundaries could all still remember an earlier address. Some behaved like browsers and followed redirects. Other server clients deliberately refused redirects as a security rule.

We therefore verified the transition in dependency order.

  1. Confirm that DNS and certificates point to the new address correctly.
  2. Confirm that an unregistered public host does not accidentally open the main application.
  3. Confirm that login sessions are not shared with public subdomains.
  4. Confirm that scheduled calls and runner registration authenticate at the new address.
  5. Complete one real cycle of code work and repository delivery.
  6. Confirm that public-site search metadata and external connection boundaries resolve to a single canonical address.

An address change became an effective test for hidden dependencies. If we changed only the links people could see and missed background callers, the site could look healthy while scheduled and development work quietly stopped.

A worker marked “running” was actually duplicated

The domain transition also exposed a restart problem in the installed bridge. We stopped and restarted a scheduled task, but a child execution process could remain after its supervising parent had ended. A new supervisor started, then collided with the old instance and repeated retries.

The scheduler’s “running” label did not prove how many application instances were really alive.

Recovery did not mean terminating every process of the same general kind. We matched the exact execution target and parent relationship, then cleaned up only orphaned instances whose owner had disappeared. If a valid supervisor already existed, a duplicate startup stopped immediately. If the process relationship could not be inspected, the existing single-instance lock remained as the final defense.

Again, relationships mattered more than a status label. We needed to observe the scheduled task, supervisor, actual worker, and last healthy heartbeat separately.

The schedule succeeded, but the AI work did not finish

Around the same time, one scheduled content job failed. Its message appeared on time, and automatic approval worked. The installed runner claimed the job. The failure came later.

Research, images, three-language drafts, and verification had all been combined into one request, pushing it beyond the execution limit. Some files remained in the isolated workspace, but they were not delivered as a completed result.

We did not commit or publish the partial output automatically. We adjusted the limit within a bounded range, but work that repeatedly approached it would be split by article or deliverable. The distinction between scheduler success and AI-job success also had to be visible.

One early stage succeeding should never hide a later failure. This became a recurring principle in Haru Space operations.

Receiving dependencies without opening the internet

AI work that needed an external package tested the same boundary. Giving the AI execution environment general network access would make implementation easier. It would also open arbitrary downloads, supply-chain attacks, internal-network access, and credential-leak risks.

We created structured dependency approval instead of general internet access.

When existing code could not solve the task, the AI requested an exact package, fixed version, and purpose. A person reviewed that target in the work view. Only an approved request reached a restricted installer using an official supply path, with installation scripts disabled and checks on changed files and high-risk vulnerabilities. If it succeeded, the original request continued in the same isolated workspace and work context.

In the first production attempt, the package manager itself was treated like a project dependency, and restoration did not finish within its limit. We separated tool restoration from adding a project package and allowed bounded restoration only when the repository’s declared version and lockfile agreed.

We could classify the failure more precisely without weakening the security boundary.

A checklist for the day operations begin

If I repeated those two days, I would check the following before opening the screen.

1. Is a data change approved together with its source revision?

Do not execute silent DDL during a request. Bind the reviewed change files, impact summary, fingerprint, and execution record.

2. Are platform authority and content authority separate?

Operating the infrastructure should not, by itself, grant access to every private group.

3. Have we found every hidden consumer of the public address?

Check scheduled calls, sign-in returns, runners, webhooks, search metadata, and public-site connections—not only browser links.

4. Does process status prove there is exactly one live worker?

Observe the scheduler label, parent and child processes, readiness, and last successful job independently.

5. Can success in an early stage be mistaken for overall success?

Separate scheduling, AI execution, repository delivery, merge, and deployment. Do not publish a partial result as complete.

6. Does a dependency exception become general network authority?

Use an exact target, one-time approval, a restricted installer, and vulnerability checks.

Operations began before the page opened

It was genuinely exciting to see the new address respond and the first page appear. But a browser screenshot was not our definition of done that day.

The database change had to match its approved source revision. Group permissions had to be checked again. Scheduled calls and runners had to complete one real flow at the new address. A failed job could not spread partial output. Public release and monetization also remained behind separate doors for rights, legal notice, and human review, even when the technical switches were ready.

The production domain did not complete the service for us. It revealed, all at once, whether the boundaries we had built separately were truly connected.

The address bar was the last visible result. Operations had begun earlier, when we rechecked every relationship behind the screen.

Continue reading

Previous story · Next story

Previous storyBeyond One Repository: How Each Group Came to Own Its ProjectNext story What Must an AI Job Preserve So It Can Resume?