フォトシンス エンジニアブログ

株式会社Photosynth のテックブログです

AWS CloudShell 「Error when retrieving credentials from container-role」エラー

この記事は Akerun - Qiita Advent Calendar 2025 - Qiita の18日目の記事です。

皆さんこんにちは。フォトシンス エンジニアの ps-k-itoh - Qiita です。
フォトシンスで SREチームとして、SRE / AWS インフラ周りを担当しています。

弊社の正式な会社名は「株式会社Photosynth」と英字表記です。
でもカタカナの方が分かりやすそうですし、いつもイベント参加などの申し込みフォームで、
英字で登録するかカタカナで登録するか悩みます。

さて今回はAWS関連の小ネタです。

CloudShell を使っているときの謎のエラー

ある日、AWS CloudShell でコマンドを一つ一つ実行していったのですが、
急にこんなエラーが出るようになり、コマンドをどう変更しても解消しません。

Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response 500 from container metadata: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>500 - Internal Server Error</title>
 </head>
 <body>
  <h1>500 - Internal Server Error</h1>
 </body>
</html>


解決策

調べてみるとこんな記事がありました。

今回は同時実行ではないですが、どうやら一定数以上のコマンドを実行すると発生する、認証情報の取得に失敗するエラーのようです。

対応法についても、記事をヒントに、 一度CloudShellのタブを閉じて、再度メニューから開き直し たところ、
事象が解消され、コマンドが実行できるようになりました。



以上です。
何かのお役に立てれば幸いです。

一緒にSRE施策や、AWS環境の改善、構築や運用を進めてくれる仲間を募集中です!
↓↓↓


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 photosynth.co.jp Akerunにご興味のある方はこちらから akerun.com

Jetson AGX Thor の初期設定

この記事は

Akerun - Qiita Advent Calendar 2025 - Qiita

の 20 日目の記事です。

daikw - Qiita です。 Physical と Photosynth (弊社) はなんとなくスペルが似ていますね。

最近サンタさんが Jetson AGX Thor を届けてくれたので、初期設定・動作確認時にやや戸惑ったポイントを書いておきます。

まとめ

  • Jetson AGX Thor の初期設定は USB インストールメディアを使うと便利かも
  • これで Physical AI に入門しよう!

前提

Jetson AGX Thor はつよつよエッジコンピュータです。つよめの CPU と GPU が載っています。快適です。

USB-C ポートが三箇所(5a, 5b, 8)にあって、用途が少しずつ違います。

Hardware Layout — Jetson AGX Thor Developer Kit - User Guide より

JetPack のインストール

最初に Thor に JetPack を入れます。

Quick Start Guide — Jetson AGX Thor Developer Kit - User Guide が丁寧に書かれているので、これに従えば良さそうです。

マクニカの記事も安心できる情報がありました。 5a, 5b どっちの USB-C 端子を電源に利用してもいいらしいです: Jetson AGX Thor 開発者キット入門:最短セットアップからAI推論の動作確認まで - 半導体事業 - マクニカ

ただ、僕の場合、ディスプレイがどうしても映らなくて困りました。

ディスプレイが映らないので、シリアルコンソールから操作する必要がありますが、工場出荷状態の最初のシリア ルコンソール(デバッグポートの方)は、全くインタラクティブな感じがしません。

最初のコンソール画面

操作にやや怖気付きながらも、 BSP Installation — Jetson AGX Thor Developer Kit - User Guide に従って用意した USB メディア経由の BSP インストールを試みます。

BSP インストール中 ...

完了後に再起動すると、デバッグポートから確認できるシリアルデバイスが4つああり、そのうち2つが接続できます。どれがどれだかわからないので全部接続して確かめます。

2 ❯ ll /dev/tty.* | grep usbmodem
crw-rw-rw-  1 root  wheel  0x900002a Dec 19 17:17 /dev/tty.usbmodemTOPOA735A12B2
crw-rw-rw-  1 root  wheel  0x9000028 Dec 19 17:17 /dev/tty.usbmodemTOPOA735A12B4
crw-rw-rw-  1 root  wheel  0x9000026 Dec 19 17:16 /dev/tty.usbmodemTOPOA735A12B6
crw-rw-rw-  1 root  wheel  0x9000024 Dec 19 17:16 /dev/tty.usbmodemTOPOA735A12B8

しばらく待つと、それらのポートからの出力に、以下のように指示がきました。うまく起動できているようです。

[   15.501295] Please complete NVIDIA OOBE on the serial port provided by Jetson's USB device mode connection. e.g. /dev/ttyACMx where x can 0, 1, 2 etc.

シリアルコンソール

この状態で、普通の USB-C ポート(5a or 5bの電源に使ってない方)に接続して見えたシリアルデバイスに接続すると、 Debconf らしき画面が見えます。

Debconf ?

パスワードやリージョンなどの設定を進めると、ログインできました。

ログインできた

