Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,58 @@ Use an existing prepared UUID in the local owner's POSIX ledger. Status remains

Watch is read-only: no intents, waits, receipts, ledger writes, submission or wake. It adds no host/device/Windows route or Codex ACK. Limits are 16 KiB per frame and 256 KiB total with a 2 KiB end reserve. Real-fd stdout uses one owned isolated output-only Python helper that sees only bounded public serialized bytes, never changes shared descriptor flags and reads no ledger/native data. The parent enforces the original total budget including IPC, checks it before new ledger read/validation stages, and reserves 100 ms within it for final output and cleanup, so sampling may end earlier. It terminates and reaps its helper on timeout, SIGINT or error; uninterruptible OS operations prevent a hard-real-time guarantee. Partial or unacknowledged writes prohibit subsequent/end frames; consumers must reject truncated final NDJSON lines. Helper completion means OS write completion, not recipient consumption. Snapshots are not a lossless event stream, and local UTC observations do not prove ACK arrival order. See the [handoff runtime guide](handoff-runtime.md) for privacy, retained submission/ACK/wait meanings, read-only collector queries and the existing quarantine gate. Watch launches no native message process or collector. This candidate is not a published release. No payload/capability digests are exposed; public targetGeneration keeps its existing contract. The read-only ledger releases its shared lock after reading immutable snapshot bytes, before parsing and validation. Interrupted final output and cleanup are capped at 100 ms within the remaining total budget. Overall success requires a complete successful end frame and exit 0: cleanup may fail after that frame. A nonzero exit means overall failure, without promoting ACK, discarding independently valid submission facts or permitting retry.

### Trusted local SSH configuration (v1.3 candidate, not published)

On Linux and macOS, an explicit local CLI invocation of `list`, `send`, `doctor`,
or `update` with `--host` can select an existing OpenSSH configuration by pairing
`--ssh-config ABSOLUTE_PATH` with `--trust-ssh-config`. Both flags are required.
For example, using a placeholder path (quoted spaces are supported):

```bash
session-peer list --host worker --ssh-config '/home/alice/SSH Profiles/work.conf' --trust-ssh-config
session-peer doctor --host worker --ssh-config '/home/alice/SSH Profiles/work.conf' --trust-ssh-config --check-return-route
```

This grants local code-execution authority to the selected configuration:
`Match exec` can run even during `ssh -G` identity discovery or `send --dry-run`.
The operator must also trust `Include` files, `ProxyCommand`, and other external
dependencies. Validation is not a configuration sandbox and does not recursively
validate those dependencies. No existing profile or configuration file is edited.

The path must be absolute, with no `..` components, control characters, or
symlinks in any component. The selected file must be a regular file owned by the
current effective user, have exactly one hard link, be at most 64 KiB, and have
neither group/other write permissions nor setuid/setgid/sticky bits. Ancestor
directories must be owned by root or the current effective user and must not be
group/other writable, except for root-owned sticky directories. Linux rejects
extended access ACLs and directory default ACLs; macOS rejects allow ACL entries
and volumes with ownership disabled. ACL or ownership checks that cannot be
verified refuse the selection. These are conservative checks, not a full
effective-permissions interpreter.

One selection is reused throughout that CLI call for local `ssh -G` discovery,
doctor, remote listing/version checks, update probes/install/verification, and
send/handoff SSH calls. Before each SSH spawn it revalidates file identity,
metadata, content hash, and storage safety. Detected changes refuse the operation
without falling back to default configuration. OpenSSH opens the original path;
this is not an immutable byte snapshot and a same-user change between validation
and OpenSSH's read remains possible.

This mode forces `StrictHostKeyChecking=yes`, `UpdateHostKeys=no`,
`ForwardAgent=no`, `PermitLocalCommand=no`, and `BatchMode=yes`, and disables
connection multiplexing. Existing explicit host-key pins retain priority. The
`--ssh-opt` allowlist is unchanged: `-F` and `ProxyCommand` remain forbidden there.
The selected local path is not forwarded to the remote command, reply route, or
public JSON. Reverse doctor checks use the remote machine's own configuration;
they never inherit this path. Forward success does not prove reverse
authentication, message consumption, or an ACK.

Environment variables, MCP requests, ReplyTo addresses, and stored presets cannot
select this mode. Windows, `setup`, paired-device routes, preset combinations,
reply-URI destinations, and invocations without `--host` are rejected before
reading the configuration or starting SSH. Omitting the pair preserves the
existing default SSH behavior.

### Updating

