oharu tech blog

Articles

  • Per-article Open Graph cards in Astro with Satori — CJK fonts and X's title overlay

    I saw a Qiita article shared on X, and its preview card had Qiita's logo and the article's title drawn into the picture. Links to this blog showed only a cover image, which looked plain beside it. Covers here come from a shared registry keyed by topic, so every Astro article unfurled as the same black Astro logo. When I built that registry I decided the cover could serve as the Open Graph image directly, and wrote that I had budgeted for Satori and didn't need it. Every article now gets its own…

    Read more
  • Astro article links that show their site's brand icon — a rehype plugin and three traps

    GitHub renders a link to a pull request as the pull request icon followed by its title and number, and Confluence turns a pasted link into a small card for the page it points at. On this blog every link was the same blue underline, so a list of references mixing GitHub issues, MDN pages and vendor docs read as one column of identical text, and I wondered why it could not look like GitHub's. I added a build-time rehype plugin that puts the destination's brand mark in front of links to the sites…

    Read more
  • Measuring TypeSafe's Jev before wiring it in — it can tag an article, but not judge a translation

    I had heard that TypeSafe's Jev could sit between Claude Code and its tools and pick which ones to use, and I wanted to know whether it had a place in this blog's pipeline. Jev returns no text, only a probability per question, and the costliest judgment here is an Opus agent reading every translation for sentences that sound translated. So I measured Jev against labels on two candidate jobs before wiring it into anything. On picking an article's tags it scored AUC 0.97 and its probabilities…

    Read more
  • Terraform rebuilds a console-built AWS account from prod — read-only spec, parity diff, GitHub OIDC

    Every resource in a production AWS data layer I work on had been built by hand in the console: S3 buckets, Glue tables, an OpenSearch Serverless collection, two Bedrock knowledge bases, a Lambda, and an AgentCore gateway and code interpreter. Nothing described any of it, so its configuration was hard to copy into another environment. Then a test account was added, for testing new features before they reach production. It already ran the main application's stack, and its data layer was empty. I…

    Read more
  • pnpm 12's version pin outgrew Corepack — packageManager, devEngines, and a lockfile GitHub could not read

    This blog ran pnpm 11.3.0, and moving it to pnpm 12 looked like a one-line change to the packageManager field in package.json. The install finished in 26ms and reported Already up to date, yet pnpm-lock.yaml had grown by 158 lines. Those lines are a new YAML document that pins pnpm itself, and pnpm 12 puts it first in the file, pushing the dependency records into a second document. GitHub's dependency graph reads only the first document, so it would have seen pnpm and no dependencies, and this…

    Read more
  • Connecting Claude Code to a Cognito MCP server — a pre-registered client ID, or headersHelper

    I had an MCP server running on Bedrock AgentCore Runtime, with Amazon Cognito handling inbound auth, and wanted to register it in Claude Code so that /mcp → Authenticate would sign me in through the browser. The plain claude mcp add stops before any browser opens, with Incompatible auth server: does not support dynamic client registration. Pasting a Cognito access token in as a header connects, until the token expires (one hour by default) and the server comes back as Token has expired. Claude…

    Read more
  • Bedrock structured outputs stop at Claude 4.6 — a prompt rule and error feedback for Sonnet 5

    A document translation pipeline I work on started failing batches with ValueError: 応答要素の形式が不正: ['id', 'text']: a response element with the wrong keys. Claude Sonnet 5 was forced to answer through a tool whose schema asks for {id, translated_text}, and on some calls it named every key text instead, copying the input. Strict tool use exists to make that impossible, and Amazon Bedrock rejects it for Sonnet 5 and every Claude model after Opus 4.6. A one-line prompt rule kept the JSON valid, backed…

    Read more
  • Two green GitHub pull requests broke main — require branches to be up to date before merging

    I merge a pull request once every check on it is green. So it was a surprise when one of my pull requests failed CI on a test file it never touched. The failure was not mine at all. Main itself had gone red right after another pull request merged with every check passing, so every open pull request was now red for a reason outside it. The broken main was also hiding a real bug that no test had run against yet. The checks on the merged pull request were not wrong, only old. They had run before a…

    Read more
Load more