シリアルコンソールでは鍵の設置だけ操作して(curl https://github.com/daikw.keys > .ssh/authorized_keys )、あとは手元の Mac から操作できる状態になりました。

環境を確認します。

daikw@jetson-thor01:~$ cat /etc/nv_tegra_release
# R38 (release), REVISION: 2.2, GCID: 42205042, BOARD: generic, EABI: aarch64, DATE: Thu Sep 25 22:47:11 UTC 2025
# KERNEL_VARIANT: oot
TARGET_USERSPACE_LIB_DIR=nvidia
TARGET_USERSPACE_LIB_DIR_PATH=usr/lib/aarch64-linux-gnu/nvidia
INSTALL_TYPE=
daikw@jetson-thor01:~$ nvidia-smi
Fri Dec 19 00:34:59 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.00                 Driver Version: 580.00         CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA Thor                    Off |   00000000:01:00.0 Off |                  N/A |
| N/A   N/A  N/A             N/A  /  N/A  | Not Supported          |      0%      Default |
|                                         |                        |             Disabled |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A           10633      G   /usr/lib/xorg/Xorg                        0MiB |
|    0   N/A  N/A           10714      G   /usr/bin/gnome-shell                      0MiB |
+-----------------------------------------------------------------------------------------+

問題なさそうです。

SDK Manager に振り回されることもなく、特に迷わずにここまで来れたので、インストールメディアとデバッグポートによる初期設定はとても便利でした。

適当なコンテナの起動

Docker Setup — Jetson AGX Thor Developer Kit - User Guide に記載のある jetson-containers を試してみます。

dusty-nv/jetson-containers: Machine Learning Containers for NVIDIA Jetson and JetPack-L4T に従ってインストールします。

# add to docker group
sudo usermod -aG docker $USER
newgrp docker

# install the container tools
git clone https://github.com/dusty-nv/jetson-containers
bash jetson-containers/install.sh

適当に pytorch を試してみると、 jupyter が起動しました。便利ですね。

jetson-containers run $(autotag pytorch)
...
[I 2025-12-19 23:23:34.441 ServerApp] Serving notebooks from local directory: /
[I 2025-12-19 23:23:34.441 ServerApp] Jupyter Server 2.15.0 is running at:
[I 2025-12-19 23:23:34.441 ServerApp] http://jetson-thor01:8888/lab
[I 2025-12-19 23:23:34.441 ServerApp]     http://127.0.0.1:8888/lab
[I 2025-12-19 23:23:34.441 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 2025-12-19 23:23:34.444 ServerApp] No web browser found: Error('could not locate runnable browser').
[I 2025-12-19 23:23:34.455 ServerApp] Skipped non-installed server(s): bash-language-server, dockerfile-language-server-nodejs, javascript-typescript-langserver, jedi-language-server, julia-language-server, pyright, python-language-server, python-lsp-server, r-languageserver, sql-language-server, texlab, typescript-language-server, unified-language-server, vscode-css-languageserver-bin, vscode-html-languageserver-bin, vscode-json-languageserver-bin, yaml-language-server

JupyterLab server is now started

JupyterLab URL:   http://192.168.128.123:8888
JupyterLab logs:  /data/logs/jupyter.log


Copy the URL with the token above for the initial login or to reset your password.

autotag で互換性のあるコンテナを自動で指定できるのが素敵なポイントだと理解しました。

追記

tensorrt などを含む他のコンテナを試そうとしましたが、 r38 対応のコンテナがほとんどなくて自分でビルドする必要がありました。

しかし、 jetson-containers が依存している PyPI がずっと落ちていて、ずっとビルドエラー(タイムアウト)になります。同じような報告を数件見かけました。

Nuxt2/Vue2とReact v19が混在しても壊さない!段階移行のルールとVue→React Bridge

この記事は Akerun - Qiita Advent Calendar 2025 - Qiita の22日目の記事です。

こんにちは。@ps-shimizuです。バックエンドシステムの開発やプロジェクトマネージャーを担当しています。

先日、業務でVue.js / Nuxt.js を採用しているSPAのフロントエンド移行に取り組む機会がありました。 本記事ではSPA (Client-Side Rendering) を前提に、Nuxt2/Vue2とReact v19が混在しても壊れないようにするためのルール設計とVue→React Bridgeの運用ポイントをお話しします。

はじめに

Vue -> React.jsへの移行のきっかけはシンプルで、Vue.js / Nuxt.js のVer 2系がEOLを迎え、保守 (サポート・セキュリティ) の前提が崩れたためです。

「今のまま動いているからOK」では済まなくなりどこかのタイミングで移行が必要となるのですが、 問題は移行の間も機能開発と改善を止められないことです。

一気に作り直せるならそれがシンプルですが実際には機能追加や改善を止められないことが多く、移行は大抵既存開発と並走になります。

そこで「既存のVue (Nuxt) を動かしたまま、Reactコンポーネントを差し込んで置き換える」段階移行が選択肢に上がります。 便利な反面、無計画に始めるとReactがVueと依存してしまい、最後にVue/Nuxtを削除できない状態になることが予想されます。

この記事では、SPA 前提で、Vue/Nuxt と React が混在する期間を壊さずに進めるために、先に決めたこと (ルール・置き場所・Bridge運用) をまとめます。

留意事項

  • 本記事の対象はSPA (Client-Side Rendering)です。
  • 本記事で紹介する VueにReactをマウントして段階移行するアプローチは先行事例を参考にしています (「参考」セクション参照) 。
  • 記事内のコードやディレクトリ例は一般化して記載します。
  • 最終ゴールはVue.js / Nuxt.js を完全に削除して React.js に移行し切ることです。本記事は「移行途中を安全に成立させるための設計と運用」の記事です。

技術スタック

  • 既存: Nuxt.js 2 / Vue.js 2 / Vuetify 2
  • 移行先: React v19 / TypeScript

※ここでは読者のイメージ用に最低限だけ記載。細かい構成や設定値は伏せます。

検討した選択肢と、React + TypeScript を採用した理由

段階移行に入る前に、選択肢は複数ありました。

  • Vue/Vuetify/Nuxtをサポートバージョンまでアップグレードする
    • 既存資産を活かしやすい一方で、破壊的変更が多いと結局「広範囲の修正+検証」になりますし、ビッグバンリリースになりやすい
  • 別スタックで一から作り直す
    • 理想的だが、機能差分の埋め戻し・移行期間の二重運用が重くなりやすい
  • 既存を動かしたまま、段階的に置き換える(段階移行)
    • 日々の開発と並走しやすい反面、混在期間の設計を誤るとトラブルが発生しやすい

段階移行のメリット

段階移行を選ぶメリットは、「移行のためにプロダクト開発を止めない」以外にもいくつかあります。

  • リスクを分割できる
    • 置き換え対象を小さく切れるので、影響範囲が読みやすく切り戻しもしやすい
  • 学習コストを分散できる
    • いきなり全員が新スタックを習得する必要がなく、移行の進捗に合わせてチームの習熟を進められる
  • 検証コストを局所化できる
    • 「全部動くか」ではなく「この範囲が同じ体験を維持できるか」に検証を寄せられる
  • 移行の優先順位を柔軟に変えられる
    • 影響の小さい領域から進めたりボトルネックになっているUIだけ先に置き換える、といった調整が可能
  • 方針転換に強い (段階移行が頓挫しても資産を持ち運べる)
    • もし段階移行がリスク/課題で進めづらくなり「別スタックで一から作り直す」方針に切り替える場合でも、段階移行で作ったReactコンポーネントはほとんどが流用可能

React + Typescript を採用した理由

最終的に React + TypeScript を軸にしたのは、技術的優劣というより 学習コスト・採用・育成 の影響が大きかったです。

  • すでに React/TypeScript を使っているチーム・プロダクトが存在し、知見と人材が厚い
  • 新しいスタックを増やすより、社内の強みを使って 移行リスクと学習コストを下げられる
  • 長期的にも採用・育成・横断支援がしやすい

段階移行の全体像

ゴールは明確で「Vue/Nuxt を削除し、React を「正」にする」です。

ただし、段階移行では「移行途中」が危険です。経験上、よくありそうな失敗は次の3つかと思います。

  • 失敗1: 例外が増えて収拾がつかない
    • 「今だけ」「この画面だけ」の例外が積み上がり、境界が崩れる
  • 失敗2: ReactがVueの実装詳細に依存して、最後に消せない
    • React側がVueのstoreやプラグインに直接依存し始めると撤去が難しくなる
  • 失敗3: 置き場所が曖昧で、同じ概念が複数箇所に生える
    • 修正のたびに「どっちが正?」が発生する

この失敗を避けるために、コードを書く前に次の2つを先に決めました。

  • ディレクトリ戦略: どこに何を置くか
  • ルール: 依存方向と例外の運用

そして、どうしても必要になるのが Vue→React Bridge (Vue上にReactをマウントする仕組み) です。

ディレクトリ戦略

今回の移行をきっかけにディレクトリ構造のルールを明文化し、置き場所を固定しました。 混在期間に効果を実感したのは、この「置き場所の固定」です。

  • src/pages
    • Nuxtのページ置き場 (Vueの既存ページが中心)
    • 移行途中は一部にReactページが混在し得るが、ページとしての責務 (ルーティング・つなぎ込み) を固定する
  • src/app
    • React専用のページ/アプリ構造の置き場 (React側の“正”をここに作る)
  • src/shared
    • React専用の共用コンポーネント置き場
    • 複数のReactページ/機能で再利用するUIやスタイルなどを集約する

ここで重要なのは、「sharedは便利だから何でも置く」にならないことです。 sharedが何でも置ける場所になってしまうと、結局あとで分離できず、移行の最終盤で苦労することになります。

運用上は、置き場所の判断を以下のようにしました。

  • Reactのページ/アプリ構造として置くなら src/app
  • Reactの共用コンポーネントとして使い回すなら src/shared
  • Nuxtのページとしての責務 (ルーティング・画面のつなぎ込み) が中心なら src/pages, src/components

最後にVue/Nuxtを消すために依存方向のルールを決める

段階移行で最重要なのは依存方向です。原則は以下の一つです。

  • 旧 (Vue) →新 (React) は許容
  • 新 (React) →旧 (Vue) は原則禁止

このルールを破ると、移行の後半で「Reactを進めるほどVueが必要になる」状態となってしまい「移行が進むほど撤去が難しくなる」という最悪の形です。

例外を許すなら「期限」「撤去条件」「オーナー」をセットにする

現実には、どうしても例外が必要な瞬間がありますが、 そのときに「例外OK」で終わらせると例外が永続化します。

例外を許可する場合は、最低限以下をセットとしました。

  • 期限: いつまでに消すか
  • 撤去条件: 何が揃ったら消せるか
  • オーナー: 誰が最後まで責任を持つか

PRレビューのチェックリスト

  • 置き場所は妥当か (src/app/pages, src/shared のどこか)
  • 依存が逆流していないか (React→Vueになっていないか)
  • 移行後にも残る設計か (Vue->React.js移行の都合がReact本体に入り込んでいないか)

Vue→React Bridge (VueにReactをマウントして進める)

段階移行を「動く形」にするのが Bridge です。 考え方はシンプルで、Vue側に「Reactを描画するための器」を用意します。

最小構成のイメージ ReactWrapper

先行事例と同様、Vueコンポーネントmounted でReactをマウントし、$attrs をReactのpropsとして渡します。

例:

<template>
  <div ref="container" />
</template>

<script>
import { createElement } from 'react'
import { createRoot } from 'react-dom/client'

export default {
  inheritAttrs: false,
  props: { component: { type: Function, required: true } },
  data() { return { reactRoot: null } },
  mounted() {
    this.reactRoot = createRoot(this.$refs.container)
    this.reactRoot.render(createElement(this.component, this.$attrs))
  },
  watch: {
    $attrs: { deep: true, handler() {
      this.reactRoot.render(createElement(this.component, this.$attrs))
    }},
  },
  destroyed() { this.reactRoot?.unmount() },
}
</script>

ここまでなら「Vueのコンポーネントの中にReactが出る」だけですが、 本当に難しいのは運用で、次の2つがハマりどころになります。

ハマりどころ1 ルーティングと <a> の扱い

BridgeでマウントしたReact側が <a> で遷移すると、Vue側のルーティングに乗らず 全リロード になることがあります。 SPAでは体感が悪く、さらに「どの遷移が安全か」が曖昧になると事故が増えます。

回避としてはReact側に「遷移関数」をpropsで渡し、リンクはそれ経由で行うなどです。

詳細は先行事例がわかりやすいので、参考資料のリンク先をご覧ください。

ハマりどころ2 slot/children をどう渡すか

Vueのslot (子要素) をReactのchildrenとして渡したくなる場面があります。 ただ、Vueのslotは「ただのHTML」ではなくVue独自の表現です。

ここを雑にやると、React側にVueの都合が漏れてBridgeのボリュームが膨らみます。 先行事例では「静的HTML/文字列に制限する」「HTMLをJSXに変換する」などの工夫が紹介されていますが、どちらもトレードオフです。

段階移行を安全に回す観点では、最初から欲張らずに

  • childrenを必要としないコンポーネントから置き換える
  • childrenが必要な場合も、まずは静的な表現に制限する

のように「進め方で回避する」ほうが、結果として移行が止まりにくい印象でした。

Bridgeのボリュームを増やさないための運用ルール

Bridgeは便利なので何でも運べてしまうため、撤去時の作業ボリュームが膨らむのでBridge運用は次の方針としました。

  • propsは薄く (primitive中心)
  • 関数propsは最小限 (遷移など必要なものだけ)
  • Vue側の実装詳細 (store/プラグイン等) をReactへ漏らさない

置き換え順序

どこから置き換えるかで移行の難易度は変わりますので、大雑把には影響の小さいところから始めるのが安全です。

  • 影響が限定される領域 (例: ログイン後)
  • 画面遷移を伴わないUI (例: モーダル)
  • 影響が大きい領域 (公開・高トラフィック) は後回し

ここは「技術的にできるか」より「トラブルが発生した際に戻せるか」「ユーザー影響がどれくらいか」で優先順位を決めるほうが、結果として止まりにくい印象です。

テスト方針 (テスティングトロフィーに基づくテスト設計)

段階移行では「境界」が壊れやすいので、テストは闇雲に増やすのではなく、スティングトロフィーの考え方に寄せて設計しました。

テスト戦略の優先順位

        /\
       /  \  E2E (少数)
      /----\
     /      \  統合テスト (適度)
    /--------\
   /          \  機能テスト (重点) ← ここに注力
  /------------\
 /              \  単体テスト (実装詳細は除外)

React側のテスト実装には React Testing Library を利用していますが、方針としては「何をテストすべきか」をまず固定します。

機能面にフォーカス

  • テストすべきこと
  • テストすべきでないこと
    • CSSクラス名の付与確認
    • コンポーネントの内部状態 (外部から見えない部分)
    • 実装の詳細 (具体的なDOM構造など)
    • スタイリングの詳細

この前提を置いた上で、Bridgeを挟む境界 (props、遷移、イベント、エラー時) を優先して守るようにしています。

最後にVue/Nuxtを消すために

最終ゴールが「Vue/Nuxtを完全に削除する」以上、後半で撤去コストが膨らまないように、いまの時点で次を方針として決めています。

  • React側の「正」を src/app に寄せ続ける
  • 依存逆流を例外扱いにしない (例外は管理する)
  • Bridge撤去の完了条件 (チェック項目) を先に決めておく
    • Bridge経由の呼び出し箇所が0
    • 新旧依存が逆流していない
    • 代替のReact実装が揃っている

Bridgeは便利ですが最終的には消す対象です。

消せる形に保つためにディレクトリ戦略とルールを先に固定し、混在期間中も崩さないことが大切だと思っています。

まとめ

  • 段階移行の本質は「VueにReactをマウントする」ことより、最後にVue/Nuxtを削除できる設計を保つこと
  • そのために、まず ディレクトリとルールを決める
  • Vue→React Bridge は必要悪になりやすいので、「propsを薄く、関数を最小限、実装詳細を漏らさない」が重要

段階移行は「動くものを増やす」ほど、あとから保守対象のコード範囲も増えていきます。だからこそ実装前にディレクトリ戦略と依存ルールを先に決めておくと、混在期間中の迷いが減り、手戻りや撤去コストを小さく保ったまま移行を進めやすくなります。

参考

note.com

medium.com


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 photosynth.co.jp

Akerunにご興味のある方はこちらから akerun.com

AWS Control Tower でリージョン制限をしている環境で、Bedrock クロスリージョン(global)の推論プロファイルを使えるようにする

この記事は Akerun - Qiita Advent Calendar 2025 - Qiita の18日目の記事です。

皆さんこんにちは。フォトシンス エンジニアの ps-k-itoh - Qiita です。
フォトシンスで SREチームとして、SRE / AWS インフラ周りを担当しています。

1年間溜め込んだアウトプットのエナジーを、アドベントカレンダーの時期に一気に放出することに定評のある、
歳末大売り出し中な フォトシンス エンジニアブログ、
ここまで、SREチームの記事がなかったので、書きます。

Bedrock クロスリージョン(global)の推論プロファイルを使いたい

ある日、AI利用を推進する担当の部門からこんな問い合わせがありました。

「Claude Codeにて、最新モデル「Claude Opus 4.5」を使用しようとした際にSCP起因のエラーが発生しています。使えるようにできませんか?」

403 {"Message":"User: arn:aws:sts::xxxxxxxxxxxx:assumed-role/xxxxxxx/xxxxxx is not authorized to perform: bedrock:InvokeModel 
on resource: arn:aws:bedrock:::foundation-model/anthropic.claude-opus-4-5-20241201-v1:0 with an explicit deny in a service control policy"}

あー、Control Tower でリージョン制限しているからか。
といって、リージョン制限はセキュリティの観点から重要な設定なので外すわけにもいかず、何か回避方法あるかなと。

全体的なリージョン制限は維持しながら、Bedrockのクロスリージョン(グローバル)の推論プロファイルを使えるように

AWS公式のブログ記事を見つけました。

この記事の「オプション1」をもとに設定をしましたがうまくいかず、
いろいろと試行錯誤し、さらにAWSサポートへも問い合わせた結果、実現できました。
実施した設定を紹介します。

全リージョンControl Tower の管理対象内にし、「リージョン拒否コントロール」を無効化

私たちの環境では、元々「使ってよいリージョン以外のリージョンを Control Tower の管理対象外とする」ことで、リージョン制限を実現していました。
これを、一度すべて「管理対象」として登録し、「リージョン拒否コントロール」の無効化も行います。

まずは、AWS マネジメントコンソールの Control Tower のコンソールから「ランディングゾーン設定」を選択します。
「設定を変更する」ボタンをクリックします。

ランディングゾーン設定

設定のステップを進める中で「管理対象リージョン」を選択する箇所があるので、
全てのリージョンを選択して、管理対象とします。

追加リージョン

さらに、「リージョン拒否コントロール」を開き、「有効になっていません」を選択して次へ進みます。

リージョン拒否コントロール

そのまま設定を変更します。「ランディングゾーンの更新」ボタンをクリックしてランディングゾーンの更新も行います。

MULTISERVICE.PV.1 コントロールでリージョン制限する

Control Tower のコンソールから「Control Catalog」を選択します。
コントロールの検索フィールドに「MULTISERVICE.PV.1」と入力し、検索します。
表示された MULTISERVICE.PV.1 コントロールの名前のリンクをクリックします。

MULTISERVICEPV1

「コントロールを有効にする」ボタンをクリックします。

コントロールを有効にする

OUを選択するステップで、適用するOU(制限対象とするAWSアカウントが含まれるOU)を選択します。

OUを選択

リージョンアクセスを指定するステップで、利用を許可するリージョンを選択します。

利用を許可するリージョンを選択

サービスアクションを追加するステップで、NotActionsの追加フィールドに「bedrock:Invoke*」を入力し、追加します。

NotActions

そのままステップを進めて、コントロールを有効化します。

結果、エラーが解消された

以上の設定で、エラーが解消され、他リソース利用のリージョン制限についてもコントロールを用いて適用できました。

以上となります。
この記事が、何かのお役に立てれば幸いです。

フォトシンスのAWSマルチアカウントの管理、Control Tower や Organizations の運用には、 まだまだ改善の余地が多くあります。
プロダクトや組織の特性をふまえた、最適なマルチアカウント管理を目指し、日々楽しく取り組んでおります。


そんなわけで、一緒にAWS環境の改善、構築や運用を進めてくれる仲間を募集中です!
↓↓↓


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。
photosynth.co.jp

Akerunにご興味のある方はこちらから
akerun.com

AIは「便利ツール」から、チームのコミュニケーションを変え得る「通訳者(L8以上の層)」へ

この記事は Akerun Advent Calendar 2025 - Qiita の16日目の記事です。

こんにちは。Esperna - Qiita  です。 今年は仕事でもプライベートでも、AIに触れる時間が増えました。 一番変わったのは、開発の量やスピードではなく、AIとの向き合い方でした。 この記事では、私のAIとの向き合い方がこの1年でどう変わったかを、具体的な運用ルールと一緒に振り返ります。 (前提として、判断や責任をAIに委ねるのではなく、あくまで人間が握るつもりで運用しています。)

2025/5月:時間を短縮する「便利なツール」としてのAI

Cursorを導入した当初は、運用保守のプロジェクトでAIに単体テストを書かせていました。 モック作成、パラメタライズドテスト、細かいリファクタリング、コメントの英文化など面倒だけど必要な作業が短くなるのは素直にうれしかったです。 ただ、この時点ではまだ「便利なツール」でした。 便利さの次に来たのは、疑いの増加でした。 テストがFailしたときに、

  • 実装が間違っているのか
  • テストが間違っているのか
  • それとも両方とも間違っているのか

を疑うのと同じように、AIの出力に対しても同様の問いが増えました。 面白いのは、これは単に不安が増えたのではなく、考える幅が一段広がった感覚があったことです。自問自答はもともとしていましたが、AIが入ると、その自問が対話になり、思考が外に出やすくなりました。ここから、作業の手触りが変わり始めました。

2025/7月:AIを鵜呑みにしないための「運用」(ラベルとRules)

この頃、Linux / Node.js / Go といった技術スタック中心の開発から、Zephyr / C / 電子回路など、より低レイヤーのファームウェア開発にシフトしました。 それに伴い、習得すべき知識・スキルが増え、必要なインプット量も以前より格段に増えました。 最初はドキュメントを1つずつ読み込んでいましたが、そもそも一日に読める量には限界があります。 そこで、量の多いドキュメントは一旦NotebookLMに読み込ませて要約し、読むようにしました。 ここで私が意識したのは、要約を答えとして扱わないことです。少しでもわからない点や違和感があれば、納得いくまで質問します。結果として、少なくとも自分のケースでは理解に入るまでの時間が短くなり、考える幅も一段広がったように感じました。 一方で、AIを使う量が増えるほど「運用」が重要になります。 AIとのやり取りはMCPを使ってWikiやチケットにまとめるようにし、その際にAI出力であることを明示的にラベルするようにしました。さらに、AIの回答には確信度(Red/Yellow/Green)を出力してもらうようにしています。 これらは、AIがハルシネーションを起こし得る以上、読む側が鵜呑みにしないためです。 私の場合、次のようなサインが出たらそこで止めて、定義や根拠(一次情報)に戻るようにしています。

  • 根拠(一次情報の該当箇所)が示せない
  • 用語の定義が曖昧
  • 前後で主張が変わる

確信度はAIの自己申告であり、正しさの保証ではありません。むしろ「自信満々でも間違える」前提で、私が疑うきっかけとして扱っています。 このあたりの性質については、Berryman / ZieglerのLLMのプロンプトエンジニアリングの説明が参考になりました。 運用を固定するために、CursorのRulesにも記載を追加しました。 Rulesは他にもありますが、ここでは趣旨に関係するものだけ以下に抜粋します。

  • 指定がない限り出力はmarkdownで書くこと
  • 単に用語の意味を知りたいなどの単純な質問の場合、確信度(Red:50%以下、Yellow:50%より大きく90%未満、Green:90%以上)とともに答えること。確信度はアイコンでRed,Yellow,Greenで示すこと
  • 案を考えてください/提案してくださいと言われた時は、見落とし確認→不明点の質問→複数案→メリットデメリット整理→最適案と根拠、の順で出す

2025/11月:AIは「観測できる範囲」しか答えられない

11月にHWの動作確認をするためにドライバを実装していて、数週間ハマった出来事がありました。 原因は、デバイスが状態を持っていて、こちらの予期しない状態(ハング状態)に入っていたという問題でした。 このとき痛感したのは、私の使い方ではAIが答えられるのはソースコード、仕様、デバッグログなど、こちらが与えたコンテキストの範囲に限られる、ということです。 観測がない領域(ハードウェアの状態)は分からないか推測になりやすいです。 だからこそ、鵜呑みにしない運用と、観測を増やす判断が重要になりました。 具体的には、ログや波形を増やすだけでなく、自分の外にある経験(先輩の知見)に当たりにいくことも含めて、手掛かりを増やすようにしました。この件は、先輩に相談したことで突破口が見えました。

2025/12月その1:段階的なプロンプトで回す、自分用Review study

自分が知らないドメインのレビューをすることが、圧倒的に増えてきました。 最初はレビュー内容に対して、AIに分からない点を1つ1つ確認しながら進めていましたが、概念が多いと事前調査に時間がかかります。 困っていたところ、優秀な後輩に「ChatGPTのStudyモード相当のものをスラッシュコマンドで作ればいい」とアドバイスをもらいました。 そこで自分用にReview studyコマンドを作り、レビューを学習と観点拡張の場に変えました。 狙いは、いきなりレビューに入るのではなく、用語→観点→レビューと段階を分けることです。結果として、レビュー前に自分の知らない概念を整理し、理解度チェックを挟み、観点を洗い出した上で、必要だと判断したものだけコメントを残せるようになりました。 (段階化した方が結果が安定しやすい、という考え方はBerryman / ZieglerのLLMのプロンプトエンジニアリングでも参考になる点が多かったです。) ここまで来ると、AIは単なるツールというより、分からない知識をフォローしながら一緒にレビューしてくれる同僚に近い存在になりました。 さらに面白いのは、レビュー対象のMRも同僚がAIを使って生成・監修しており、私もAIを使って理解しながらコメントする点です。コミュニケーションが直接のやり取りというより、AIを介して間接的に成立する感覚が出てきました。

▶︎ Review study コマンドの中身(和訳)

description: 「プログラミングコードレビューのための対話型学習モード。用語理解、レビューポイント、メンター風のコードレビューをカバー。ユーザープロンプトは日本語のままです。」

# レビュー学習モード

ユーザー入力(例:MRタイトルやコード差分)は`$ARGUMENTS`として渡されます。

## 1️⃣ 対話型学習フェーズ

1. Claudeがユーザーに質問:
   > 「わからない用語や概念はありますか?」
2. ユーザーが理解できない用語や概念を提示
3. Claudeが技術的背景と目的を詳細かつ親しみやすい指導者調で説明
4. ユーザーが納得するまで必要に応じて繰り返し
5. Claudeが理解度確認の短文クイズを提示
   - 選択式または穴埋め形式
   - ユーザーの回答に基づく解説を提供

## 2️⃣ 確認ポイントフェーズ

1. 用語と概念が理解されたら
2. 約5つの主要な確認ポイントを提示
   - 各ポイントの根拠とシンプルな設計判断の指針を含める
3. コードレビューへ進む
   - `$ARGUMENTS`からのコードまたは差分を確認
   - 問題点を指摘し改善案を提案
   - 重要度とリスクについてコメント
   - 友好的なメンター的な口調を保つ

## 3️⃣ 対話型フォローアップ

- レビューポイントとコードフィードバック提示後、ユーザーに尋ねる:
  > 「もっと深掘りしたい項目はある?それとも次に進む?」
- ユーザーの応答に基づき、追加説明や例を継続する

2025/12月その2:テストファーストをAIと回す

組み込みソフトウェア開発では、実機環境でテストファーストを回すハードルが下がったと感じています。 まずデータシートをClaude CodeまたはNotebookLMに読み込ませて機能を整理してもらい、同時に自分でも斜め読みして不明点は納得いくまで質問します。その後、主要なテストケースとテストコードを作ってもらい、ビルドしたバイナリをJ-Linkでボードに書き込みます。ドライバ実装が無いのでテストはFailします。 その後ドライバを実装し、Failしたら誤っているのは「実装か/テストか/両方か」を疑います。 このとき参照するコンテキストは、仕様(データシート)やソースコードだけでなく、J-Linkの出力やオシロスコープの波形なども含まれます。これらのコンテキストが揃っている範囲では、AIと対話しながら仮説を更新でき、1人で考えるより思考の幅が広がったように感じます。 同じ密度で同僚に付き合ってもらうのは現実的には難しいので、AI相手だと遠慮なく深掘りできるのは助かっています。

まとめ:AIは「便利ツール」から、チームのコミュニケーションを変え得る「通訳者(L8以上の層)」へ

AIは単に作業時間を短くし、大量の情報処理を行う便利ツールではなく、対話を通して思考の幅を広げ、ある意味で人間の認知能力を拡張するようなものだと捉えています。一方で最近は、仕事というコンテキストにおいて、与えられたコンテキストの範囲内で、AIは「同僚」としてだけでなく、理解と説明の往復に伴う摩擦を減らすことで、チームのコミュニケーションの形を変え得る「通訳者」として働きつつある、と感じています。OSI参照モデルで言えば、これはアプリケーション層(L7)の上に、人間同士の会話や議論、意思決定をスムーズにする新たな通信層(L8以上の層)が生まれつつあるということかもしれません。

参考文献

www.oreilly.co.jp qiita.com en.wikipedia.org


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 photosynth.co.jp Akerunにご興味のある方はこちらから

あなたの「リファクタリング」わたしの「リファクタリング」

社会人28年目、フォトシンス2年目の何でも屋です。

前職で様々なリファクタリングを10年ほど経験してきました。テレビのファームウェアから始まり、UI、アプリ、フレームワークへ広げ、レコーダやIT機器、ケータイにも展開し、最後は製品化プロセスまで手を広げていました。

今回は、そんな私の経験談を語らせて下さい。


はじめに:リファクタリングは「便利で危ない」

リファクタリング」で一番危険な事象って何かわかりますか?

技術的な話ではないんです。技術そのものより「言葉のズレ」です。「リファクタリング」という言葉は便利です。でも受け取り手のバックグラウンド次第で、頭に浮かぶ景色がバラバラになるんですよね。

しかも困るのが、ズレてるにも関わらず、お互い「ちゃんと話せているつもり」になってしまうところ。会話がすれ違っているのに気づきにくい。

同じリファクタリングでも、聞こえ方はこんなに違います。
・変数名や配置を整える“掃除”
・テストを足して壊れにくくする“補強”
・バグ修正や仕様変更まで混ざった“何でも屋”
"作り直し"に近い感覚

同じ組織の中でも立場が変わればこの程度のズレは発生します。

その中でも私が「これは差が大きいな」と感じたのは、Web/アプリ側と、ハード/ファーム(組み込み)側の間でした。

Web/アプリ側は 「直して、配って、戻せる」 が前提になりやすい。
組み込み側は 「直すことが、現場の事故や交換コストに直結する」 が前提になる。
同じ単語でも、背負っている リスクの種類 が違う。だから温度差が出ます。どちらが良い、どちらが悪いではなく、文化的な背景の違いによって発生する、感覚の違いです。

今回は、ここについて語ります。

そもそも「リファクタリング」とは何でしょう?

今回の「リファクタリング」の定義は外部仕様(動作、互換、運用の前提)をできるだけ守りながら、製品の内部構造を組み替えて、変更と運用に耐える状態へ寄せることとします。

では「Web/アプリ側」のリファクタリングと「組み込み側」のリファクタリングについて説明します。


Web/アプリ側:配れる世界のリファクタリング

Web/アプリ側は、変更を「高速に配信できる」ことが特徴です。 新旧を並べて、少しずつ切り替え、最後に撤去する。戻す余地も残せる。 だからリファクタリングが、作業というよりプロセスとして回りやすいのです。

1. 言葉の線引き:リファクタリング/移行/改修

Web/アプリ側だと、リファクタリングと「OSS入れ替え」が同義語になったりしがちです。 ただ、私の経験上、ここは挙動にも差分が入りやすいので「リファクタリング」ではなく「移行」もしくは「改修」として扱った方が良いと感じています。 意識しなくても日付・タイムゾーン・丸め、バリデーション境界、例外、エラー表現、SQL生成といった差分が紛れている流ことが普通にあります。

2. 言葉の線引きが崩れると起きること

リファクタリング」という名札の作業に、バグ修正や仕様変更が混ざると レビュー観点が混線し、テストも“同一性”の確認より“改善”込みの確認に寄ってしまう。 結果、「リファクタリング」の失敗が増える(移行や改修観点で作業していれば問題なかった可能性が高い)。これにより「リファクタリング」という言葉の信用が失われている気がします。

3. 判定ルール:チケット/PRの固定3点

一番簡単にリファクタリングの失敗を防げるのはフォーマットで確認すること。 チケットやPRの冒頭に、固定で以下の3点を書きます。

・変えない外部仕様は何か(画面、API互換、運用手順、性能下限、SLA
・変わる挙動があるなら何か(それはバグ修正か仕様変更だ、と明示)
・同一性の確認方法は何か(テスト、ログ、監視、差分比較)

これが素直に書けないなら、作業の種類が違う可能性が高いです。

4. 具体例:UI/内部構造/基盤

以下に、それぞれの作業で発生する具体例を記述します。

4.1 UI

画面を「同じ部品」として扱えるようにすることです。 そして「状態」と「見た目」と「振る舞い」を分離する。 UIは“変えてないつもり”が一番起きやすいので、挙動の明確化が最重要項目になります。

4.2 アプリ内部

画面ロジックからAPI依存を引き剥がすのも重要です。 データ取得用のAPIと描画の間に、アプリ用のデータ形式への変換層を作り(DTP変換)、API変更の影響範囲が「面」で広がらないようにする。これが出来ていないと、API変更に振り回されることになります。

4.3 基盤の整備(ルーティング/依存/例外/ログ)

ルーティング、DI、例外処理、ログの整備を行います。 運用負荷と障害復旧に効果が大きいので是非やるべきだと思います。事故の際に現象が追いやすいかどうかで復旧までの時間が短縮できます。

5. 強みと怖さ:配れるからこそ起きる事故

Web/アプリ側のリファクタリングの強みは段階を踏んだ対応が取りやすいこと。 一方、対応が速いぶん再度不具合を入れてしまう可能性も高い。なので観測手段が弱いまま構造だけ変えると、原因が追えず「戻すしかない」になりがちです。


組み込み側:観測から作る世界のリファクタリング

組み込み側も目的は同じです。動作を変えずにシステムを再構築する。 ただし、動作を維持するために気にしなくてはならないのがコードだけではありません。

タイミング、電力、通信の不安定さ、現場設置、交換コスト、更新失敗時の復旧。 こういう“物理が混ざった動作”を抱えると、リファクタリングの怖さが別物になります。

まずやるべき作業は、コード整形ではなく「観測できる構造づくり」です。 ログの整備からです。ログの量を増やすというより、ログ全体を仕様から作り直す感覚です。

先ほど述べたように組み込み側の第一歩は、「観測手段」と「復旧手段」を整えることです。 追跡できない変更は何が起こるか分かりません。

私が実際にリファクタリングを行う際に気をつけているのは以下です。
・ログだけでなく処理単位にも一意のEventIdを付ける
・データは基本数値(Enum含む)で扱う
・解析できる粒度と、リアルタイム性を壊さない粒度のバランスを取る

ここが整うと、組み込みの世界が“観測できる世界”に寄ってきます。

1. 言葉の線引き:リファクタが混ざる相手

組み込み側のリファクタリングで混ざりやすい事象は、デバッグ、バグ修正、安定化、仕様変更、ハード改修あたりです。 Web/アプリとは違い“構造変更に見えるのに、タイミングや電力で死ぬ”が起きるので、Web/アプリ側よりも「変えない約束」を強く言語化した方が安全です。

2. 安全策の順番:配布より先に復旧と観測

復旧経路があるか。壊れたときに戻れるか。 そして、何が起きたか追えるか。ここがキモです。

ウォッチドッグ、フェイルセーフ、更新失敗時の旧ソフトでの再起動、 EventId付きログ、状態遷移の記録、エラーコード体系、バージョン同定。

地味です。システム全体に入れないと意味がありません。辛いです。が、効きます。

3. 判定ルール:チケット/PRの固定3点

Web/アプリ側と同じく、フォーマットで線を引きます。
・変えない外部仕様は何か(電気特性、プロトコル互換、タイミング上限、電力、現場手順、復旧手順)
・変わる挙動があるなら何か(周期、優先度、メモリ、ログ量、フラッシュ書き込み、再送回数)
・同一性の確認方法は何か(実機/HIL、負荷、故障注入、OTA失敗、ログ比較)

これが書けない変更は、リファクタリングの対象にすべきではありません。

4. 具体例:境界/RTOS/通信/更新

4.1 ドライバ層と製品ロジック

I/Oの入口と出口にEventIdを置き、何が起きたか辿れる状態にしてから依存方向を整える。 全体を見ずに、見えた順に抽象化を行うと、何が何の抽象化なのかわからなくなるので注意。

4.2 RTOSのタスク構成

機能で分ける前に「壊れた時の影響範囲」で分けます。 落ちても復旧できる処理、落ちたら致命傷な処理、タイミングが厳しい処理。 組み込みならではの観測が必要な処理です。 ここをしっかり分別すると、リファクタリングが“安全設計”になります。

4.3 通信とメッセージング

テキストで綺麗にするより、状態遷移と数値コードを固定する。 現場で拾える、あとから解析できる、送信コストも読める。組み込みだとJSONよりもenumを利用します。

4.4 更新・復旧

更新できるかより、失敗しても戻れるかを先に仕組みかすること。 これが無いシステムは、リモートでのシステム変更は不可です。

5. 強みと怖さ:観測できない変更は現場で死ぬ

組み込み側でのリファクタリングの強みは、境界が物理に寄るので“実体”として作りやすいこと。 怖さは、観測できない変更は現場でしか発生しないことです。典型はログを入れすぎてタイミングを壊す、フラッシュを食う、通信を詰まらせる。観測のための変更が本体を壊すのは本末転倒なので、ログの設計は慎重に行う必要があります。


まとめ:同じ言葉で、違う怖さを扱っている

様々な人が持っている「リファクタリング」という単語への印象を揃えるコツは単純で、「同じ言葉で、違う怖さを扱っている」と認めることです。

Web/アプリ側は「直して配る」で安全を作れる。 組み込み側は「観測して復旧する」で安全を作る。 やっていることは同じで、製品を壊さず前へ進めるための安全を作っているだけ。違うのは道具と順番です。

そして Web/アプリ で 組み込み リファクタリング用の観測をサポートすることもできるし、組み込み 側が Web/アプリ にサポートデータを提供することもできる。互いに支え合いながら、より良いリファクタリングを目指したいです。


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 photosynth.co.jp

Akerunにご興味のある方はこちらから akerun.com

チームのパフォーマンスを最大化する!私たちが実践する「自律的ワーキングアグリーメント」の全貌

皆さん、こんにちは!Akerun事業開発部のプラットフォームチームでエンジニアを務めている島田です。

私たちのチームは、日々変化する技術やビジネスの要求に対応しながら、高い生産性と健全なチーム文化を維持することを目指しています。その実現のために、私たちは「ワーキングアグリーメント(WA:行動規範)」をチーム全員で作成し、運用しています。

本記事では、このWAがなぜ必要で、どのような内容になっているのか、そしてそれが私たちのチームにどのような変化をもたらしたのかをご紹介します。自律的なチーム作りや、リモートワーク環境下でのコミュニケーションに課題を感じているエンジニアリングマネージャーやリーダーの方にとって、ヒントになれば幸いです。

なぜ、あえて「ワーキングアグリーメント」を決めるのか?

「ルールで縛るなんて、自律的なチームとは逆行しているのでは?」と思われるかもしれません。しかし、私たちのWAは「最小限の制約で、最大のパフォーマンスと心理的安全性」を得るための共通言語であり、チームメンバー全員の「働き方や価値観の尊重」を土台にしたものです。

私たちがWAに込めた3つの願い

  1. コミュニケーションの質の向上と摩擦の軽減: 価値観が多様化する中で、「暗黙の了解」は対立の種になりがちです。WAは、意思決定や相談の「型」を定めることで、議論を建設的にし、無駄な衝突を減らします。
  2. 自己組織化の基盤作り: エンジニア一人ひとりが自律的に動くためには、「この状況ではどう動くべきか」という共通認識が必要です。WAは、その判断基準を提供します。
  3. 新メンバーのスムーズなオンボーディング: WAを読むだけで、チームの文化、コミュニケーションのスピード感、緊急時の対応優先度がわかるため、新しいメンバーがすぐにチームに貢献できるようになります。

私たちのチームを支える3つの柱:ワーキングアグリーメントの内容

私たちのWAは、チームメンバー同士の議論を重ね、他社の優良事例も取り入れながら作成しました。また、四半期に一度は必ず見直し、形骸化を防いでいます。最初に決めた内容から大きく変わることはありませんが、微調整を続けることで、常にチームの「今」にフィットさせています。

1. 「コミュニケーション」:ストレスフリーで円滑な意思決定のために

項目 具体的な内容と意図
意思決定の基本はラフコンセンサス 全員が完全に賛成でなくても、異論を唱える人がいなければ進めるというルール。「完璧な合意」を求めないことで、意思決定のスピードを上げます。
Slackへの返信は4時間以内 コミュニケーションの「速度」に関する期待値を合わせることで、相手の不安を解消し、ボールが停滞するのを防ぎます。
Slackへのリアクションルール 👀(確認した)、✅(OK/賛成)など、絵文字で意思表示を統一。文字を打つ手間を省き、「見た/見てない」の無用な確認をなくします。
やりとりはオープンに(基本的にDM不使用) 透明性を高め、情報格差をなくします。DMを使うべき特別な理由がない限り、すべてパブリックチャンネルで行います。
アジェンダの共有は前日まで 参加者が事前に準備し、質の高い議論をするための最低限のマナーとルールです。

2. 「業務の進め方・開発プロセス」:生産性を高め、常に前に進むために

項目 具体的な内容と意図
Fail Fast, Learn Fast(素早く失敗し、素早く学ぶ) 完璧を目指してリリースが遅れるよりも、小さく試して市場やユーザーからフィードバックを得ることを推奨する姿勢です。失敗を恐れない心理的安全性の醸成に繋がります。
詰まっている時は、すぐに相談 抱え込みによる開発の遅延を防ぐため、専用チャンネルやメンションで「助けを求めることの推奨」を明文化しています。
タスクや返信には期限を明確にする タスクの優先順位付けと計画的な対応を促します。期限がない場合は「翌営業日対応」とすることで、無期限のタスクを発生させない仕組みです。
Pull Request(PR)/チケットの概要にTODOや進捗を記載 状況を可視化し、誰でもすぐに引き継ぎやレビューができる状態を作ります。属人化を防ぎ、相互サポートを容易にします。
エラー/ワーニング通知は最優先調査 サービス品質維持のため、アラートチャンネルへの通知を最優先業務と定めます。これにより、緊急時の判断基準を統一しています。

3. 「ワークスタイル」:お互いの存在を感じ、一体感を維持するために

項目 具体的な内容と意図
オンライン会議はカメラオン or エフェクト リモートワークでも「そこに人がいる」という感覚を大切にするため。全員の表情やリアクションが見えることで、発言者は安心して進められます。
音声やリアクションでの応答 ファシリテーターの進行や発言内容に対するフィードバックを明確にすることで、議論の停滞を防ぎ、参加意識を高めます。
朝会は参加必須 or Slackで日報共有 チームの同期を維持し、お互いの状況を把握するための最も重要な接点です。不参加の場合の代替手段(日報)を定めることで、情報共有の漏れを防いでいます。

コードレビューのWA

さらに、「Looks Good To Me」を参考に取り入れたコードレビューのチームワーキングアグリーメントがあります。

www.shuwasystem.co.jp

コードレビュープロセスにおける目標、ワークフロー、責務、およびレビューの焦点となるガイドラインを定めています。

1.コードレビューの目標

  • バグの発見
  • コードベースの安定性とメンテナンス性
  • 知識移転・共有
  • 記録の保持・作成

2.私たちのワークフロー

フェーズ 主なルール・責務
準備 GitHubとSlackを連携し、PRの通知を受け取れるように推奨。
レビュー前 (レビューイー) ローカルでの動作確認、CI(単体テスト、Lint)のパス、PRテンプレートの使用、レビューアーを2名以上アサイ(AIレビューアーは1名にカウントしない)。
レビュー中 (レビューアー) チーム目標である「オープンからレビューまでの平均時間」以内に応答、レビュー観点に基づいたレビュー、修正済みならconversationを解決、問題なければ承認、修正依頼はコメント。
レビュー後 (レビューイー) 指摘事項には要・不要に関わらず返信、修正した場合はコミットハッシュを記述、全て対応後に再レビューを依頼。
マージ 2人以上の承認がある場合、PRをマージ。マージ後のCI通過を確認。
PR作成者の責務 自分自身が最初のレビュー担当者になる、PRを管理しやすくする(理想は20ファイル未満、500行未満)、エゴを捨てる、フィードバックに焦点を当てる。
レビュー担当者の責務 エゴを捨てる、開発者ではなくコードに焦点を当てる、建設的なフィードバック、影響力を濫用しない(迅速な完了)、徹底的にレビューする(通過したコードはレビュー担当者の責任となる)。

3. 私たちのレビューの焦点(観点)コードレビュー時に特に焦点を当てるべき主要な項目として、以下のものが挙げられています。

  • 複雑さ: コードが理解可能で、将来的に変更しやすいか。
  • 整合性: 既存の設計パターンやプラクティスに従っているか、再利用可能な既存コードはないか。
  • 規約: 業界やプログラミング言語の規約を守っているか。
  • ドキュメント: ドキュメントの不足や更新の必要性。
  • エラー処理: エラーと例外処理の明確なガイドラインと一貫性。
  • 命名: 変数名などが明確で理解しやすいか。
  • リソース管理: メモリやネットワーク接続などのリソース管理が適切か。
  • 拡張性: リファクタリングや書き換えが容易で、将来のシナリオに対応できるか。
  • セキュリティ: 明らかな脆弱性やセキュリティ基準の遵守。
  • テスト: テストの不足やカバレッジに関する許容範囲。

4. ブロッキング問題 vs 非ブロッキング問題

  • ブロッキング問題 (PRの承認を止めるべき問題):
    • 要件未達、CIの未通過、セキュリティの問題、パフォーマンス問題。
  • ブロッキング問題 (PRの承認を止めるべきでない問題):
    • スタイルの好み、軽微なフォーマットの不一致、ドキュメントの細かい指摘、任意の機能の欠如、軽微なリファクタリングの機会、無関係な改善。

まとめ:WAは成長するチームの「OS」である

私たちのワーキングアグリーメントは、単なるルールブックではなく、チームがスムーズに動くための「オペレーティングシステム(OS)」のようなものです。

この共通認識を持つことで、私たちは余計な摩擦にエネルギーを使わず、ユーザーへの価値提供という最も重要な活動に集中できています。また、メンバー全員で作り、定期的に見直すプロセス自体が、チームのオーナーシップを高め、自律性を育んでいます。

もし皆さんのチームでも、コミュニケーションのすれ違いや意思決定の遅さに悩んでいるようでしたら、ぜひ「メンバー主導」でワーキングアグリーメントを作成し、運用することをおすすめします。それは必ず、チームの心理的安全性と生産性を飛躍的に向上させる第一歩となるでしょう。


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 photosynth.co.jp

Akerunにご興味のある方はこちらから akerun.com