For package-managed installs, use the same manager that installed the command:
Expand Down
2 changes: 1 addition & 1 deletion docs/i18n-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"docs/ai-assistant-guide.md": "9624ec96b92fb688fae3be3c94cb3564c77985091be451fbf1f056a1af9b9d9c",
"docs/antigravity.md": "f2b5122a0ce6e6fb5bd4d8ed50ce2c8bd2dc9c98ec8ce328405cf7c2cd24229d",
"docs/architecture/agent-transports.md": "01a4e3942e87acb476595859f2e37f9653ea1e3bc19ebc68dced1adf20a6966f",
"docs/cli-reference.md": "af1d3524bad9020dd4cb9ecb6b23db7207686ee956ae2215c21d01d79551ede1",
"docs/cli-reference.md": "5d4a52e5eda0e3287e45fd1d8bd852acee76af9917e759431efd84d247a73b0e",
"docs/compatibility-v1.md": "7e551aad37a369faff7e370728376763efb54c2c9e9cfd8556a0c19aabc3d103",
"docs/contracts/handoff-v1.md": "46a953010c49214bd8f969412f26713384fbe09a0ba78ebf0fef75da40d0d889",
"docs/diagnostics.md": "0949e53612eeab2cd7c7bbda498e14d71e9cb1b1189aa7722030cb8702cd8481",
Expand Down
19 changes: 19 additions & 0 deletions docs/ja/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,25 @@ session-peer handoff watch --correlation-id PREPARED_UUID --watch-timeout 30 --i

監視は読み取り専用で、intent・待機・受領確認の作成、記録の書き込み、提出や起動を行いません。ホスト・機器・Windows 経路や Codex ACK は追加しません。フレームは 16 KiB、総量は 256 KiB に制限し、終了用に 2 KiB を予約します。実ファイル記述子の標準出力には専用の分離された Python 出力補助プロセスを一つ使用します。サイズ制限付きの直列化された公開バイトだけを受け取り、共有記述子フラグを変えず、記録やネイティブデータも読みません。親は IPC を含め元の総予算を適用し、新しい記録読み取り・検証段階の前にも期限を確認します。総時間内に最終出力と終了処理用の 100 ms を確保するため、照会は早めに終わる場合があります。タイムアウト、SIGINT、エラー時には補助プロセスを終了・回収しますが、中断不能な OS 操作の厳密リアルタイム保証ではありません。部分書き込みや完了応答がない場合は終了を含む後続フレームを禁止し、利用側は切れた最後の NDJSON 行を拒否する必要があります。補助プロセスの完了は OS 書き込み完了であり、受信者の消費ではありません。スナップショットは全イベントを欠落なく伝えるストリームではなく、ローカル UTC 観測は ACK 到着順序を証明しません。プライバシー、保持する提出・ACK・待機の意味、読み取り専用コレクター照会、従来の隔離の制約は [handoff ランタイムガイド](handoff-runtime.md)を参照してください。監視はネイティブメッセージプロセスやコレクターを起動しません。この候補は公開リリースではありません。 ペイロード・権限のダイジェストは公開せず、公開 targetGeneration の既存契約は維持します。 読み取り専用記録は不変のスナップショットバイトを読み終えた後、解析・検証の前に共有ロックを解放します。 中断時の最終出力と終了処理は、残りの総予算内で最大 100 ms に制限します。 全体の成功には完全な成功終了フレームと終了コード 0 の両方が必要です。そのフレームの後に終了処理が失敗する場合があります。非ゼロの終了は全体の失敗であり、ACK を格上げしたり、独立して有効な提出事実を捨てたり、再試行を許可したりするものではありません。

### 信頼するローカル SSH 設定 (v1.3 候補、未公開)

Linux と macOS では、`--host` を指定したローカル CLI の `list`、`send`、`doctor`、`update` で、`--ssh-config ABSOLUTE_PATH` と `--trust-ssh-config` を併用して既存の OpenSSH 設定を選択できます。両方のフラグが必要です。次のパスは例であり、引用符で囲んだ空白も利用できます。

```bash
session-peer list --host worker --ssh-config '/home/alice/SSH Profiles/work.conf' --trust-ssh-config
session-peer doctor --host worker --ssh-config '/home/alice/SSH Profiles/work.conf' --trust-ssh-config --check-return-route
```

この選択は設定にローカルコード実行権限を与えます。`Match exec` は `ssh -G` によるユーザー確認や `send --dry-run` 中でも実行され得ます。運用者は `Include` ファイル、`ProxyCommand`、その他の外部依存先も信頼する必要があります。検証は設定のサンドボックスではなく、依存先を再帰的に検証しません。既存のプロファイルや設定ファイルは編集しません。

