すべての Asana 展開には管理者コンソールがあります。 IT 管理者は、パスワードの要件、役割と権限、Dropbox からファイルを添付できるかどうか、デフォルトで新規プロジェクトを閲覧できるユーザーなどを設定し、会社における Asana の使用方法を構成します。
Asana が成長するにつれて、管理者コンソールには長年にわたるカスタムロジックや一時的な寄せ集め機能が蓄積され、管理機能の構築とメンテナンスにかかるコストがますます高騰していました。 管理設定の 1 つである、新規プロジェクトのデフォルトの公開範囲を例に見てみましょう。 管理者は、新しいプロジェクトを組織全体に公開するか、チームに公開するか、招待されたメンバーのみに公開するかを選択します。 説明は簡単ですが、その背後には多くの複雑さが隠されています。
この機能は、お客様のプランに含まれていますか?
以前は有料プランを利用していたものの、現在は利用しておらず、変更できない設定のままになっているのでしょうか?
お客様は HIPAA または FedRAMP の対象であり、上位の役割を持つユーザーのみが編集できるのでしょうか?
ある選択肢が、別の設定によって使用できなくなっていることはないか?
現在の制限事項を説明する情報バナーを表示すべきか?
管理者コントロールを追加したいチームは、これらすべてを正しく行う必要がありました。 ほとんどのチームは、その労力をかける価値がないと判断しました。そして、時間の経過とともに、Asana でできることと管理者が管理できることとのギャップが広がっていきました。 たとえば、一部のコントロールは全社レベルでのみ設定できるため、IT 管理者がユーザーの一部だけにコントロールを適用することが困難になります。
以下は、プロジェクトのプライバシー設定ダイアログのスニペットです。このダイアログは、設定を無効にするべきかどうか、またバナーを表示すべきかどうかを判断するために使用されます。
ここには、機能のライセンス、ガバナンス、展開構造による上書き、そして特にレビュー担当者のユーザーの役割など、解析すべきロジックがたくさんあります。 慎重に確認するには、頭の中でテストマトリクスを再構築し、それが正しいかどうかを判断する必要があります。
しかも、これはダイアログの話にすぎません。 行が設定ページに表示されるかどうかは、別の場所で決定されており、その方法も一貫していません。
3つの行、3つのメカニズム、そしてゲーティングが必ずしも同じファイル内にあるとは限りません。 つまり、「このお客様には実際にどの設定が表示されるのか?」という質問に答えるには、 すべての行を読むだけでなく、すべてのコンポーネントをチェックする必要がありました。 この質問はかなり頻繁に寄せられます。カスタマーサポートが、ある顧客の設定がなぜ表示されなくなったのかを説明しようとする場合、プロダクトマネージャーが、新しいコントロールがすぐに変更できるものなのか、それとも2週間かかるものなのかについて明確な答えを求めている場合、新入社員が、特定のユーザーに何が表示されるかを決める場所を1箇所だけ見つけようとしている場合などです。
全体像を見てみると、管理者コンソールでの作業を非効率にしていた要因は 4 つありました。
レビューに手間がかかる。 ロジックは作成者が配置した場所に存在するため、PRによってレビュアーにはわかりにくい特別な動作が導入される可能性があり、読むだけでは正しさを簡単に確認できませんでした。
標準化の欠如により、バグが見えにくくなっていた。 長年存在していたバグの中には、検出が困難なものもありました。 その多くは、カスタム実装が多数存在することに起因する、製品仕様と実装の間の乖離が原因でした。 チームが恣意的な決定を下したため、すべてのコントロールに独自の癖がついてしまいました。
変更にコストがかかる。 エンドユーザーのために 1 つの変更を加えるには、ルールが記述されているすべての場所を見つける必要があり、定義が 1 か所にまとまっていることはほとんどありませんでした。
テストにコストがかかる。 テストの準備にはバックエンドの状態に関する深い知識が必要であり、相互に作用する要素が多すぎるため、最終的な展開に対して包括的な手動テストを実施することは現実的ではありませんでした。
私たちは、コードベースにおける信頼できる情報源として機能する、管理コントロール用の宣言型フレームワークを作成しました。 コントロールは、それが何であるかを明示するようになりました。
ここにあるすべてのフィールドは、上記のダイアログの分岐に対応しています。requiredAdminRoleはHIPAA/スーパー管理者チェック、upsellBehaviorは2つのアップセル分岐、churnBehaviorは解約済み顧客のケースで、デフォルトのみを復元できるようにしています。
その一環として、このフレームワークは、エンジニアがコントロールの計算された状態を導き出すために使用するフックを公開します。 同じプロジェクトのプライバシーダイアログが現在どのように表示されるかを見てみましょう。
バナーの if-chain は、一元化されたフックによって駆動される 1 つの共有コンポーネントに集約されました。 フレームワークは、さまざまなシナリオの組み合わせロジックを処理します。管理製品を深く理解している、そのメンテナンスを担当する SME は、自信を持って大規模な変更を加えることができます。 現在、厳格な型指定を使用して、実装者がすべてのシナリオで設定を正しくレンダリングするために必要な必須情報を入力するよう促しています。 重要なのは、実装担当者がこれらのシナリオの複雑さや、シナリオ同士の関連性を理解する必要がないことです。
これらの設定には、管理者コンソールの UI の行からアクセスできます。 これらの行の表示 / 非表示も同様に処理され、ここで 2 つ目のフレームワークが役立ちます。 設定レジストリの行は、独自の表示ルールを記述するのではなく、それを表すコントロールに関連付けられています。
コントロール配列が価値をもたらします。 この配列には、ダイアログが useAdminConsoleControl に渡すのと同じ ProjectDefaultPrivacy オブジェクトが格納されており、レジストリはこれを信頼できる唯一の情報源を介して実行するため、ページとダイアログが矛盾することはありません。 以前は個別に計算されていたため、不一致があると 2 つの障害モードが発生する可能性がありました。1 つは、表示されているものの、開いたダイアログが使用できない行です。もう 1 つは、顧客が有料で利用している設定にアクセスできる行がないことです。 これを一元化することで、このカテゴリのバグを排除できました。
一元化されたフレームワークを採用したテストにより、プルリクエストのレビュー担当者のエクスペリエンスが大幅に改善されました。 たとえば、行の表示 / 非表示のテストでは、「このお客様には実際にはどの設定が表示されるのか?」という先ほどの質問に 先ほどの質問に答えます。 テストコードの代わりに、シナリオは単なるデータです。つまり、ペルソナ、ドメインの状態、およびシナリオが表示されるページです。
そして、行には、その行が表示される必要がある名前付きシナリオがリストアップされます。
レンダリング呼び出しも、記述すべきアサーションもありません。 動的テストスイートはカタログを読み取り、各行が名前が記載されているすべてのシナリオと照合されます。 カタログは、お客様に表示される内容が記載された唯一の場所となり、機械によってチェックされるようになりました。 テストケースを正しく特定して作成するために、熱心なコードレビュアーや作成者に頼る必要はもうありません。
この取り組みは、SME 以外のエンジニアが管理者コンソールで安心して開発できるようにする必要があると予測したため、2025年後半に開始しました。 当時、目標は LLM のパフォーマンスを最適化することではありませんでしたが、エンジニアの体験を標準化し、合理化することで、AI エージェントにも同じ効果が得られることがわかりました。
これらのフレームワークを構築する前に、この移行の問題に AI を適用してみましたが、技術的にはうまくいきました。 問題は、エージェントもレビュアーもテストが実際に正しいかどうかを判断できず、誤った自信と見落とされる不備が生じていたことです。 AIは構造の欠如を解決するものではなく、既存の構造の上に、より多くのコードをより速く生成するだけです。 Googleは、AIを活用した開発において、Goの型システムについて同様の主張をしています。LLMはプロパティを誤認したり、ファイル間で型が一致しなかったりしがちであるため、静的型は自動的なセーフティネットの役割を果たすのです。 TypeScript は Go のように静的に厳密ではありませんが、フレームワークはその上に同じ保証を構築できます。フレームワークレベルでコントロールのタイプを一度定義すれば、すべての実装が使用時にそれに適合しなければなりません。
フレームワークの準備が整ったら、委任と並列化の準備を始めました。 私は、当社の新しい仕様駆動型開発ツール [リンクのプレースホルダー: 仕様駆動型開発に関するエンジニアブログ記事: Asana エンジニアブログ - 仕様駆動型開発: メリット] を使用して、最初から最後まで作業をこなすスキルを構築しました。 このスキルは、コントロールの定義、フックの呼び出し、バナーの置き換え、フラグメントの更新、新しい宣言型テストの追加、さらに自動更新されるチェックリストと過去の変換におけるエッジケースのログなど、変換作業全体をコード化します。 約 150 件の移行すべてにおいて、レビュー後に修正を必要としなかったのは 91% でした。
エージェントに PR の作成を依頼するのも、その PR をレビューするのも、それほど工数はかかりません。 すべてが予測可能な方法で宣言されるため、レビュー担当者は、実装が製品仕様に合致しているかどうかを確認するために、管理に関する専門知識を持つ必要はありません。 重要なのは、これによりレビュー担当者の候補がはるかに幅広いエンジニア層に拡大することです。これは、上流で PR を作成する段階のファネルを広げるだけよりも、スピードアップにつながります。 この時代にふさわしいレビューのあり方を再考しているのは私たちだけではありません。GitHubは、Copilot独自のレビューエージェントを構造化されたPRエビデンスに基づいて再構築し、人間のレビュー担当者がより迅速に適切な質問にたどり着けるようにすることで、レビューコストを約20%削減しました。
複数のフレームワークにまたがる約 150 件のアイテムの元の移行は、最初から最後まで手作業による 1 回限りのエンジニアリング作業として計画されていました。 最初にフレームワークを構築し、その後、エージェントをモニタリングするエンジニアに移行作業を委任することで、当初の計画よりも1か月以上早くすべての作業を完了することができました。
これらのフレームワークの構築自体は、プロジェクトではありませんでした。 これは、並行作業とスケーリングが必要なロードマップから生まれたもので、途中で人員が限られ、変動する中で、すべてのコントリビューターが最初にその分野の専門家である必要がないという必要性から生まれました。 このフレームワークは、すでに構築したチームを超えて機能していることがわかっています。現在、フレームワークに含まれる 66 のコントロールのうち 18 個は、8 つの異なるチームのエンジニアによって作成されました。
現在、当社はこの種の投資を行う次の分野を探しています。 むしろ、この取り組みの意義は、開始前よりも今の方がはっきりとしています。適切に設計された宣言型のフレームワークは、レビューを容易にするだけでなく、エージェントが信頼できる成果物を出せるか、それとも単に速いだけの成果物を出してしまうかを左右します。 また、自律的なレビューを現実的なものにする可能性もあります。Cloudflareは、AIレビュー担当者がクリーンなコードを承認し、実際の問題を自らブロックするシステムを構築しました。このシステムが機能するのは、入力がレビュー担当者が信頼できるほど十分に構造化されているからです。 Asana のフレームワークが同じことを試すのに十分な構造を備えているかどうかは、次の検討事項としてふさわしいでしょう。
Leo Zhang は、IT 管理者が組織を管理できるよう支援する Admin Foundations チームのソフトウェアエンジニアです。 現在、彼は当社の製品を支える技術的フレームワークに注力することで、管理者コンソールにおける他の製品エンジニアの開発体験を向上させています。
これらの変更の設計、実装、テスト、共有には、チームの多大な工数が費やされました。 この取り組みは、Admin Foundations チームの他のエンジニアである Yunus Rahbar さん、Maryam Booshehrian さん、Saverio Castelli さん、Bronwyn Damm さん、Cindy Yu さん、Calvin Norton さん、Jaxsun McCarthy Huggan さんの貢献により実現しました。 エージェントサクセス部門のタイガーチームに所属する Walter Li さんは、これらの移行に適切な AI ツールをセットアップするにあたり、多大な貢献をしてくれました。
Lan Cheng、Emerson Murphy-Hill、Mark Canning、Ciera Jaspan、Collin Green、Andrea Knight、Nan Zhang、Elizabeth Kammer、「What Improves Developer Productivity at Google? Code Quality(コード品質)」、ESEC/FSE '22、2022年 11月。https://doi.org/10.1145/3540250.3558940
「Orchestrating AI Code Review at Scale」、Cloudflareブログ、2026年4月。https://blog.cloudflare.com/ai-code-review/
Napalys Klicius、「Better tools made Copilot code review worse. Here's how we actually improved it」The GitHub Blog、2026年7月。https://github.blog/ai-and-ml/github-copilot/better-tools-made-copilot-code-review-worse-heres-how-we-actually-improved-it/
「Why Go is an Ideal Language for AI-Assisted Software Engineering」(『GoがAI支援ソフトウェアエンジニアリングに理想的な言語である理由』)、Google Developers Blog、2026年8月。https://developers.googleblog.com/why-go-is-an-ideal-language-for-ai-assisted-software-engineering/