Introducing Ramune, a task graph for coding agents
Ramune assigns work to multiple coding agents and serializes the integration of verified changes.
- Coding Agents
- MCP
- Git
- TypeScript
webapp-blueprint · Ramune
Language: English
Notes from the work.
Ramune assigns work to multiple coding agents and serializes the integration of verified changes.
webapp-blueprint · Ramune
An introduction to webapp-blueprint, a project template for starting web application development with coding agents.
webapp-blueprint · Ramune
Tracing why the BFF layer emerged as a frontend-owned tier: from clients calling backend services directly, through the Gateway pattern, to how responsibilities divide across frontend, BFF, and backend.
Audit success events were being dropped by production log-level settings yet still counted as delivered. This post covers fixing that with the outbox pattern and separate verification paths, so failures of the observability machinery itself become detectable too.
Cloud Run falls back to the previous revision when a new one fails to start, yet gcloud run deploy still exits successfully — so CI stays green while traffic never switches. Fixed by pinning revision suffixes, verifying the created revision, and routing traffic explicitly with update-traffic.
When implementing screen update notifications with AWS AppSync Events, we chose a design where events act purely as signals triggering refetches instead of carrying state. This article explains why, how consistency is preserved with the database as the source of truth, and how to combine it with the outbox pattern.
Porting an AI generation workflow surfaced environment-side problems with no counterpart in the source code: a WIF attribute condition rejecting every token, OOM kills, internal ingress blocking Cloud Run-to-Cloud Run calls, and ffmpeg missing from the image.
How I cut the wait for all required checks on a pull request from 14 minutes 12 seconds to 3 minutes 54 seconds, through test selection based on changed files, splitting coverage jobs, and removing inter-job dependencies.
Runtime-evaluated feature flags leave OFF-branch code inside the build artifacts. This article describes fixing that by pinning flags at build time so dead code elimination removes them physically, and verifying removal in CI with marker checks.
Two update paths, gcloud run jobs update and Terraform apply, shared one Cloud Run job: plan diffs regenerated on every apply and etag conflicts failed the DB deploy workflow. Giving each attribute a single owner ended both problems.
Returning authorization results as booleans erases what was authorized from downstream types. This post combines spec kinds, conditional types, and branded types so the fact of authorization travels as a value all the way into service signatures.
AnnotationView carried decisions like claimable checks and tutorial display logic alongside its rendering; moving them into pure functions on the model side, spread across nearly 40 PRs, made everything far easier to test.
Replaced buildx --load into the Docker daemon followed by docker push with a direct push to the registry, cutting the dev CD pipeline by 46%; layer caching and removing a wasteful Dockerfile copy shaved the build further.
Sensitive reveal endpoints used to return emails after firing a single audit log line. This post covers gating the response on an outbox commit instead, typed audit payloads that structurally exclude personal data, and diagnostics for the failure path.
Cloud Trace showed a 304ms API whose SELECT ran in 3.6ms—the real cost was a 217ms external lookup triggered by checkRevoked. This is a record of moving revocation decisions into the app's own DB and removing external I/O from the normal request path.
Log shaping and error conversion had scattered across every controller, service, and guard; consolidating them behind a global boundary in NestJS separates human-readable messages from machine-searchable structured fields.
While porting an AI generation pipeline to another workflow platform, several plausible-looking configuration values — thresholds, model names, external endpoint paths — turned out to diverge from the source system. A retrospective of those issues, along with the verification steps that would have caught them.
Merging to main fired distribution to Qiita and Zenn directly. This post covers gating publication behind a long-lived blog branch with a single PR, a status comment that sorts published posts from drafts, and a permanent draft canary that detects leaks.
Passing thirty days' worth of milliseconds to setInterval exceeded Node.js's TIMEOUT_MAX timer limit, and the delay silently became 1 millisecond. This post follows the process of spotting the anomaly from the log's abnormal frequency and landing on a fix that clamps at the boundary.
Preview environments that let reviewers exercise the real application on every pull request, built on a trusted workflow and Cloud Run tagged revisions, with a Lite/Full split depending on whether the change touches the database schema.
How we gave each production telemetry lane its own sink, retention, and IAM for governance, contained PII leaking to stdout, and added a CI ratchet that stops legacy logger usage from growing.
Promise.all inside a Prisma interactive transaction ran its queries serially until the tx timed out with P2028. Splitting into a tx per query restored parallelism, and two static analysis rules pointing in opposite directions now coexist to keep both mistakes out.
Rather than letting top-level features balloon, nest child features recursively inside their parents and enforce public-surface-only imports by inspecting the import graph with ts-morph in CI.
Hardening measures added in parallel around the same audit window: secretlint in pre-push, a single OAuth-based deletion request path, resolving a vulnerable transitive dependency, and making CI output fail-closed.
PostgreSQL was evaluating the RLS policy's authorization function once per row, so list queries slowed in proportion to row count. Changing the unit of evaluation from row to SQL statement removed the repetition and delivered a measured ~11x speedup.
Running Terraform plan on same-repo PRs hands cloud read permissions to untrusted input. This post traces how a plan-commenting workflow hardened its boundary, starting from emitting nothing sensitive and widening what may be shown stage by stage.
An approach to performance work that skips upfront hypotheses about what to fix: turn anomalies found in logs and traces into findings, hypothesize causes, then fix and re-measure. Shown through three real cases at different layers—Node timers, auth external lookups, RLS—together with whole-suite p50/p95 benchmark medians.
Choosing tRPC over GraphQL, gRPC, and ConnectRPC for a high-churn BFF layer, plus the reasoning behind keeping types in TypeScript rather than extracting them into a separate shared schema layer.
Instead of scattering authorization conditions across routes and services, this design expresses them as a typed catalog of action × subject × check. Unions and required-context types are derived from a single ACCESS_SPECS constant, so missing contexts surface as compile-time errors.
Splitting a six-root Terraform setup organized around a 1,500-line god module into domain-specific subsystems without recreating any production resource, relying on roughly 745 moved entries plus machine verification that plans stay no-change.
A retrospective on attending TSKaigi 2026 through student travel support, from TypeScript backends and type inference to sponsor booths, scholarship lunch, OST, and the party.
During a two-week internship in GMO Internet Group's ML/WEB course, I joined a five-person team building an MVP and took charge of the backend for an LLM chatbot. This is a retrospective on the requirements, technology choices, design decisions, failures, and lessons learned.