Skip to content

Anthropic built Scion for itself. Carbon Forge is yours →

Carbon Forge
Menu

ガイド

コードの変更とそのドキュメントを 1 つのチェンジセットでランディングする

コードの変更と、それを説明するページは、同じチェンジセットで一緒にランディングするか、どちらもしないかです。このガイドでは、そうした変更を 1 つ、開いたレーンから 1 回のランディングまで進めます。

他の言語: English, Español, Português · 日本語のガイド一覧

開示: Carbon Forge は 100monkeys.ai で開発しているため、作り手による説明として読んでください。このガイドは公開ドキュメント、主に Working in lanes と Code and files on the substrate をもとに当社の AI エージェントが下書きし、当社がレビューしました。この日本語版は英語の原文ガイドの翻訳です。呼び出しはすべてドキュメント自身の例で、引用は英語のまま示し訳を添えています。ドキュメントが答えていない点は、最後の節に書いています。

なぜ 1 つのチェンジセットなのか

ドキュメントのトップページは単位をこう定義しています。"A changeset is many writes landed as one: every page, atom, code tree and library entry it names is written in one transaction under one intent, the changeset's intent, or nothing is written"(チェンジセットとは、1 つとしてランディングされる多数の書き込みである。そこに挙げられたページ、アトム、コードツリー、ライブラリ項目はすべて、1 つの意図、すなわちチェンジセットの意図のもとで 1 つのトランザクションで書き込まれるか、何も書き込まれないかのどちらかだ。Welcome to Carbon)。コードと文章は 1 つの記録のエンティティなので、読み手が新しいコードと古いページを並べて見ることはなく、取り消せば両方が一緒に戻ります。

レーンとツリーに書き込めるトークンが必要です。ドキュメントがこの作業に挙げるプリセットは SCM agent です。

ステップ 1. トランクが保護されているか確かめる

workspaces.get_settings {}
→ { "workspaceId": "…", "trunkProtected": true, "trunkProtectedEntities": false }

"With trunkProtected, code trees, library entries and changesets go through a lane; with trunkProtectedEntities as well, page and atom edits do too."(trunkProtected があれば、コードツリー、ライブラリ項目、チェンジセットはレーンを通る。さらに trunkProtectedEntities があれば、ページとアトムの編集も同様だ。)どちらにしても、ここではレーンが正しい形です。ドキュメントがレーンを使うのは "a change should be seen whole before it lands"(変更をランディング前に全体として見るべき)ときです。

ステップ 2. 変更のためにレーンを開く

lanes.create { "label": "agent/7/fix-login" }

ラベルはスラッシュ区切りの小文字のセグメントで、開いているレーンの中で一意です。"A lane costs nothing to open and holds no copy, so one per task, or one per agent, is the expected use."(レーンは開くのにコストがかからず、コピーも持たない。だからタスクごとに 1 つ、あるいはエージェントごとに 1 つが想定された使い方だ。)owner を渡すと、そのレーンへの書き込み、解決、ランディングをあなただけのものにできます。

ステップ 3. レーン上でコードを変更する

trees.apply_patch { "path": "app", "operations": [ { "op": "patch", "entry_path": "src/login.ts", "old_string": "password", "new_string": "magicLink" } ], "intent": "fix: accept magic links", "lane": "agent/7/fix-login" }

ラベルを lane として渡すと、"the write is held on the lane as a patch against the trunk"(書き込みはトランクに対するパッチとしてレーンに保持される)、つまり "the trunk is not written"(トランクには書き込まれない)。trees.apply_patch は操作(ファイル内の置換、書き込み、削除、移動)だけを送り、trees.put はツリーの全エントリを送ります。どちらでも "the lane keeps only what differs"(レーンは差分だけを持つ)。

ステップ 4. 同じレーンで、それを説明するページを変更する

pages.apply_patch { "pathOrId": "guides/login", "old_string": "Sign in with a password.", "new_string": "Sign in with a magic link.", "lane": "agent/7/fix-login" }

同じラベルなので、ページの編集はコードの隣で待ちます。変更でページ名も変えるなら、pages.move も lane を受け取り、"a rename belongs to the change that needs it"(名前の変更は、それを必要とする変更に属する)。スクリーンショットも同じように library.put_at_path とラベルで入れます。

ステップ 5. レーンが作る結果を読む

読み取りに同じ lane を渡すと、"the answer is the trunk as it stands now with the lane's patches applied, composed on the call"(答えは、現在のトランクにレーンのパッチを適用したもので、呼び出し時に合成される)。ページには pages.read、コードには trees.get、trees.diff、trees.grep を使います。次に全体をレビューします。

lanes.diff { "label": "agent/7/fix-login" }
lanes.get { "label": "agent/7/fix-login" }

lanes.diff は "entity by entity, the trunk's section and the lane's"(エンティティごとに、トランクの節とレーンの節)を返し、lanes.get はパッチ、競合、そして landable、すなわち "open, at least one live patch, no conflict"(開いている、有効なパッチが少なくとも 1 つある、競合がない)を返します。アプリでは /<workspace>/lanes/<label> が同じ内容を示し、変更された各テキストファイルを unified diff で表示します。lanes.export を読んでその合成ハッシュで承認したレビュー担当者は "has approved exactly that change"(まさにその変更を承認したことになる)。

ステップ 6. 競合があれば答える

その間に誰かがトランク上でページやファイルの同じ行を編集していたら、パッチは競合状態になり、"nothing merges by itself"(何も勝手にはマージされない)。lanes.conflicts は、パッチ、元の節、トランクの現在の節、そしてそれを動かしたチェンジセットを返します。lanes.resolve で答えるか、lanes.drop_patch でパッチを捨ててください。ファイル内の置換は "replays on the trunk's current file, so two agents changing different parts of one file both land"(トランクの現在のファイルに再適用されるので、1 つのファイルの別々の部分を変えた 2 つのエージェントはどちらもランディングできる)。

ステップ 7. 意図を添えて一度だけランディングする

lanes.land { "label": "agent/7/fix-login", "intent": "fix: accept magic links", "dry_run": true }
lanes.land { "label": "agent/7/fix-login", "intent": "fix: accept magic links" }

まずドライランを、次にランディングを実行します。"Every live patch is replayed as one changeset whose intent is lane agent/7/fix-login: fix: accept magic links"(有効なパッチはすべて、意図が lane agent/7/fix-login: fix: accept magic links である 1 つのチェンジセットとして再適用され)、自身のトランザクション内で再確認され、"refused whole, with every conflict named, if anything moved"(何かが動いていれば、すべての競合を名指しして丸ごと拒否される)。意図を feat、fix、docs、chore、revert のいずれかで始めると、リリースノートはその語でまとめます。idempotency_key を送れば、タイムアウト後の再試行は "answers the first landing's result instead of landing twice"(2 回ランディングせず、最初のランディングの結果を返す)。

ステップ 8. ランディングを読み返す

/<workspace>/changes/<id> を開いてください。意図の全文、実行者、元のレーン、封印、エントリが、コードファイルとページを一緒にして表示されます。変更した行の blame は、あなたが書いた意図で答えるようになります。trees.blame は "each line's revision, changeset, intent, actor and landing lane"(各行のリビジョン、チェンジセット、意図、実行者、ランディング元のレーン。Code and files)を返します。両方を一度に元に戻すには、changesets.revert が、そのランディングが書いたすべてのエンティティを復元する新しいチェンジセットを 1 つ書きます。

ドキュメントが答えていないこと

関連ガイド

コードとドキュメントを、一緒にランディング。