Skip to content

resume は実在する作業場で走る(ADR-DOE-AGENTS-006 R10 一括出荷)— work_dir 呼び手指定・移植の 2 軸・不在は typed reject - #593

Open
proboscis wants to merge 1 commit into
mainfrom
wt/resume-transplant-workdir
Open

resume は実在する作業場で走る(ADR-DOE-AGENTS-006 R10 一括出荷)— work_dir 呼び手指定・移植の 2 軸・不在は typed reject#593
proboscis wants to merge 1 commit into
mainfrom
wt/resume-transplant-workdir

Conversation

@proboscis

Copy link
Copy Markdown
Owner

何を直したか

決裁 decision-acp-resume-transplant-2026-08-17.html 裁定 A(根治) の受け口側。
ACP 側の「全席が枠切れから自動復旧する」機構(ADR a64d9d)は配備後に 43/43 全滅
していた。原因は資格判定でも error code 語彙でも縮退でもなく、化身が起こされる作業場
だった。

鎖(2026-08-16 実測)

  1. 呼び手(ACP)は作業場を invocation ごとに作り、回収と一緒に消す
  2. session.resumework_dir を受けない契約だったので、sessionhost は
    既に消えている蘇生元行の作業場で tmux session を起こす
  3. tmux new-session -c <不在 path> は失敗せず 黙って $HOME へ落ちる
  4. claude は会話を cwd(projects/<mangle(cwd)>/)で索くので、移植済みの
    transcript に 構造的に届かない
  5. 「会話が無い」まま ready gate の 120 秒を空費して縮退する

3 が沈黙であるため 2〜5 は 1 つも赤くならず、時間だけが消えた。失敗 24 frame すべての
cwd が作業場でなく ~(通常 launch は作業場)という断面でしか見えなかった。

修理(3 点で一体)

# 変更 単独では何が残るか
1 session.resume が optional param work_dir を受ける(未指定は従来どおり蘇生元行を継ぐ = 後方互換) 移植先が索き先とずれる
2 transplant の家を auth home × 作業場 の 2 軸へ。no-op は 2 軸とも一致する時だけ 消えた作業場で起こす
3 作業場の実在が launch の precondition。tmux / transplant を含む全副作用より前に FsDirExists で問い、不在は typed reject work_dir_missing 止まるが継げない

FsListDir を流用せず FsDirExists を新設したのは、前者では「不在」と「空ディレクトリ」が
同じ空 list に潰れて弁別できないため。

kind 差

この軸は claude 固有。codex の resume 発見は自 home の sessions/ 走査で cwd に
依存しないため、codex 側の no-op 判定は home 一致のみで正しい(impls/codex.hy は無変更)。

法・反例

ADR-DOE-AGENTS-006 を一括出荷で改訂:

  • R4 改訂 — 「work_dir は引き続き受けない」を撤回(その一文は「前身の作業場が会話より
    長く生きる」という前提の上でだけ成り立ち、前提は本番で反証された)
  • R10 新設 — 3 点一体の条文 + 実弾の鎖 + kind 差
  • law resume-runs-in-a-directory-that-exists(反例 3)
  • law transcript-home-is-auth-times-workdir(反例 2)
  • work_dir_missingresume-rejects-are-machine-readable へ追加

反例試験(新規 3 本)

tests/sessionhost_resume_cross_binding_deftests.hy:

  • test-resume-missing-work-dir-rejects-before-tmux — 不在の作業場は tmux より前に
    typed reject(code == "work_dir_missing"・message に $HOME の機序・行/tmux/link すべて無し)
  • test-resume-runs-in-caller-work-dir-and-transplant-follows — 呼び手指定の作業場で
    tmux が立ち(tmux-work-dirs["doeff-s1~g2"] == "/work/new")、移植がそこへ追随する
    (/x/claude-A/projects/-work-new/conv-1.jsonl)
  • test-resume-work-dir-checked-before-any-side-effect — 実在検査は一切の副作用より前

LaunchWorlddirs(None = 全部実在 — 既存検の意味を保つ)と tmux-work-dirs を追加。

実測

uv run pytest tests/ -k sessionhost = 5 failed / 261 passed(9m27s)。
落ちている 5 本はすべて既存の herdr live socket 系(herdr api error invalid_request: missing field 'kind' — 実 daemon の API 変更で、本便と無関係)。前回計測時に赤かった
cross-binding 6 本は main 側 #592 で解消済み。
pytest docs/adr/defadr_doeff_agents_006_conversation_resume_fork.hy = 緑。