絶対パスが必要で、`..` 要素、制御文字、パス内のシンボリックリンクは許可しません。選択したファイルは現在の実効ユーザーが所有する通常ファイルで、ハードリンク数が 1、最大 64 KiB である必要があります。グループ・その他の書き込み権限、および setuid/setgid/sticky ビットも拒否します。祖先ディレクトリは root または現在の実効ユーザーの所有で、グループ・その他から書き込み不可である必要があります。ただし root 所有の sticky ディレクトリは例外です。Linux では拡張アクセス ACL とディレクトリのデフォルト ACL、macOS では allow ACL エントリと所有権が無効のボリュームを拒否します。ACL や所有権を確認できない場合も拒否します。これは保守的な検査であり、実効権限の完全な解釈ではありません。

同じ CLI 呼び出し内で、ローカル `ssh -G` 照会、doctor、リモート一覧・バージョン確認、更新の調査・インストール・検証、send/handoff の SSH に同じ選択を使います。各 SSH 起動前にファイルの識別情報、メタデータ、内容ハッシュ、保存場所の安全性を再検証します。変更を検出すると、既定設定にフォールバックせず拒否します。OpenSSH は元のパスを開きます。不変のバイトスナップショットではなく、検証から OpenSSH の読み取りまでの間に同じユーザーが変更する競合は残ります。

このモードでは `StrictHostKeyChecking=yes`、`UpdateHostKeys=no`、`ForwardAgent=no`、`PermitLocalCommand=no`、`BatchMode=yes` を強制し、接続の多重化を無効にします。既存の明示的なホスト鍵固定が優先されます。`--ssh-opt` の許可リストは変更せず、そこでの `-F` と `ProxyCommand` は引き続き禁止します。選択したローカルパスはリモートコマンド、返信経路、公開 JSON に渡しません。逆方向の doctor はリモート側自身の設定を使用し、このパスを継承しません。順方向の成功は逆方向の認証、メッセージ消費、ACK を証明しません。

環境変数、MCP リクエスト、ReplyTo アドレス、保存済みプリセットからは選択できません。Windows、`setup`、ペアリング済みデバイス経路、プリセットとの併用、返信 URI 宛先、`--host` のない呼び出しは、設定を読む前および SSH 起動前に拒否します。両フラグを省略した場合は従来の既定 SSH 動作を維持します。

<a id="updating"></a>
### 更新

Expand Down
19 changes: 19 additions & 0 deletions docs/ko/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,25 @@ session-peer handoff watch --correlation-id PREPARED_UUID --watch-timeout 30 --i

감시는 읽기 전용이며 의도·대기·수신 확인 생성, 기록 쓰기, 제출·깨우기를 수행하지 않습니다. 호스트·기기·Windows 경로나 Codex ACK를 추가하지 않습니다. 프레임은 16 KiB, 전체는 256 KiB로 제한하고 종료용 2 KiB를 남깁니다. 실제 파일 디스크립터 표준 출력에는 전용 격리 Python 출력 보조 프로세스 하나를 사용합니다. 크기가 제한된 직렬화된 공개 바이트만 받고 공유 디스크립터 플래그를 바꾸거나 기록·네이티브 데이터를 읽지 않습니다. 부모는 IPC까지 원래 총예산으로 제한하고 새 기록 읽기·검증 단계 전에도 기한을 확인합니다. 총 시간 안에서 최종 출력·정리에 100 ms를 남기므로 조회는 더 일찍 끝날 수 있습니다. 시간 초과·SIGINT·오류 시 보조 프로세스를 종료·회수합니다. 다만 중단할 수 없는 OS 작업이 있어 엄격한 실시간 보장을 제공하지는 못합니다. 부분 쓰기나 완료 응답 부재 시 종료를 포함한 후속 프레임을 금지하며 소비자는 잘린 마지막 NDJSON 줄을 거부해야 합니다. 보조 프로세스 완료는 OS 쓰기 완료이며 수신자 소비의 증거가 아닙니다. 스냅샷은 모든 이벤트를 빠짐없이 전달하는 스트림이 아니며 로컬 UTC 관측은 ACK 도착 순서의 증거가 아닙니다. 개인정보, 유지되는 제출·ACK·대기의 의미, 읽기 전용 수집기 조회와 기존 격리 조건은 [handoff 런타임 가이드](handoff-runtime.md)를 참고하세요. 감시는 네이티브 메시지 프로세스나 수집기를 시작하지 않습니다. 이 후보는 배포된 릴리스가 아닙니다. 페이로드·권한 다이제스트를 노출하지 않으며 공개 targetGeneration의 기존 계약은 유지합니다. 읽기 전용 기록은 불변 스냅샷 바이트를 읽은 뒤 파싱·검증 전에 공유 잠금을 해제합니다. 중단 시 최종 출력·정리는 남은 총예산 안에서 최대 100 ms로 제한합니다. 전체 성공에는 완전한 성공 종료 프레임과 종료 코드 0이 모두 필요합니다. 해당 프레임 뒤에도 정리가 실패할 수 있습니다. 0이 아닌 종료는 전체 실패이며 ACK를 상향 해석하거나 독립적으로 유효한 제출 사실을 버리거나 재시도해도 된다는 뜻은 아닙니다.

