OpenHands Headless Modeの実装を読む
昨今、巷ではClineやDevinによるAIコーディングが話題です。特にDevinのような「タスクを渡したら、完了まで自律的に思考と行動を繰り返すエージェント型ソフトウェア」には、面倒だけど微妙に自動化しきれない作業を巻き取ってくれる可能性を秘めていると期待しています。例えば、machine-readableでない文書を定期的に監視して変更を実装に反映する、などです*1。
そもそも、どのようにしてAIに自律的に思考と行動を繰り返させているのでしょうか?AIの最新情報には疎いので、実装イメージがパッと思い浮かびません。どのようなアーキテクチャになっているのか非常に興味が湧いてきました。
Devinは商用プロダクトなのでコードベースは公開されていませんが、類似のオープンソース実装であるOpenHandsであればコードが読めます。本記事はもっとも仕組みが単純そうなHeadless Modeの実装を読んでみたメモです。
*1:例えば、メンテしているTFLintのAWS rulesetでは定期的に公式ドキュメントを参照して有効な値を実装に反映する、みたいな不毛な作業があります... https://github.com/terraform-linters/tflint-ruleset-aws/pull/803
criu restoreを非特権コンテナから呼ぶことはできるか
CRIUによるプロセスのリストアには複数のcapabilityが必要であり、コンテナ内部で行うためには--privileged相当で起動された特権コンテナでなければいけません。例えば、TCP connection repairにCAP_NET_ADMINが必要なのは明らかですが、もっと単純なプロセスであれば非特権コンテナでもリストアできるのでは...?と考えたのが事の始まりです。
sigstoreのKeyless Signingでは何を検証しているのか
最近、個人的にsigstoreのKeyless Signingがアツいです。以下のブログを読みました。
これらの記事は主にコンテナイメージの署名について解説しているのですが、sigstoreはバイナリの署名にも使えます。以前から、複数メンテナ体制で秘密鍵をどう共有しよう?とか、公開鍵の安全な配布方法って無くない?と考えていたので、渡りに船です。
チームでひとつの鍵を保守したい場合とかどうやってるんだろ、みんなに主キー配るんかな、まぁそりゃそうか...
— wata (@wata727_) 2021年5月1日
リリースバイナリの署名に使った鍵をキーサーバーで公開してたら、今それ信用できんのでリポジトリに公開鍵入れてくれという話が来ていた、もう何も信用できないhttps://t.co/2g5diZxGIM
— wata (@wata727_) 2019年12月24日
早速、採用に向けて色々調べていたのですが、署名した人をどう確認しているのか、改ざんされていないことをどう保証しているのかがわからなかったので、Keyless Signingでは何を検証する必要があるのかを調べました。
全然わからない状態から調べているので、間違ったことを書いてるかもしれません。何か間違いを見つけたらTwitterとかで教えて下さい。
続きを読むコンテナはなぜ安全(または安全でない)なのか
CVE-2019-5736を覚えていますか?今年の2月に見つかったrunc(Dockerがデフォルトで利用しているコンテナのランタイム)の脆弱性で、ホストのruncバイナリを好き勝手にコンテナ内部から書き換えることができるというものです。
脆弱性の仕組みに興味があったので調べたところ、コンテナを攻撃する方法というのは他にもいろいろあって、runcは頑張ってそれを塞いでいるようです。これまとめると面白いかも、と思ったので以下のようなおもちゃを作りました。
Drofuneは簡単なコンテナランタイムです。drofune runとかdrofune execなどでコンテナを起動したり、入ったりすることができます、といえば想像がつくでしょうか。
これだけでは何も面白くないので、Drofuneはわざと安全でない実装になっています。なので、今回発見されたCVE-2019-5736を利用した攻撃も成立します。このプロジェクトは攻撃コードがどのように動き、どのように防げるのかを試すことが目的です。
続きを読むRubyのprivateを考える
RuboCopのIssueを眺めていると、いろいろな人のRubyの考え方に触れることができて面白い。例えば、多くのRubyistにとってprivateなメソッドを宣言したいときには、以下のような書き方をすると思う。
class Cat def meow puts "Meow!" end private def bowwow puts "Bowwow!" end def cock_a_doodle_doo puts "cock-a-doodle-doo" end end
privateの後にインデントするとかしないとか、微妙な差異こそあれど、大体こんな感じ。でも、これをよくないと考える人もいる。ではどうするのかというと、以下のようにインラインでアクセス修飾子を書くべきだという主張。
class Cat def meow puts "Meow!" end private def bowwow puts "Bowwow!" end private def cock_a_doodle_doo puts "cock-a-doodle-doo" end end
以下はこのスタイルを強制することができるCopを追加するプルリクエスト。RuboCop v0.57.0 以上を使っているならば、EnforcedStyleをinlineにすれば、すぐに試すことができる(ただ、v0.57.2 時点でいくつかの問題が報告されているので、有効にして運用するのはちょっとオススメしない...)
RuboCopの Rails/InverseOf について調べた
最近、RuboCopへのパッチを投げるようにしているのですが、なんか良さそうなバグは無いかなとissueを漁っていたところ、こんなissueを見つけました。
このissue自体は単なるfalse positiveなので、まぁ対応すれば良いのですが... こっちがその問題のCopが追加されたプルリクエスト。
このCopが教えてくれることは、状況によっては :inverse_of を明示的に指定しないと、意図した挙動をしないことがあるので、その場合にはちゃんと :inverse_of を書きなさいね、ということです。ただ、1個目のissueのコメントで「Railsガイドには :through とか :polymorphic を指定していると、:inverse_of は効かないって書いてあるけど、それでも指定しないとダメなの?」と言っている人もいます。
:inverse_of については、Railsのバージョンアップによってデフォルトで指定しなくても動くようになった経緯などもあって、いつ指定すべきで、いつ指定しなくてもいいのか、いまいち理解が曖昧だったので、ちょっと調べることにしました。
続きを読む