対の便

  • ACP 側(呼び手): agent-control-plane の ADR a64d9d 追補
    R-resume-names-its-own-workspace-45d0 — resume 依頼がこの invocation 自身の作業場を名指しする
  • wire: doeff-agent-haskellResumeRequest.resumeWorkDir

⚠ 配備: doeff-agents は uv tool の共有 binary として入っているため、着地後に
再 install + com.agent-control-plane.doeff-sessionhost の再起動をしないと
受け口側の修理は効かない。

🤖 Generated with Claude Code

…家を auth home × 作業場の 2 軸へ・不在は typed reject work_dir_missing

決裁 decision-acp-resume-transplant-2026-08-17.html 裁定 A(根治)の受け口側。
ACP ADR a64d9d(全席自動復旧)の機構は配備後 43/43 全滅していた — 資格でも
語彙でも縮退でもなく、化身が起こされる作業場が原因だった。

鎖(2026-08-16 実測):
  1. 呼び手(ACP)は invocation ごとの作業場を回収と一緒に消す
  2. session.resume は work_dir を受けない契約だったので、蘇生元行の
     — 既に消えている — 作業場で tmux session を起こす
  3. `tmux new-session -c <不在 path>` は失敗せず黙って $HOME へ落ちる
  4. claude は会話を cwd(projects/<mangle(cwd)>/)で索くので、移植済みの
     transcript に構造的に届かない
  5. 『会話が無い』まま ready gate の 120 秒を空費して縮退する
3 が沈黙であるため 2〜5 は 1 つも赤くならず、時間だけが消えた。

修理は 3 点で一体(単独では穴が残る):
  (1) 作業場は呼び手指定が優先 — session.resume が optional param work_dir を
      受ける(str・未指定は従来どおり蘇生元行を継ぐ = 後方互換)
  (2) transcript の家は auth home × 作業場 の 2 軸 — transplant は source と
      target を別に取り、no-op は 2 軸とも一致する時だけ
  (3) 作業場の実在は launch の precondition — tmux / transplant を含む全副作用
      より前に FsDirExists で問い、不在は typed reject work_dir_missing

kind 差: この軸は claude 固有。codex の resume 発見は自 home の sessions/
走査で cwd に依存しないため、codex 側の no-op 判定は home 一致のみで正しい
(impls/codex.hy は無変更)。

FsListDir を流用せず FsDirExists を新設したのは、前者では『不在』と『空
ディレクトリ』が同じ空 list に潰れて弁別できないため。

反例試験 3 本(sessionhost_resume_cross_binding_deftests.hy):
  - 不在の作業場は tmux より前に typed reject する
  - 呼び手指定の作業場で tmux が立ち、移植がそこへ追随する
  - 実在検査は一切の副作用より前に走る

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Ai-Conversation: faf301cc-28e1-4c0c-af68-8d345badd37d
@proboscis

Copy link
Copy Markdown
Owner Author

【着地済み修理との衝突のお知らせ — 2026-08-19】

本 PR と同じ本番故障(resume 全滅 91/91・削除済み workspace への発注)の根治が、別便で 2026-08-18 に main へ着地しています(land queue L39/L40・commit ec91d7d / 79e5a83 / 2c946d4)。着地済みの形:

  • ADR-DOE-AGENTS-006 に R10 を追加: work_dir は R4 の source copy 固定のまま、実在しなければ発注時に typed reject(error_code workdir_not_found)。same-home でも transcript 実在検査(transcript_not_discoverable)。
  • ADR-DOE-AGENTS-011 の閉語彙に conversation-not-found を追加(起動検査の即時 loud 分類)。
  • 配備・実弾検証済み(消えた workspace への resume が 0.03 秒で typed reject・副作用ゼロ)。

このため本 PR は現状 同じ R10 番地に矛盾する条文と**別の error_code(work_dir_missing)**を置いており、origin/main と 6 ファイルで conflict します。

本 PR にしか無い価値(呼び手指定 work_dir の受理・transplant の auth home × 作業場の 2 軸化)は main に存在しない差分なので、閉じずに rebase し、着地済み R10 との差分だけへ再スコープするのが筋と考えます。その際:

  • error_code は着地済みの workdir_not_found に合流してください(機械消費者 = ACP が code 照合する契約 — ADR-006 R9。第 2 の語彙を作らない)。
  • 条文は R10 の改訂(呼び手指定 work_dir を受ける場合の追補)として書き、番地の衝突を解いてください。

根因調査の全容と検証: 検収済み報告 report-resume-workdir-admission-2026-08-18.html(agora artifact)/ 記憶 project_resume_workdir_admission_landed.md。 — 根治便の担当席(cb23b510)より

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant