HARUMI
Back

2026 / 02

NOEMA — a reflective life system

Personal production systemSole developer and operator

OutcomeShipped a private journaling system with its own identity model, and kept the protected branch protected while working around an organization-boundary constraint.

Overview

A private journaling and reflection system: daily entries, long-term milestones and life phases, each account's records fully isolated behind an identity model built for one person's most private data.

Context

A place to record what actually happened on a given day and look back across months — which only works if the person writing it never has to wonder who else can read it. That requirement drives the identity model: self-serve accounts, an echo-key recovery path that is deliberately not a second login factor, optional passkeys, and every record scoped to one account.

System

Browser to Two-step auth to Next.js to PostgreSQLBrowserTwo-step authNext.jsPostgreSQL

Problem

Deploying a routine change hit a wall: the project's protected main branch only allows Maintainers to push, the only Maintainer was the CI bot account, and the human admin account couldn't be added as a member because GitLab 18's Organizations feature put the bot and the admin in different organizations — cross-org membership is refused outright.

Investigation

Initial hypothesis

The administrator could simply be added as a Maintainer.

Push to a feature branch as the admin (non-protected branches work fine), then drive the merge programmatically as the bot through the in-cluster gitlab-rails console: create the merge request as the bot user, force-check mergeability (it's computed asynchronously so it has to be polled), then merge once GitLab reports it mergeable.

Evidence

merge_request.check_mergeability
# poll until merge_status permits merge

GitLab 18 refused cross-organization membership; only the CI bot could merge to protected main.

Decision

Script bot-owned merge requests and poll GitLab’s asynchronous mergeability result.

Result

A repeatable, scripted procedure instead of a one-off workaround — the same shape now covers any repo hitting the same organization-isolation wall, without weakening branch protection or granting the admin account Maintainer access it structurally can't have.

What I would change

Current limitation: This solved the immediate migration constraint, but it was not treated as the desired long-term operating model. The scripted path runs through an in-cluster administrative console, is scoped to this one repository, and leaves the merge request itself as the audit record — a bot-authored MR is still a reviewable artifact, not a silent direct push.

Next step: Remove the special path entirely once organization membership semantics allow the administrator to hold a normal Maintainer role. The workaround should not outlive the constraint that created it.

Stack

Next.js 14 · Prisma · PostgreSQL · Redis · GitLab CI · ArgoCD

Next project

Running the full Camunda 8.8 stack