### 신뢰하는 로컬 SSH 설정 (v1.3 후보, 미출시)

Linux와 macOS에서는 `--host`를 지정한 로컬 CLI의 `list`, `send`, `doctor`, `update` 호출에서 `--ssh-config ABSOLUTE_PATH`와 `--trust-ssh-config`를 함께 사용해 기존 OpenSSH 설정을 선택할 수 있습니다. 두 플래그가 모두 필요합니다. 다음은 예시 경로이며, 따옴표로 감싼 공백도 지원합니다.

```bash
session-peer list --host worker --ssh-config '/home/alice/SSH Profiles/work.conf' --trust-ssh-config
session-peer doctor --host worker --ssh-config '/home/alice/SSH Profiles/work.conf' --trust-ssh-config --check-return-route
```

이 선택은 해당 설정에 로컬 코드 실행 권한을 부여합니다. `Match exec`는 `ssh -G` 사용자 확인이나 `send --dry-run` 중에도 실행될 수 있습니다. 운영자는 `Include` 파일, `ProxyCommand`, 기타 외부 의존성도 신뢰해야 합니다. 검증은 설정 샌드박스가 아니며 의존성을 재귀적으로 검증하지 않습니다. 기존 프로필이나 설정 파일을 수정하지 않습니다.

경로는 절대 경로여야 하며 `..` 구성 요소, 제어 문자, 경로 내 심볼릭 링크를 허용하지 않습니다. 선택한 파일은 현재 유효 사용자가 소유한 일반 파일이어야 하고, 하드 링크 수가 정확히 1개이며, 최대 64 KiB여야 합니다. 그룹·다른 사용자 쓰기 권한과 setuid/setgid/sticky 비트도 거부합니다. 상위 디렉터리는 root 또는 현재 유효 사용자 소유여야 하며 그룹·다른 사용자 쓰기가 금지되어야 합니다. 단, root 소유의 sticky 디렉터리는 예외입니다. Linux에서는 확장 접근 ACL과 디렉터리 기본 ACL을 거부하고, macOS에서는 allow ACL 항목과 소유권이 비활성화된 볼륨을 거부합니다. ACL이나 소유권을 확인할 수 없어도 거부합니다. 이는 보수적 검사이며 전체 유효 권한 해석기는 아닙니다.

하나의 CLI 호출에서 같은 선택을 로컬 `ssh -G` 조회, doctor, 원격 목록·버전 확인, 업데이트 탐색·설치·검증, send/handoff SSH 호출에 재사용합니다. 매 SSH 실행 전에 파일 식별 정보·메타데이터·내용 해시와 저장 경로 안전성을 다시 확인합니다. 변경을 발견하면 기본 설정으로 대체하지 않고 거부합니다. OpenSSH는 원래 경로를 열기 때문에 불변 바이트 스냅샷이 아니며, 검증과 OpenSSH 읽기 사이에 같은 사용자가 변경하는 경쟁 조건은 남습니다.

이 모드는 `StrictHostKeyChecking=yes`, `UpdateHostKeys=no`, `ForwardAgent=no`, `PermitLocalCommand=no`, `BatchMode=yes`를 강제하고 연결 다중화를 비활성화합니다. 기존 명시적 호스트 키 고정이 우선합니다. `--ssh-opt` 허용 목록은 그대로이며, 여기서 `-F`와 `ProxyCommand`는 계속 금지됩니다. 선택한 로컬 경로는 원격 명령·응답 경로·공개 JSON으로 전달되지 않습니다. 역방향 doctor 검사는 원격 장비 자체 설정을 사용하고 이 경로를 상속하지 않습니다. 정방향 성공은 역방향 인증, 메시지 소비, ACK를 입증하지 않습니다.

환경 변수, MCP 요청, ReplyTo 주소, 저장된 프리셋에서는 이 모드를 선택할 수 없습니다. Windows, `setup`, 페어링된 기기 경로, 프리셋 조합, 응답 URI 대상, `--host` 없는 호출은 설정을 읽거나 SSH를 시작하기 전에 거부됩니다. 두 플래그를 생략하면 기존 기본 SSH 동작을 유지합니다.

<a id="updating"></a>
### 업데이트

Expand Down
Loading
Loading