From d9db433031776ca7e449f1571db4d7101887bf2f Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Mon, 19 Oct 2026 13:55:31 +0900 Subject: [PATCH 1/6] chore(release): draft v1.2.1 preparation pending integration --- README.ja.md | 6 +-- README.ko.md | 6 +-- README.md | 6 +-- README.zh-CN.md | 6 +-- RELEASING.ja.md | 12 ++++- RELEASING.ko.md | 12 ++++- RELEASING.md | 12 ++++- RELEASING.zh-CN.md | 12 ++++- docs/README.md | 4 +- docs/i18n-manifest.json | 9 ++-- docs/ja/README.md | 4 +- docs/ja/releases/v1.2.0.md | 8 ++- docs/ja/releases/v1.2.1.md | 33 ++++++++++++ docs/ko/README.md | 4 +- docs/ko/releases/v1.2.0.md | 8 ++- docs/ko/releases/v1.2.1.md | 33 ++++++++++++ docs/releases/v1.2.0.md | 8 ++- docs/releases/v1.2.1.md | 33 ++++++++++++ docs/zh-CN/README.md | 4 +- docs/zh-CN/releases/v1.2.0.md | 8 ++- docs/zh-CN/releases/v1.2.1.md | 33 ++++++++++++ session_peer.py | 2 +- session_peer_core/common.py | 2 +- tests/docs/test_docs_i18n.py | 2 +- tests/docs/test_release_commands.py | 13 +++++ tests/docs/test_stable_candidate.py | 78 ++++++++++++++++++++++------- 26 files changed, 310 insertions(+), 48 deletions(-) create mode 100644 docs/ja/releases/v1.2.1.md create mode 100644 docs/ko/releases/v1.2.1.md create mode 100644 docs/releases/v1.2.1.md create mode 100644 docs/zh-CN/releases/v1.2.1.md diff --git a/README.ja.md b/README.ja.md index f038bff..7055ba2 100644 --- a/README.ja.md +++ b/README.ja.md @@ -34,11 +34,11 @@ session-peer 1.0.2による実際のローカル通信です。CodexがClaude Co ### インストール Python 3.9以上が必要です。基本のローカル・SSH CLIに外部Python依存パッケージはありません。 -ソースバージョン:**1.2.0**。2026-10-16の公開状況の確認時点で、最後に確認した公開済み安定版は**1.1.2**でした。 +ソースバージョン:**1.2.1**。2026-10-19の公開状況の確認時点で、最後に確認した公開済み安定版は**1.2.0**でした。 -公開済みメンテナンス版1.1.2は#298を修正します。[過去の準備記録](docs/ja/releases/v1.1.2.md)を参照してください。パッケージ公開と本番環境への配備は別です。 +公開済み1.2.0の[公開記録・過去の準備](docs/ja/releases/v1.2.0.md)を参照してください。パッケージ公開と本番環境への配備は別です。 -入手できるバージョンは[GitHub Releases](https://github.com/abruption/session-peer/releases)と[PyPI](https://pypi.org/project/session-peer/)で確認してください。[準備記録](docs/ja/releases/v1.2.0.md)は記載日時点の範囲と残る条件を説明します。ソースのバージョンだけではパッケージの公開状況は確認できません。 +入手できるバージョンは[GitHub Releases](https://github.com/abruption/session-peer/releases)と[PyPI](https://pypi.org/project/session-peer/)で確認してください。[準備記録](docs/ja/releases/v1.2.1.md)は記載日時点のパッチ範囲と残る条件を説明します。ソースのバージョンだけではパッケージの公開状況は確認できません。 実験的なhandoffは明示的に選択する機能です。ローカルPOSIX Claudeは受領ACKに対応し、CodexとSSHは相関IDによる送信のみ対応してACKの観察には対応しません。公開済みの範囲と残る検証条件は[handoffガイド](docs/ja/handoff-runtime.md)を参照してください。 diff --git a/README.ko.md b/README.ko.md index ef12026..43a67f3 100644 --- a/README.ko.md +++ b/README.ko.md @@ -34,11 +34,11 @@ session-peer 1.0.2를 사용해 실제 로컬 요청과 회신을 주고받았 ### 설치 Python 3.9 이상이 필요합니다. 기본 로컬·SSH CLI는 외부 Python 패키지에 의존하지 않습니다. -소스 버전: **1.2.0**. 2026-10-16 공개 상태 확인 시점의 마지막 확인 공개 안정판은 **1.1.2**였습니다. +소스 버전: **1.2.1**. 2026-10-19 공개 상태 확인 시점의 마지막 확인 공개 안정판은 **1.2.0**이었습니다. -공개된 유지보수 버전 1.1.2는 #298을 수정합니다. [과거 준비 기록](docs/ko/releases/v1.1.2.md)을 참고하십시오. 패키지 공개와 운영 배포는 별개입니다. +공개 버전 1.2.0의 [공개 증거 및 과거 준비 기록](docs/ko/releases/v1.2.0.md)을 참고하십시오. 패키지 공개와 운영 배포는 별개입니다. -설치할 수 있는 버전은 [GitHub Releases](https://github.com/abruption/session-peer/releases)와 [PyPI](https://pypi.org/project/session-peer/)에서 확인하십시오. [준비 기록](docs/ko/releases/v1.2.0.md)은 해당 날짜의 범위와 남은 조건을 설명하며, 소스 버전만으로 패키지 공개 여부가 확인되는 것은 아닙니다. +설치할 수 있는 버전은 [GitHub Releases](https://github.com/abruption/session-peer/releases)와 [PyPI](https://pypi.org/project/session-peer/)에서 확인하십시오. [준비 기록](docs/ko/releases/v1.2.1.md)은 해당 날짜의 패치 범위와 남은 조건을 설명하며, 소스 버전만으로 패키지 공개 여부가 확인되는 것은 아닙니다. 실험적 handoff는 명시적으로 선택해야 합니다. 로컬 POSIX Claude는 영수증 ACK를 지원하지만, Codex와 SSH는 상관 ID를 이용한 제출만 지원하며 ACK 관찰은 지원하지 않습니다. 공개된 범위와 남은 검증 조건은 [handoff 가이드](docs/ko/handoff-runtime.md)를 참고하십시오. diff --git a/README.md b/README.md index cc78339..c7b09f1 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,11 @@ in this ~22-second animation, not a screen recording; send success alone is not ### Install Python 3.9+. The core local/SSH CLI has no third-party Python dependencies. -Source version: **1.2.0**. At the 2026-10-16 publication checkpoint, the last verified published stable release was **1.1.2**. +Source version: **1.2.1**. At the 2026-10-19 publication checkpoint, the last verified published stable release was **1.2.0**. -Published maintenance version 1.1.2 addresses #298; see the [historical preparation notes](docs/releases/v1.1.2.md). Package publication and operational deployment are separate. +See the [publication record and historical preparation](docs/releases/v1.2.0.md) for published version 1.2.0. Package publication and operational deployment are separate. -Check [GitHub Releases](https://github.com/abruption/session-peer/releases) and [PyPI](https://pypi.org/project/session-peer/) for available versions. The [preparation notes](docs/releases/v1.2.0.md) record the dated scope and remaining gates; a source version alone does not establish package availability. +Check [GitHub Releases](https://github.com/abruption/session-peer/releases) and [PyPI](https://pypi.org/project/session-peer/) for available versions. The [preparation notes](docs/releases/v1.2.1.md) record the dated patch scope and remaining gates; a source version alone does not establish package availability. Experimental handoff is opt-in: local POSIX Claude supports receipt ACKs; Codex and SSH support correlation-only submission, not ACK observation. See the [handoff guide](docs/handoff-runtime.md) for the shipped scope and remaining acceptance gates. diff --git a/README.zh-CN.md b/README.zh-CN.md index 4c2365e..76c97ab 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -34,11 +34,11 @@ session-peer使用各智能体自身的收件箱和队列;接收方智能体 ### 安装 需要Python 3.9或更高版本。核心本地与SSH CLI没有第三方Python依赖。 -源码版本:**1.2.0**。在2026-10-16的发布状态检查时,最后确认的已发布稳定版本为**1.1.2**。 +源码版本:**1.2.1**。在2026-10-19的发布状态检查时,最后确认的已发布稳定版本为**1.2.0**。 -已发布的维护版本1.1.2修复#298;请参阅[历史准备记录](docs/zh-CN/releases/v1.1.2.md)。软件包发布与生产环境部署是两项独立操作。 +已发布的1.2.0请参阅[发布记录与历史准备](docs/zh-CN/releases/v1.2.0.md)。软件包发布与生产环境部署是两项独立操作。 -可用版本请查看[GitHub Releases](https://github.com/abruption/session-peer/releases)和[PyPI](https://pypi.org/project/session-peer/)。[准备记录](docs/zh-CN/releases/v1.2.0.md)说明记录日期时的范围与剩余门禁;仅凭源码版本不能确认软件包是否已发布。 +可用版本请查看[GitHub Releases](https://github.com/abruption/session-peer/releases)和[PyPI](https://pypi.org/project/session-peer/)。[准备记录](docs/zh-CN/releases/v1.2.1.md)说明记录日期时的补丁范围与剩余门禁;仅凭源码版本不能确认软件包是否已发布。 实验性handoff需要明确选择启用:本地POSIX Claude支持收据ACK;Codex与SSH仅支持关联标识提交,不支持ACK观察。已发布范围与剩余验收条件请参阅[handoff指南](docs/zh-CN/handoff-runtime.md)。 diff --git a/RELEASING.ja.md b/RELEASING.ja.md index c8c2d1e..c84a5c9 100644 --- a/RELEASING.ja.md +++ b/RELEASING.ja.md @@ -30,7 +30,17 @@ gh release edit v1.1.2 --repo abruption/session-peer \ --draft=false --prerelease=false --latest ``` -## v1.2.0候補 — 未公開 +## v1.2.1準備 — 公開権限なし + +公開済み1.2.0を基準に2026-10-19に準備しました。[候補ノート](docs/ja/releases/v1.2.1.md)はPR #319/#317(macOS Orca Claudeの制限付き検索)、#320/#318(制限付きスキルfrontmatter)、#303/#302(正本の互換スキル0.3.3)を記録します。統合ソース基準`PENDING`は最終準備・公開コミットではありません。プラグイン・スキルのバージョンはPython 1.2.1と独立し、グローバル導入や本番配備は含みません。 + +順次統合後に最終コミット検証、独立レビュー、パッケージ導入検査、最新依存関係監査を実行します。別途承認された準備PRのマージ後、正確な保護mainのCI成功が必要です。2026-10-19のタグ・PyPI未使用確認は日時点の観察であり、バージョン予約ではありません。現在の非公開Trusted Publisher設定の検証は主張せず、必須の人手pypi環境承認を維持します。#316と残るnative・handoff受け入れ条件は別で、この準備では閉じません。 + +この節は実行用コマンドを提供せず、マージ、タグ・ドラフト作成、ワークフロー実行、公開・配備を承認しません。別途承認後に全ゲートを再確認し、実行依頼後はattach-draft成功まで停止して、不変資産7個、SHA256SUMS、release-provenance.jsonと認証された証明を正確なタグ・コミットと照合します。ローカル準備ビルドは公開用資産ではなく、公開完了を先に宣言したりメタデータ変更のため不変資産を置換したりしません。 + +## v1.2.0 — 公開記録と過去の準備 + +GitHubは`4fc526f36afc65bb6ec460439eb0986c09ecc8ee`から安定・不変のv1.2.0を2026-10-16 12:39:13 UTCに公開しました。PyPIのwheelは12:41:38.903354 UTC、sdistは12:41:40.537212 UTCにアップロードされました。2026-10-19の読み取り専用再確認で[GitHubリリース](https://github.com/abruption/session-peer/releases/tag/v1.2.0)と[PyPI記録](https://pypi.org/pypi/session-peer/1.2.0/json)を確認しました。以下の未公開・PR #315が未マージという表現は2026-10-15/16の準備時点の記録で、現在の状態や実行指示ではありません。v1.2.0の再利用や不変資産の変更は禁止します。 公開版1.1.2を基に2026-10-15に準備しました。マイルストーン目標は2026-10-18で、公開の約束ではありません。PR #305、#311、#310、#308、#313、#314をこの順にマージし、正確なマージコミットを[候補ノート](docs/ja/releases/v1.2.0.md)に記録しました。このバージョン・文書のみの準備にはmainの対象変更が含まれます。Issue #180、#181、#268、#304、#306、#307は未完了のままです。 diff --git a/RELEASING.ko.md b/RELEASING.ko.md index e22ed12..bf04fcd 100644 --- a/RELEASING.ko.md +++ b/RELEASING.ko.md @@ -30,7 +30,17 @@ gh release edit v1.1.2 --repo abruption/session-peer \ --draft=false --prerelease=false --latest ``` -## v1.2.0 후보 — 미공개 +## v1.2.1 준비 — 공개 권한 없음 + +공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. [후보 노트](docs/ko/releases/v1.2.1.md)는 PR #319/#317(macOS Orca Claude의 제한된 검색), #320/#318(제한된 스킬 frontmatter), #303/#302(정본 호환 스킬 0.3.3)을 기록합니다. 통합 소스 기준 `PENDING`은 최종 준비·공개 커밋이 아닙니다. 플러그인·스킬 버전은 Python 1.2.1과 별개이며 전역 설치나 운영 배포는 포함하지 않습니다. + +순차 통합 후 최종 커밋 검증·독립 검수·패키지 설치 검사·최신 의존성 감사를 수행합니다. 별도 승인으로 준비 PR을 병합한 뒤 정확한 보호 main의 CI 성공이 필요합니다. 2026-10-19 태그·PyPI 미사용 검사는 해당 시점의 관찰이지 버전 예약이 아닙니다. 현재 비공개 Trusted Publisher 검증은 주장하지 않으며 필수 사람 pypi 환경 승인은 유지합니다. #316과 남은 native·handoff 수락 조건은 별개이며 이 준비로 닫지 않습니다. + +이 절에는 실행용 릴리스 명령이 없으며 병합, 태그·초안 생성, 워크플로 실행 요청, 공개·배포를 승인하지 않습니다. 별도 승인 후 모든 조건을 재확인하고 실행 요청 뒤 attach-draft 성공까지 멈추며 불변 자산 7개, SHA256SUMS, release-provenance.json과 인증된 증명을 정확한 태그·커밋에 대조합니다. 로컬 준비 빌드는 게시할 릴리스 자산이 아니며 공개 완료를 미리 선언하거나 메타데이터 갱신을 위해 불변 자산을 교체하지 않습니다. + +## v1.2.0 — 공개 기록 및 과거 준비 + +GitHub는 `4fc526f36afc65bb6ec460439eb0986c09ecc8ee`에서 정식·불변 v1.2.0을 2026-10-16 12:39:13 UTC에 공개했습니다. PyPI wheel은 12:41:38.903354 UTC, sdist는 12:41:40.537212 UTC에 업로드됐습니다. 2026-10-19 읽기 전용 재확인으로 [GitHub 릴리스](https://github.com/abruption/session-peer/releases/tag/v1.2.0)와 [PyPI 기록](https://pypi.org/pypi/session-peer/1.2.0/json)을 확인했습니다. 아래의 미공개·PR #315 열림 문구는 2026-10-15/16 준비 당시 기록을 보존한 것이며 현재 상태나 실행 지시가 아닙니다. v1.2.0을 재사용하거나 불변 자산을 수정하지 마십시오. 공개 버전 1.1.2를 기준으로 2026-10-15에 준비했습니다. 마일스톤 목표는 2026-10-18이며 공개 약속이 아닙니다. PR #305, #311, #310, #308, #313, #314를 이 순서로 병합했으며 정확한 병합 커밋은 [후보 노트](docs/ko/releases/v1.2.0.md)에 기록했습니다. 이 버전·문서 전용 준비는 main의 해당 변경을 포함합니다. 이슈 #180, #181, #268, #304, #306, #307은 열린 상태로 유지합니다. diff --git a/RELEASING.md b/RELEASING.md index 264c508..b88b661 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -30,7 +30,17 @@ gh release edit v1.1.2 --repo abruption/session-peer \ --draft=false --prerelease=false --latest ``` -## v1.2.0 candidate — unpublished +## v1.2.1 preparation — no publication authorization + +Prepared on 2026-10-19 against published 1.2.0. The [candidate notes](docs/releases/v1.2.1.md) record PR #319/#317 (bounded macOS Orca Claude inventory), #320/#318 (bounded skill frontmatter) and #303/#302 (canonical compatibility skill 0.3.3). Integrated source base: `PENDING`, not the final preparation or publication commit. Plugin and skill versions remain independent of Python 1.2.1; no global installation or operational deployment is included. + +Finish sequential integration before final-head validation, independent review, package installation checks and current dependency audits. Require successful CI on the exact protected main after a separately authorized preparation-PR merge. The 2026-10-19 unused-tag/PyPI checks are dated observations, not a version reservation. No current private Trusted Publisher verification is claimed; the required human pypi environment approval remains mandatory. #316 and the remaining native/handoff acceptance gates remain separate and unclosed by this preparation. + +This section supplies no executable release commands and authorizes no merge, tag/draft creation, workflow dispatch, publication or deployment. After separate authorization, recheck all gates, stop after dispatch until attach-draft succeeds, and review all seven immutable assets, SHA256SUMS, release-provenance.json and authenticated attestations against the exact tag/commit. Local preparation builds are not publishable release assets; do not announce publication or replace immutable assets to update metadata. + +## v1.2.0 — published record and historical preparation + +GitHub published stable, immutable v1.2.0 on 2026-10-16 at 12:39:13 UTC from `4fc526f36afc65bb6ec460439eb0986c09ecc8ee`; PyPI uploaded the wheel at 12:41:38.903354 UTC and sdist at 12:41:40.537212 UTC. The 2026-10-19 read-only recheck confirmed the [GitHub release](https://github.com/abruption/session-peer/releases/tag/v1.2.0) and [PyPI record](https://pypi.org/pypi/session-peer/1.2.0/json). The candidate wording below, including unpublished and PR #315 remaining open, preserves the 2026-10-15/16 preparation snapshot, not current status or instructions. Never reuse v1.2.0 or modify its immutable assets. Prepared on 2026-10-15 against published 1.1.2. The milestone target is 2026-10-18, not a publication promise. PR #305, #311, #310, #308, #313 and #314 are now merged in that order; their exact merge commits are recorded in the [candidate notes](docs/releases/v1.2.0.md). This version/docs-only preparation incorporates those changes from main. Issues #180, #181, #268, #304, #306 and #307 remain open. diff --git a/RELEASING.zh-CN.md b/RELEASING.zh-CN.md index 4cdfdd1..641e75a 100644 --- a/RELEASING.zh-CN.md +++ b/RELEASING.zh-CN.md @@ -30,7 +30,17 @@ gh release edit v1.1.2 --repo abruption/session-peer \ --draft=false --prerelease=false --latest ``` -## v1.2.0候选版本 — 尚未发布 +## v1.2.1准备 — 无发布权限 + +于2026-10-19基于已发布的1.2.0准备。[候选说明](docs/zh-CN/releases/v1.2.1.md)记录PR #319/#317(macOS Orca Claude有界搜索)、#320/#318(有界技能frontmatter)、#303/#302(正本兼容技能0.3.3)。集成源码基准`PENDING`不是最终准备或发布提交。插件与技能版本独立于Python 1.2.1,不包括全局安装或生产部署。 + +顺序集成完成后执行最终提交验证、独立审核、软件包安装检查及最新依赖审计。另行批准并合并准备PR后,须通过准确受保护main的CI。2026-10-19的标签/PyPI未使用检查仅是当时观察,不是版本预留。不声称验证了当前私有Trusted Publisher绑定,仍须人工pypi环境批准。#316及剩余native/handoff验收条件独立,不因本准备关闭。 + +本节不提供可执行命令,也不授权合并、创建标签/草稿、派发工作流、发布或部署。另行批准后须复核所有门禁,派发后等待attach-draft成功,再核对7项不可变资产、SHA256SUMS、release-provenance.json及认证证明与准确标签/提交一致。本地准备构建不是发布资产,不得提前宣布发布或为更新元数据而替换不可变资产。 + +## v1.2.0 — 发布记录与历史准备 + +GitHub于2026-10-16 12:39:13 UTC从`4fc526f36afc65bb6ec460439eb0986c09ecc8ee`发布稳定、不可变的v1.2.0。PyPI wheel于12:41:38.903354 UTC、sdist于12:41:40.537212 UTC上传。2026-10-19只读复核确认了[GitHub版本](https://github.com/abruption/session-peer/releases/tag/v1.2.0)和[PyPI记录](https://pypi.org/pypi/session-peer/1.2.0/json)。下方尚未发布、PR #315仍开放等措辞保留的是2026-10-15/16准备时快照,不代表当前状态或执行指令。不得重用v1.2.0或修改其不可变资产。 于2026-10-15基于已发布的1.1.2准备。里程碑目标为2026-10-18,并非发布承诺。PR #305、#311、#310、#308、#313、#314已按此顺序合并,准确合并提交记录于[候选说明](docs/zh-CN/releases/v1.2.0.md)。本次仅版本和文档的准备包含main中这些变更。议题#180、#181、#268、#304、#306、#307仍保持开放。 diff --git a/docs/README.md b/docs/README.md index a20eb6c..5048f1d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,9 @@ installation paths. ## Development and history -- [v1.2.0 candidate notes](releases/v1.2.0.md) record the unpublished preparation started on 2026-10-15 and updated on 2026-10-16, the merged six-PR scope and remaining acceptance gates. +- [v1.2.1 preparation notes](releases/v1.2.1.md) record the 2026-10-19 patch candidate for Orca Claude discovery, skill metadata reading and the compatibility skill copy; publication remains separate. + +- [v1.2.0 published record and historical preparation](releases/v1.2.0.md) record the 2026-10-16 publication separately from preparation started on 2026-10-15 and updated on 2026-10-16, the merged six-PR scope and remaining acceptance gates. - [v1.1.2 historical preparation notes](releases/v1.1.2.md) describe #298 and the 2026-10-13 preparation; v1.1.2 was subsequently published. Do not reuse its version or commands. diff --git a/docs/i18n-manifest.json b/docs/i18n-manifest.json index f53a8b1..4985bd4 100644 --- a/docs/i18n-manifest.json +++ b/docs/i18n-manifest.json @@ -7,10 +7,10 @@ "zh-CN" ], "sources": { - "README.md": "38d513c6938fafb790d378c0981836adf1e77d0cee969e99a370930b4ed04299", - "RELEASING.md": "952730a3eb6dfcb1a456b50d6e4918221a07d8fe90b744fc7705c809ea4918d3", + "README.md": "9ccd334628d9bb03bba3a08d0fd67a46ab48124733e4cf0b6565f034680db441", + "RELEASING.md": "b0682b5f68e72730fb060da69bb71eca60cff8b9638bbc6a34ee9d89b447a96c", "SECURITY.md": "8f018f6f98002312e143609b9734aeb971ca5217e146597c06b57b5645031046", - "docs/README.md": "e843d78ac9258645e2b4b9251328880b8a645514a66ca3b2a5f1fff99ba37dbc", + "docs/README.md": "03a461054c1570741c2022685014a1b947f0234145b83f4c8297241d5edcf327", "docs/agent-adapters.md": "bf185d3121c94829bb412071a25c4d943302e10a6b2e713111e653b8f8c3ea91", "docs/ai-assistant-guide.md": "9624ec96b92fb688fae3be3c94cb3564c77985091be451fbf1f056a1af9b9d9c", "docs/antigravity.md": "f2b5122a0ce6e6fb5bd4d8ed50ce2c8bd2dc9c98ec8ce328405cf7c2cd24229d", @@ -50,7 +50,8 @@ "docs/releases/v1.1.0.md": "66e66c4ca2d18b4da03c169885443ce26af49885fae474e95476b9078e50252f", "docs/releases/v1.1.1.md": "e7d5b6060098be0d4db06a7c2845955ea46084cdecd3fe8e5dc6c44324c09cc0", "docs/releases/v1.1.2.md": "3ffe3d6daa8e403e9f3c5e83ec81c3afa9f10750627b31362990ec5b92326f3a", - "docs/releases/v1.2.0.md": "e91d7b6ec7468a3b1e7186bdbfb4802a898485a1f1fb2e198f831ea0863b2163", + "docs/releases/v1.2.0.md": "9a153493fb3d25306306a05f6c1f5672d7d7becfe008f371770ce2d13d7e9b38", + "docs/releases/v1.2.1.md": "7690a9e0602add79e66dd7436592dd3000b8bedebc1c308405f230d6d4fa1c47", "docs/validation/69-rc.md": "e490c6a9ad0fec9108b91c74922cedac7ddf214ed405f8f5523da22f48a4b222", "docs/validation/85-antigravity.md": "f89b175191cd98ab03d4029b487065133814b3c8dd8de8cd0a5cc367e2579e4f", "docs/wake.md": "cde135da2ea7be21c815bb265e694f737dbe467d8e76bb82eb118e3b86e29d22", diff --git a/docs/ja/README.md b/docs/ja/README.md index eb8d8c3..8eac137 100644 --- a/docs/ja/README.md +++ b/docs/ja/README.md @@ -23,7 +23,9 @@ ## 開発と履歴 -- [v1.2.0候補ノート](releases/v1.2.0.md)は2026-10-15に開始し2026-10-16に更新した未公開準備、マージ済み6件のPRの範囲と残る受け入れ条件を記録します。 +- [v1.2.1準備記録](releases/v1.2.1.md)は、Orca Claude検索・スキルメタデータ読み取り・互換スキルコピーの2026-10-19パッチ候補を記録し、公開は別です。 + +- [v1.2.0公開記録と過去の準備](releases/v1.2.0.md)は2026-10-16の公開と、2026-10-15に開始し2026-10-16に更新した準備、マージ済み6件のPRの範囲と残る受け入れ条件を区別します。 - [v1.1.2の過去の準備記録](releases/v1.1.2.md)は#298と2026-10-13の準備を説明します。その後v1.1.2は公開済みです。バージョンやコマンドを再利用しないでください。 diff --git a/docs/ja/releases/v1.2.0.md b/docs/ja/releases/v1.2.0.md index 0d76bbd..01d6fb6 100644 --- a/docs/ja/releases/v1.2.0.md +++ b/docs/ja/releases/v1.2.0.md @@ -1,4 +1,10 @@ -# v1.2.0リリース候補 +# v1.2.0 — 公開版と過去の準備 + +## 公開記録 + +2026-10-19の読み取り専用再確認で、安定・不変の[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)を確認しました。`4fc526f36afc65bb6ec460439eb0986c09ecc8ee`から2026-10-16 12:39:13 UTCに公開され、[PyPI 1.2.0記録](https://pypi.org/pypi/session-peer/1.2.0/json)のアップロードはwheelが12:41:38.903354 UTC、sdistが12:41:40.537212 UTCです。 + +以下の候補時点の記述は2026-10-15/16の過去の準備記録として維持します。未公開・PR #315が未マージという表現は現在の状態や再公開の指示ではありません。v1.2.0の再利用や、固定メタデータ変更のための不変資産の再構築・置換は禁止します。パッケージ公開に本番配備は含みません。 ## 範囲 diff --git a/docs/ja/releases/v1.2.1.md b/docs/ja/releases/v1.2.1.md new file mode 100644 index 0000000..c9e5dfd --- /dev/null +++ b/docs/ja/releases/v1.2.1.md @@ -0,0 +1,33 @@ +# v1.2.1 リリース候補 + +## 状態とソース + +公開済み1.2.0を基準に2026-10-19に準備しました。ソースの準備であり、公開完了の告知ではありません。最後に確認した安定版は[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)と[PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)です。 + +統合記録です(未確定の行はレビュー前に確定します)。統合ソースの基準は`PENDING`であり、最終準備・公開コミットではありません。 + +| PR | Issue | mainマージコミット | +| --- | --- | --- | +| #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | +| #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | +| #303 | #302 | `PENDING` | + +## パッチの範囲 + +- #319: 明示的な`CLAUDE_CONFIG_DIR`または`ANTHROPIC_CONFIG_DIR`がない場合、macOSの同じユーザーが所有する既知のOrcaプロファイルでnative Claude登録を検索します。明示指定の範囲・優先順位は維持します。制限付きメタデータ検索は一部失敗時も正常な行を残しますが、検索が不完全か生存記録が矛盾する場合はすべての送信先選択を拒否します。選択した記録・プロファイル・受信箱の証拠を保持して再確認します。通常のソケット別名は維持し、既存の任意世代検査の制限も維持します。検索は認証情報・会話履歴を読まず受信箱に接続せず、受信証明も提供しません。Orca自動検索は新しいWindows/Linux対応ではありません。 +- #320: 文書全体の大きさに依存せず、制限した先頭のスキルメタデータを読みます。16 KiBのヘッダー上限は区切りと改行を含み、先読みは最大1バイトです。完全なUTF-8ヘッダーだけを解釈し、読み取り不能・未終端・上限超過・不正UTF-8のヘッダーはunknownのままです。既存の限定的なフィールド抽出は汎用YAML検証器ではなく、従来認識した形式は維持します。既存のフィールド・管理者・シンボリックリンク動作を維持し、通常ファイル以外のメタデータはunknownとします。不正な数値フィールドは別の有効なフィールドを消しません。YAMLやスキル指示は実行しません。 +- #303: companion v0.3.3のソース`eb239fb358336d85b49bab2c80e4ea39037d1374`、SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`から互換スキルコピーを更新します。メタデータはPython 1.2.1と独立した0.3.3 / 最小0.9.1 / 全機能1.0.1です。グローバルインストールや管理者が所有するインストールの更新ではありません。 + +## 検証と制限 + +最終統合ソース、生成された単独CLI、翻訳ハッシュ、パッケージ内容とインストール済みCLIを確認します。別ブランチの成功はこの準備の証拠を代替しません。最終コミットCI、独立レビュー、最新の依存関係監査が必要で、別途承認された準備PRのマージ後には正確な保護mainのCIも必要です。ローカルビルドは予行検証の証拠であり、公開用資産ではありません。 + +#319最終候補のローカル全体実行は1,294テストOK・19スキップでしたが、asyncio AssertionErrorと無視されたunclosed socket・transport ResourceWarningも出力されました。その改訂の最初のログを残し、診断を隠すために再実行していません。#316は未解決で、テスト成功や無関係な変更は原因・修正を証明しません。#161と#180/#181/#268/#304/#306/#307の残る受け入れ条件は別です。過去のRC4 ACK証拠は20/21のままです。 + +一般的なCodex ACK・世代、初回入力前の配送、Antigravity安定対応、完全なnative・プラットフォーム受け入れは追加しません。固定handoff契約・fixtureは不変です。submitted/queuedは消費やACKではなく、unknownは自動再送を許可しません。プラグインのバージョンは独立です。所有するMacBookへのソース転送SSH検査では、導入やnative受信箱入力なしでメタデータ検索・任意世代メタデータ・明示指定範囲を確認しましたが、配送証拠ではありません。SSH・Relay・MCP経由の実エージェントメッセージ・ACK、OAuth・fleet・運用の受け入れは主張しません。パッケージ公開に本番配備は含まれず、Control/Relayや導入済み端末の更新には別の承認・検証が必要です。 + +## 公開の境界 + +2026-10-19の読み取り専用確認ではv1.2.1タグとPyPI 1.2.1記録はありませんでした。日時点の証拠であり、予約・将来保証・公開権限ではありません。現在の非公開Trusted Publisher設定の検証は主張しません。 + +実行用リリースコマンドは提供せず、この準備自身のマージ、タグ・ドラフト作成、ワークフロー実行、公開・配備も承認しません。別途承認後にバージョン未使用と保護を再確認し、正確なmain CIを要求して承認された準備ワークフローで構築し、attach-draft成功まで停止します。不変資産7個、SHA256SUMS、release-provenance.jsonと認証された証明を正確なタグ・コミットと照合します。必須の人手pypi環境承認を維持し、監査・保護を迂回しません。実際の公開証拠は別に記録し、固定メタデータを変更するために不変資産を再構築・置換しません。 diff --git a/docs/ko/README.md b/docs/ko/README.md index 69c9ad2..db977d8 100644 --- a/docs/ko/README.md +++ b/docs/ko/README.md @@ -23,7 +23,9 @@ ## 개발과 이력 -- [v1.2.0 후보 노트](releases/v1.2.0.md)는 2026-10-15에 시작해 2026-10-16에 갱신한 미공개 준비, 병합된 PR 6개 범위와 남은 수락 조건을 기록합니다. +- [v1.2.1 준비 기록](releases/v1.2.1.md)은 Orca Claude 검색·스킬 메타데이터 판독·호환 스킬 사본을 위한 2026-10-19 패치 후보를 설명하며 공개는 별도입니다. + +- [v1.2.0 공개 및 과거 준비 기록](releases/v1.2.0.md)은 2026-10-16 공개와 2026-10-15에 시작해 2026-10-16에 갱신한 준비, 병합된 PR 6개 범위와 남은 수락 조건을 구분합니다. - [v1.1.2 과거 준비 기록](releases/v1.1.2.md)은 #298과 2026-10-13 준비를 설명하며, 이후 v1.1.2가 공개됐습니다. 버전이나 명령을 재사용하지 마십시오. diff --git a/docs/ko/releases/v1.2.0.md b/docs/ko/releases/v1.2.0.md index f0d7260..2165625 100644 --- a/docs/ko/releases/v1.2.0.md +++ b/docs/ko/releases/v1.2.0.md @@ -1,4 +1,10 @@ -# v1.2.0 릴리스 후보 +# v1.2.0 — 공개 릴리스 및 과거 준비 + +## 공개 기록 + +2026-10-19 읽기 전용 재확인으로 정식·불변 [GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)을 확인했습니다. `4fc526f36afc65bb6ec460439eb0986c09ecc8ee`에서 2026-10-16 12:39:13 UTC에 공개됐으며 [PyPI 1.2.0 기록](https://pypi.org/pypi/session-peer/1.2.0/json)의 업로드 시각은 wheel 12:41:38.903354 UTC, sdist 12:41:40.537212 UTC입니다. + +아래 후보 문구는 2026-10-15/16의 과거 준비 기록으로 보존합니다. 미공개·PR #315 열림은 현재 상태나 공개 절차를 반복하라는 지시가 아닙니다. v1.2.0을 재사용하거나 고정 메타데이터 변경을 위해 불변 자산을 다시 빌드·교체하지 마십시오. 패키지 공개에는 운영 배포가 포함되지 않습니다. ## 범위 diff --git a/docs/ko/releases/v1.2.1.md b/docs/ko/releases/v1.2.1.md new file mode 100644 index 0000000..f368ad5 --- /dev/null +++ b/docs/ko/releases/v1.2.1.md @@ -0,0 +1,33 @@ +# v1.2.1 릴리스 후보 + +## 상태와 소스 + +공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. 이는 소스 준비이며 공개 완료 안내가 아닙니다. 마지막 확인 안정판은 [GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)과 [PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)입니다. + +통합 기록입니다(대기 행은 검토 전에 확정해야 합니다). 통합 소스 기준은 `PENDING`이며 최종 릴리스 준비·공개 커밋이 아닙니다. + +| PR | 이슈 | main 병합 커밋 | +| --- | --- | --- | +| #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | +| #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | +| #303 | #302 | `PENDING` | + +## 패치 범위 + +- #319: 명시적 `CLAUDE_CONFIG_DIR` 또는 `ANTHROPIC_CONFIG_DIR`이 없을 때 macOS의 알려진 같은 사용자 소유 Orca 프로필에서 native Claude 등록을 검색합니다. 명시적 범위와 우선순위는 유지합니다. 제한된 메타데이터 검색은 일부 실패 시 정상 행을 보존하지만 검색이 불완전하거나 살아 있는 기록이 충돌하면 모든 대상 선택을 거부합니다. 선택한 기록·프로필·수신함 증거를 유지하고 다시 확인합니다. 일반 소켓 별칭은 유지하되 기존 선택적 세대 검사 제한도 유지합니다. 검색은 인증정보·대화 기록을 읽거나 수신함에 연결하지 않으며 수신을 증명하지도 않습니다. Orca 프로필 자동 검색은 새로운 Windows/Linux 지원이 아닙니다. +- #320: 문서 전체 크기와 별개로 제한된 앞부분의 스킬 메타데이터를 읽습니다. 16 KiB 헤더 한도에는 구분자와 줄 끝이 포함되며 추가 확인은 최대 1바이트입니다. 완결된 UTF-8 헤더만 해석하며 읽을 수 없거나 닫히지 않았거나 한도를 넘거나 UTF-8이 잘못된 헤더는 unknown으로 유지합니다. 기존의 제한된 필드 추출은 일반 YAML 검증기가 아니며 이전에 인식하던 형식은 계속 인식합니다. 기존 필드·관리자·심볼릭 링크 동작은 유지하며 일반 파일이 아닌 입력의 메타데이터는 unknown으로 처리합니다. 잘못된 숫자 필드가 별도로 유효한 필드를 지우지 않습니다. YAML이나 스킬 지침은 실행하지 않습니다. +- #303: companion v0.3.3의 소스 `eb239fb358336d85b49bab2c80e4ea39037d1374`, SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`에서 호환 스킬 사본을 갱신합니다. 스킬 메타데이터는 Python 1.2.1과 별개인 0.3.3 / 최소 0.9.1 / 전체 1.0.1입니다. 전역 스킬 설치나 관리자가 소유한 설치의 갱신은 아닙니다. + +## 검증과 한계 + +최종 통합 소스, 생성된 독립 실행형 파일, 번역 해시, 패키지 내용과 설치된 CLI를 검토해야 합니다. 별도 브랜치의 검사 성공은 이번 준비의 증거를 대신하지 않습니다. 최종 커밋 CI·독립 검수·최신 의존성 감사가 남은 조건이며 별도 승인으로 준비 PR을 병합한 뒤에는 정확한 보호 main의 CI도 필요합니다. 로컬 빌드는 연습 검증의 증거이지 게시할 릴리스 자산이 아닙니다. + +#319 최종 후보의 로컬 전체 실행은 1,294개 테스트 OK와 skip 19개로 끝났지만 asyncio AssertionError와 무시된 unclosed socket·transport ResourceWarning도 출력했습니다. 해당 소스 개정의 최초 로그를 보존했으며 진단을 숨기기 위해 재실행하지 않았습니다. #316은 열려 있고 테스트 성공이나 무관한 변경만으로 원인·수정을 입증하지 않습니다. #161과 #180/#181/#268/#304/#306/#307의 남은 수락 조건은 별도입니다. 과거 RC4 ACK 증거는 20/21로 유지합니다. + +일반 Codex ACK·세대, 첫 입력 전 전달, Antigravity 정식 지원이나 완전한 native·플랫폼 수락을 추가하지 않습니다. 고정 handoff 계약·fixture는 불변이며 submitted/queued는 소비나 ACK가 아니고 unknown은 자동 재전송을 허용하지 않습니다. 플러그인 버전은 별개입니다. 소유한 MacBook의 소스 스트리밍 SSH 검사로 설치나 native 수신함 입력 없이 메타데이터 전용 검색·선택적 세대 메타데이터·명시적 경로 범위를 확인했지만 전달 증거는 아닙니다. SSH·Relay·MCP를 통한 실제 에이전트 메시지·ACK 수락이나 OAuth·fleet·운영 수락은 주장하지 않습니다. 패키지 공개에는 운영 배포가 포함되지 않으며 Control/Relay와 설치된 기기의 갱신은 별도 승인·검증이 필요합니다. + +## 공개 경계 + +2026-10-19 읽기 전용 검사에서는 v1.2.1 태그와 PyPI 1.2.1 기록이 없었습니다. 이는 해당 시점의 증거이지 예약·향후 보장·공개 권한이 아닙니다. 현재 비공개 Trusted Publisher 연결 검증은 주장하지 않습니다. + +이 준비에는 실행용 릴리스 명령을 제공하지 않으며 준비 PR 자체의 병합, 태그·초안 생성, 워크플로 실행 요청, 공개·배포를 승인하지 않습니다. 별도 승인 후 버전 미사용과 보호 설정을 재확인하고 정확한 main CI를 요구하며 승인된 준비 워크플로로 빌드한 뒤 attach-draft 성공까지 멈춥니다. 불변 자산 7개, SHA256SUMS, release-provenance.json과 인증된 증명을 정확한 태그·커밋과 대조합니다. 필수 사람 pypi 환경 승인을 유지하고 감사·보호 규칙을 우회하지 않습니다. 실제 공개 증거는 별도로 기록하며 고정 메타데이터를 바꾸기 위해 불변 자산을 다시 빌드하거나 교체하지 않습니다. diff --git a/docs/releases/v1.2.0.md b/docs/releases/v1.2.0.md index b2090bd..1503308 100644 --- a/docs/releases/v1.2.0.md +++ b/docs/releases/v1.2.0.md @@ -1,4 +1,10 @@ -# v1.2.0 release candidate +# v1.2.0 — published release and historical preparation + +## Publication record + +The 2026-10-19 read-only recheck confirmed stable, immutable [GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0), published on 2026-10-16 at 12:39:13 UTC from `4fc526f36afc65bb6ec460439eb0986c09ecc8ee`, and the [PyPI 1.2.0 record](https://pypi.org/pypi/session-peer/1.2.0/json): wheel 12:41:38.903354 UTC, sdist 12:41:40.537212 UTC. + +The remaining candidate-era text is preserved as the 2026-10-15/16 historical preparation snapshot. Its unpublished and PR #315 remains open wording is not current status or an instruction to repeat publication. Never reuse v1.2.0 or rebuild/replace its immutable assets to change frozen metadata. Package publication does not include operational deployment. ## Scope diff --git a/docs/releases/v1.2.1.md b/docs/releases/v1.2.1.md new file mode 100644 index 0000000..8120784 --- /dev/null +++ b/docs/releases/v1.2.1.md @@ -0,0 +1,33 @@ +# v1.2.1 release candidate + +## Status and source + +Prepared on 2026-10-19 against published 1.2.0. This is a source preparation, not a publication announcement. The last verified stable release is [v1.2.0 on GitHub](https://github.com/abruption/session-peer/releases/tag/v1.2.0) and [1.2.0 on PyPI](https://pypi.org/pypi/session-peer/1.2.0/json). + +Integration record (pending rows must be resolved before review). The integrated source base is `PENDING`; it is not the final release-preparation or publication commit. + +| PR | Issue | Main merge commit | +| --- | --- | --- | +| #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | +| #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | +| #303 | #302 | `PENDING` | + +## Patch scope + +- #319: discover native Claude registrations in known same-user Orca profiles on macOS when no explicit `CLAUDE_CONFIG_DIR` or `ANTHROPIC_CONFIG_DIR` selects a root. Explicit scope and precedence remain unchanged. Bounded metadata discovery preserves healthy rows on partial failure but refuses all target selection when inventory is incomplete or live records conflict. Selected record/profile and inbox evidence is retained and rechecked; ordinary socket aliases remain supported, while their existing optional-generation limitation remains. Discovery does not read credentials or transcripts, connect to an inbox, or prove receipt. Automatic Orca profile inventory is not new Windows/Linux support. +- #320: read bounded leading skill metadata independently of total document size. The 16 KiB header budget includes delimiters and line endings, with at most one extra byte of lookahead. Only the complete UTF-8 header is decoded; unreadable, unterminated, over-budget or invalid-UTF-8 headers remain unknown. Existing constrained field extraction is not a general YAML validator; legacy accepted forms remain accepted. Existing field, manager and symlink behavior is preserved; nonregular input yields unknown metadata, and an invalid numeric field does not erase a separately valid field. No YAML or skill instructions are executed. +- #303: refresh the compatibility skill copy from companion v0.3.3, source `eb239fb358336d85b49bab2c80e4ea39037d1374`, SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`. Skill metadata remains 0.3.3 / minimum 0.9.1 / full 1.0.1, independently of Python 1.2.1. This is not a global skill installation or manager-owned update. + +## Validation and limits + +Review the final integrated source, generated standalone, translation hashes, package contents and installed CLI; passing checks on separate branches do not certify this preparation. Final-head CI, independent review and current dependency audits are still gates, followed by exact protected-main CI after the separately authorized preparation-PR merge. Local builds are rehearsal evidence, not publishable release assets. + +A local full run of the final #319 candidate returned 1,294 tests OK with 19 skips, but also emitted an asyncio AssertionError and ignored unclosed-socket/transport ResourceWarnings. The first log for that revision was preserved, not rerun to hide diagnostics. #316 remains open; neither a passing test result nor unrelated changes establish a cause or fix. #161 and the remaining #180/#181/#268/#304/#306/#307 acceptance work are separate. Historical RC4 ACK evidence remains 20/21. + +This patch adds no general Codex ACK/generation, first-input delivery, Antigravity stable support or full native/platform acceptance. The frozen handoff contract and fixture remain unchanged; submitted/queued is not consumption or ACK, and unknown never permits automatic resend. Plugin versions remain independent. An owned MacBook source-streamed SSH check verified metadata-only discovery, optional generation metadata and explicit-root scope without installation or native inbox input; it is not delivery evidence. No live agent-message/ACK acceptance over SSH, Relay or MCP, or OAuth/fleet/operational acceptance, is claimed. Package publication does not include operational deployment; Control/Relay updates and installed-device changes require separate authorization and verification. + +## Publication boundary + +The 2026-10-19 read-only checks found no v1.2.1 tag or PyPI 1.2.1 record. This is dated evidence, not a reservation, future guarantee or publication permission. No current private Trusted Publisher binding verification is claimed. + +This preparation supplies no executable release commands and does not authorize its own merge, tag/draft creation, workflow dispatch, publication or deployment. After separate authorization, recheck version availability and protections, require exact-main CI, build through the authorized preparation workflow and stop until attach-draft succeeds. Review all seven immutable assets, SHA256SUMS, release-provenance.json and authenticated attestations against the exact tag/commit. Keep the required human pypi environment approval; do not bypass audits or protections. Record actual publication evidence separately and never rebuild or replace immutable assets to change their frozen metadata. diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index fdc0525..d45ab68 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -22,7 +22,9 @@ ## 开发与历史 -- [v1.2.0候选说明](releases/v1.2.0.md)记录于2026-10-15开始、2026-10-16更新的未发布准备、已合并的6项PR范围和剩余验收条件。 +- [v1.2.1准备记录](releases/v1.2.1.md)说明用于Orca Claude搜索、技能元数据读取及兼容技能副本的2026-10-19补丁候选;发布仍是独立步骤。 + +- [v1.2.0发布记录与历史准备](releases/v1.2.0.md)区分2026-10-16发布与2026-10-15开始、2026-10-16更新的准备、已合并的6项PR范围和剩余验收条件。 - [v1.1.2历史准备记录](releases/v1.1.2.md)介绍#298和2026-10-13的准备;此后v1.1.2已发布。不得重用该版本或命令。 diff --git a/docs/zh-CN/releases/v1.2.0.md b/docs/zh-CN/releases/v1.2.0.md index 4dc5d65..1484f64 100644 --- a/docs/zh-CN/releases/v1.2.0.md +++ b/docs/zh-CN/releases/v1.2.0.md @@ -1,4 +1,10 @@ -# v1.2.0发布候选版本 +# v1.2.0 — 已发布版本与历史准备 + +## 发布记录 + +2026-10-19只读复核确认了稳定、不可变的[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)。其于2026-10-16 12:39:13 UTC从`4fc526f36afc65bb6ec460439eb0986c09ecc8ee`发布;[PyPI 1.2.0记录](https://pypi.org/pypi/session-peer/1.2.0/json)的上传时间为wheel 12:41:38.903354 UTC、sdist 12:41:40.537212 UTC。 + +下方候选时期文本作为2026-10-15/16历史准备快照保留。尚未发布、PR #315仍开放的措辞不是当前状态或重复发布的指令。不得重用v1.2.0,也不得为改变固定元数据而重新构建或替换不可变资产。软件包发布不包括生产部署。 ## 范围 diff --git a/docs/zh-CN/releases/v1.2.1.md b/docs/zh-CN/releases/v1.2.1.md new file mode 100644 index 0000000..2b246ea --- /dev/null +++ b/docs/zh-CN/releases/v1.2.1.md @@ -0,0 +1,33 @@ +# v1.2.1 发布候选版本 + +## 状态与源码 + +于2026-10-19基于已发布的1.2.0准备。这是源码准备,不是发布完成公告。最后验证的稳定版本为[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)和[PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)。 + +集成记录如下(待定行必须在审核前确定)。集成源码基准为`PENDING`,并非最终发布准备或发布提交。 + +| PR | 议题 | main合并提交 | +| --- | --- | --- | +| #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | +| #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | +| #303 | #302 | `PENDING` | + +## 补丁范围 + +- #319:没有显式`CLAUDE_CONFIG_DIR`或`ANTHROPIC_CONFIG_DIR`时,在macOS中同一用户拥有的已知Orca档案内搜索native Claude注册。保留显式范围和优先级。有界元数据搜索在部分失败时保留正常行,但搜索不完整或存活记录冲突时拒绝所有目标选择。保留并重新检查所选记录、档案和收件箱证据。普通套接字别名仍受支持,其既有可选代际检查限制也保留。搜索不读取凭据或对话记录、不连接收件箱,也不证明收件。Orca自动档案枚举不是新的Windows/Linux支持。 +- #320:仅读取有界的起始技能元数据,不依赖文档总大小。16 KiB头部预算包含分隔符和行尾,最多额外预读1字节。只解码完整UTF-8头部;无法读取、未闭合、超限或无效UTF-8头部仍为unknown。既有受限字段提取不是通用YAML验证器,原先接受的形式仍被接受。保留既有字段、管理器和符号链接行为,非常规文件的元数据为unknown。错误数值字段不会清除另一个有效字段。不执行YAML或技能指令。 +- #303:从companion v0.3.3的源码`eb239fb358336d85b49bab2c80e4ea39037d1374`、SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`更新兼容技能副本。技能元数据为0.3.3 / 最低0.9.1 / 完整1.0.1,与Python 1.2.1独立。这不是全局技能安装或管理器拥有的安装更新。 + +## 验证与限制 + +须审核最终集成源码、生成的独立CLI、翻译哈希、包内容和已安装CLI。独立分支的成功不能验证本次准备。最终提交CI、独立审核及最新依赖审计仍是门禁;另行批准并合并准备PR后,还须准确受保护main的CI成功。本地构建仅是演练证据,不是可发布资产。 + +#319最终候选的本地全量运行返回1,294项测试OK、19项跳过,但也输出asyncio AssertionError及被忽略的unclosed socket/transport ResourceWarning。保留该源码修订的首份日志,未为隐藏诊断而重跑。#316仍开放;测试成功或无关变更不能证明原因或修复。#161和#180/#181/#268/#304/#306/#307剩余验收工作是独立事项。历史RC4 ACK证据保留20/21。 + +本补丁不增加通用Codex ACK/代际、首次输入前投递、Antigravity稳定支持或完整native/平台验收。固定handoff契约和fixture不变;submitted/queued不代表消费或ACK,unknown不允许自动重发。插件版本独立。对自有MacBook的源码流式SSH检查在不安装、不输入native收件箱的情况下验证了元数据搜索、可选代际元数据和显式目录范围,但不是投递证据。不声称SSH、Relay或MCP上的实际代理消息/ACK验收,或OAuth/fleet/运维验收。软件包发布不包括生产部署;Control/Relay和已安装设备的更新须另行授权并验证。 + +## 发布边界 + +2026-10-19只读检查未发现v1.2.1标签或PyPI 1.2.1记录。这是有日期的证据,不是预留、未来保证或发布权限。不声称验证了当前私有Trusted Publisher绑定。 + +本准备不提供可执行发布命令,也不授权准备自身合并、创建标签/草稿、派发工作流、发布或部署。另行授权后须复核版本未使用及保护设置,要求准确main CI,通过获批准备工作流构建并等待attach-draft成功。核对全部7项不可变资产、SHA256SUMS、release-provenance.json及认证证明与准确标签/提交一致。保留必需的人工pypi环境批准,不绕过审计或保护。另行记录实际发布证据,不为修改已固定元数据而重新构建或替换不可变资产。 diff --git a/session_peer.py b/session_peer.py index d045f89..f0fa51e 100644 --- a/session_peer.py +++ b/session_peer.py @@ -45,7 +45,7 @@ except ImportError: # Native Windows uses its own read-only writer inspection. fcntl = None -__version__ = "1.2.0" +__version__ = "1.2.1" GITHUB_REPO = "abruption/session-peer" # Claude Code refuses a same-machine message once its serialized form passes diff --git a/session_peer_core/common.py b/session_peer_core/common.py index 0fcadad..223b7a5 100644 --- a/session_peer_core/common.py +++ b/session_peer_core/common.py @@ -45,7 +45,7 @@ except ImportError: # Native Windows uses its own read-only writer inspection. fcntl = None -__version__ = "1.2.0" +__version__ = "1.2.1" GITHUB_REPO = "abruption/session-peer" # Claude Code refuses a same-machine message once its serialized form passes diff --git a/tests/docs/test_docs_i18n.py b/tests/docs/test_docs_i18n.py index 273532b..ecbc6e6 100644 --- a/tests/docs/test_docs_i18n.py +++ b/tests/docs/test_docs_i18n.py @@ -64,7 +64,7 @@ class DocumentationTranslationsTest(unittest.TestCase): def test_every_canonical_document_has_each_translation(self): sources = canonical_documents() - self.assertEqual(48, len(sources), "Update the translation manifest for new canonical docs") + self.assertEqual(49, len(sources), "Update the translation manifest for new canonical docs") canonical_docs = { path.relative_to(ROOT / "docs") for path in (ROOT / "docs").rglob("*.md") diff --git a/tests/docs/test_release_commands.py b/tests/docs/test_release_commands.py index dc84fa3..fab2fd9 100644 --- a/tests/docs/test_release_commands.py +++ b/tests/docs/test_release_commands.py @@ -15,6 +15,19 @@ class ReleaseCommands(unittest.TestCase): + def test_v121_preparation_has_no_executable_publication_instructions(self): + for name in ("RELEASING.md", "RELEASING.ko.md", "RELEASING.ja.md", "RELEASING.zh-CN.md"): + with self.subTest(document=name): + text = (ROOT / name).read_text(encoding="utf-8") + section = text[text.index("## v1.2.1"):text.index("## v1.2.0")] + self.assertNotIn("```", section) + self.assertNotRegex(section, r"(?m)^\s*(?:git\s+(?:tag|push)\b|gh\s+(?:release\b|workflow\s+run\b)|release_tag=)") + self.assertNotIn("PENDING", section) + for marker in ("2026-10-19", "1.2.1", "1.2.0", "#319", "#317", "#320", "#318", + "#303", "#302", "#316", "Trusted Publisher", "pypi", "attach-draft", + "SHA256SUMS", "release-provenance.json"): + self.assertIn(marker, section) + def test_historical_publication_requires_completed_preparation_and_asset_review(self): for name in ("RELEASING.md", "RELEASING.ko.md", "RELEASING.ja.md", "RELEASING.zh-CN.md"): with self.subTest(document=name): diff --git a/tests/docs/test_stable_candidate.py b/tests/docs/test_stable_candidate.py index e6e3349..a1f73b9 100644 --- a/tests/docs/test_stable_candidate.py +++ b/tests/docs/test_stable_candidate.py @@ -1,6 +1,7 @@ """Stable version and publication boundary agree across package and docs.""" from pathlib import Path +import re import unittest import session_peer @@ -10,6 +11,49 @@ class StableCandidate(unittest.TestCase): + def test_v121_preparation_records_patch_sources_and_publication_gates(self): + notes = [(ROOT / ("docs/" + locale + "releases/v1.2.1.md")).read_text(encoding="utf-8") + for locale in ("", "ko/", "ja/", "zh-CN/")] + expected_pairs = ((319, 317), (320, 318), (303, 302)) + for locale, text in zip(("", "ko/", "ja/", "zh-CN/"), notes): + with self.subTest(locale=locale): + self.assertNotIn("PENDING", text) + positions = [] + for pr, issue in expected_pairs: + row = re.search(r"\| #%d \| #%d \| `([0-9a-f]{40})` \|" % (pr, issue), text) + self.assertIsNotNone(row) + positions.append(row.start()) + self.assertIn(row.group(1), notes[0]) + self.assertEqual(positions, sorted(positions)) + for marker in ("1.2.1", "1.2.0", "2026-10-19", "macOS", "Windows/Linux", + "CLAUDE_CONFIG_DIR", "ANTHROPIC_CONFIG_DIR", "16 KiB", "UTF-8", + "0.3.3", "0.9.1", "1.0.1", "#316", "#161", "20/21", + "#180", "#181", "#268", "#304", "#306", "#307", "Control/Relay", + "pypi", "attach-draft", "SHA256SUMS", "release-provenance.json", + "eb239fb358336d85b49bab2c80e4ea39037d1374", + "15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f"): + self.assertIn(marker, text) + self.assertNotIn("```", text) + for marker in ("not a publication announcement", "No YAML or skill instructions are executed", + "refuses all target selection", "ordinary socket aliases remain supported", + "not publishable release assets", "required human pypi environment approval", + "not a reservation", "no executable release commands", + "does not authorize its own merge", "never rebuild or replace immutable assets"): + self.assertIn(marker, notes[0]) + + def test_v120_publication_addendum_does_not_erase_candidate_history(self): + for locale in ("", "ko/", "ja/", "zh-CN/"): + text = (ROOT / ("docs/" + locale + "releases/v1.2.0.md")).read_text(encoding="utf-8") + for marker in ("2026-10-19", "2026-10-16", "12:39:13 UTC", "12:41:38.903354 UTC", + "12:41:40.537212 UTC", "4fc526f36afc65bb6ec460439eb0986c09ecc8ee", + "https://github.com/abruption/session-peer/releases/tag/v1.2.0", + "https://pypi.org/pypi/session-peer/1.2.0/json", "#315", "2026-10-15"): + self.assertIn(marker, text) + english = (ROOT / "docs/releases/v1.2.0.md").read_text(encoding="utf-8") + self.assertIn("historical preparation snapshot", english) + self.assertIn("not current status", english) + self.assertIn("candidate is unpublished", english) + def test_v120_candidate_records_merged_scope_and_open_gates(self): source_base = "21a0be0c0c5bcb8bca214d90a873b7479d7ba97a" merged_prs = ( @@ -168,8 +212,8 @@ def test_completed_release_examples_are_explicitly_historical(self): def test_published_release_keeps_experimental_acceptance_gates(self): for suffix in ("", ".ko", ".ja", ".zh-CN"): text = (ROOT / ("README" + suffix + ".md")).read_text(encoding="utf-8") - self.assertIn("**1.1.2**", text) - self.assertIn("releases/v1.1.2.md", text) + self.assertIn("**1.2.0**", text) + self.assertIn("releases/v1.2.0.md", text) self.assertIn("handoff-runtime.md", text) self.assertIn("POSIX", text) self.assertNotIn("**1.0.4**", text) @@ -188,8 +232,8 @@ def test_published_release_keeps_experimental_acceptance_gates(self): self.assertIn(marker, english) def test_package_and_generated_core_version_agree(self): - self.assertEqual(session_peer.__version__, "1.2.0") - self.assertIn('__version__ = "1.2.0"', + self.assertEqual(session_peer.__version__, "1.2.1") + self.assertIn('__version__ = "1.2.1"', (ROOT / "session_peer_core/common.py").read_text(encoding="utf-8")) def test_all_current_readmes_and_runbooks_use_stable_version(self): @@ -197,7 +241,7 @@ def test_all_current_readmes_and_runbooks_use_stable_version(self): for stem in ("README", "RELEASING"): with self.subTest(stem=stem, suffix=suffix): text = (ROOT / (stem + suffix + ".md")).read_text(encoding="utf-8") - self.assertIn("1.1.2", text) + self.assertIn("1.2.0", text) self.assertNotIn("1.0.0rc4", text) if stem == "RELEASING": self.assertIn("--draft=false --prerelease=false --latest", text) @@ -220,18 +264,18 @@ def test_release_notes_keep_scope_and_limits_visible(self): def test_stable_release_keeps_operational_deployment_separate(self): profiles = ( - ("", "Source version: **1.2.0**.", - "At the 2026-10-16 publication checkpoint, the last verified published stable release was **1.1.2**.", - "Development candidate 1.2.0 is unpublished"), - (".ko", "소스 버전: **1.2.0**.", - "2026-10-16 공개 상태 확인 시점의 마지막 확인 공개 안정판은 **1.1.2**였습니다.", - "개발 후보 1.2.0은 미공개입니다"), - (".ja", "ソースバージョン:**1.2.0**。", - "2026-10-16の公開状況の確認時点で、最後に確認した公開済み安定版は**1.1.2**でした。", - "開発候補1.2.0は未公開です"), - (".zh-CN", "源码版本:**1.2.0**。", - "在2026-10-16的发布状态检查时,最后确认的已发布稳定版本为**1.1.2**。", - "开发候选版本1.2.0尚未发布"), + ("", "Source version: **1.2.1**.", + "At the 2026-10-19 publication checkpoint, the last verified published stable release was **1.2.0**.", + "Development candidate 1.2.1 is unpublished"), + (".ko", "소스 버전: **1.2.1**.", + "2026-10-19 공개 상태 확인 시점의 마지막 확인 공개 안정판은 **1.2.0**이었습니다.", + "개발 후보 1.2.1은 미공개입니다"), + (".ja", "ソースバージョン:**1.2.1**。", + "2026-10-19の公開状況の確認時点で、最後に確認した公開済み安定版は**1.2.0**でした。", + "開発候補1.2.1は未公開です"), + (".zh-CN", "源码版本:**1.2.1**。", + "在2026-10-19的发布状态检查时,最后确认的已发布稳定版本为**1.2.0**。", + "开发候选版本1.2.1尚未发布"), ) for suffix, source_version, dated_checkpoint, stale_unpublished in profiles: text = (ROOT / ("README" + suffix + ".md")).read_text(encoding="utf-8") From 3496cb0906e6831410b938c67bdde035b4878e75 Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Mon, 19 Oct 2026 14:04:27 +0900 Subject: [PATCH 2/6] chore(release): pin integrated v1.2.1 candidate --- RELEASING.ja.md | 2 +- RELEASING.ko.md | 2 +- RELEASING.md | 2 +- RELEASING.zh-CN.md | 2 +- docs/i18n-manifest.json | 4 ++-- docs/ja/releases/v1.2.1.md | 8 ++++---- docs/ko/releases/v1.2.1.md | 8 ++++---- docs/releases/v1.2.1.md | 4 ++-- docs/zh-CN/releases/v1.2.1.md | 4 ++-- tests/docs/test_stable_candidate.py | 12 +++++++++--- 10 files changed, 27 insertions(+), 21 deletions(-) diff --git a/RELEASING.ja.md b/RELEASING.ja.md index c84a5c9..ff2e8b7 100644 --- a/RELEASING.ja.md +++ b/RELEASING.ja.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1準備 — 公開権限なし -公開済み1.2.0を基準に2026-10-19に準備しました。[候補ノート](docs/ja/releases/v1.2.1.md)はPR #319/#317(macOS Orca Claudeの制限付き検索)、#320/#318(制限付きスキルfrontmatter)、#303/#302(正本の互換スキル0.3.3)を記録します。統合ソース基準`PENDING`は最終準備・公開コミットではありません。プラグイン・スキルのバージョンはPython 1.2.1と独立し、グローバル導入や本番配備は含みません。 +公開済み1.2.0を基準に2026-10-19に準備しました。[候補ノート](docs/ja/releases/v1.2.1.md)はPR #319/#317(macOS Orca Claudeの制限付き検索)、#320/#318(制限付きスキルfrontmatter)、#303/#302(正本の互換スキル0.3.3)を記録します。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。プラグイン・スキルのバージョンはPython 1.2.1と独立し、グローバル導入や本番配備は含みません。 順次統合後に最終コミット検証、独立レビュー、パッケージ導入検査、最新依存関係監査を実行します。別途承認された準備PRのマージ後、正確な保護mainのCI成功が必要です。2026-10-19のタグ・PyPI未使用確認は日時点の観察であり、バージョン予約ではありません。現在の非公開Trusted Publisher設定の検証は主張せず、必須の人手pypi環境承認を維持します。#316と残るnative・handoff受け入れ条件は別で、この準備では閉じません。 diff --git a/RELEASING.ko.md b/RELEASING.ko.md index bf04fcd..77441b1 100644 --- a/RELEASING.ko.md +++ b/RELEASING.ko.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1 준비 — 공개 권한 없음 -공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. [후보 노트](docs/ko/releases/v1.2.1.md)는 PR #319/#317(macOS Orca Claude의 제한된 검색), #320/#318(제한된 스킬 frontmatter), #303/#302(정본 호환 스킬 0.3.3)을 기록합니다. 통합 소스 기준 `PENDING`은 최종 준비·공개 커밋이 아닙니다. 플러그인·스킬 버전은 Python 1.2.1과 별개이며 전역 설치나 운영 배포는 포함하지 않습니다. +공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. [후보 노트](docs/ko/releases/v1.2.1.md)는 PR #319/#317(macOS Orca Claude의 제한된 검색), #320/#318(제한된 스킬 frontmatter), #303/#302(정본 호환 스킬 0.3.3)을 기록합니다. 통합 소스 기준 `32e76d2c85d945d66466f630d9729ec0be5288d8`은 최종 준비·공개 커밋이 아닙니다. 플러그인·스킬 버전은 Python 1.2.1과 별개이며 전역 설치나 운영 배포는 포함하지 않습니다. 순차 통합 후 최종 커밋 검증·독립 검수·패키지 설치 검사·최신 의존성 감사를 수행합니다. 별도 승인으로 준비 PR을 병합한 뒤 정확한 보호 main의 CI 성공이 필요합니다. 2026-10-19 태그·PyPI 미사용 검사는 해당 시점의 관찰이지 버전 예약이 아닙니다. 현재 비공개 Trusted Publisher 검증은 주장하지 않으며 필수 사람 pypi 환경 승인은 유지합니다. #316과 남은 native·handoff 수락 조건은 별개이며 이 준비로 닫지 않습니다. diff --git a/RELEASING.md b/RELEASING.md index b88b661..d765724 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1 preparation — no publication authorization -Prepared on 2026-10-19 against published 1.2.0. The [candidate notes](docs/releases/v1.2.1.md) record PR #319/#317 (bounded macOS Orca Claude inventory), #320/#318 (bounded skill frontmatter) and #303/#302 (canonical compatibility skill 0.3.3). Integrated source base: `PENDING`, not the final preparation or publication commit. Plugin and skill versions remain independent of Python 1.2.1; no global installation or operational deployment is included. +Prepared on 2026-10-19 against published 1.2.0. The [candidate notes](docs/releases/v1.2.1.md) record PR #319/#317 (bounded macOS Orca Claude inventory), #320/#318 (bounded skill frontmatter) and #303/#302 (canonical compatibility skill 0.3.3). Integrated source base: `32e76d2c85d945d66466f630d9729ec0be5288d8`, not the final preparation or publication commit. Plugin and skill versions remain independent of Python 1.2.1; no global installation or operational deployment is included. Finish sequential integration before final-head validation, independent review, package installation checks and current dependency audits. Require successful CI on the exact protected main after a separately authorized preparation-PR merge. The 2026-10-19 unused-tag/PyPI checks are dated observations, not a version reservation. No current private Trusted Publisher verification is claimed; the required human pypi environment approval remains mandatory. #316 and the remaining native/handoff acceptance gates remain separate and unclosed by this preparation. diff --git a/RELEASING.zh-CN.md b/RELEASING.zh-CN.md index 641e75a..d799a53 100644 --- a/RELEASING.zh-CN.md +++ b/RELEASING.zh-CN.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1准备 — 无发布权限 -于2026-10-19基于已发布的1.2.0准备。[候选说明](docs/zh-CN/releases/v1.2.1.md)记录PR #319/#317(macOS Orca Claude有界搜索)、#320/#318(有界技能frontmatter)、#303/#302(正本兼容技能0.3.3)。集成源码基准`PENDING`不是最终准备或发布提交。插件与技能版本独立于Python 1.2.1,不包括全局安装或生产部署。 +于2026-10-19基于已发布的1.2.0准备。[候选说明](docs/zh-CN/releases/v1.2.1.md)记录PR #319/#317(macOS Orca Claude有界搜索)、#320/#318(有界技能frontmatter)、#303/#302(正本兼容技能0.3.3)。集成源码基准`32e76d2c85d945d66466f630d9729ec0be5288d8`不是最终准备或发布提交。插件与技能版本独立于Python 1.2.1,不包括全局安装或生产部署。 顺序集成完成后执行最终提交验证、独立审核、软件包安装检查及最新依赖审计。另行批准并合并准备PR后,须通过准确受保护main的CI。2026-10-19的标签/PyPI未使用检查仅是当时观察,不是版本预留。不声称验证了当前私有Trusted Publisher绑定,仍须人工pypi环境批准。#316及剩余native/handoff验收条件独立,不因本准备关闭。 diff --git a/docs/i18n-manifest.json b/docs/i18n-manifest.json index 4985bd4..2ed623f 100644 --- a/docs/i18n-manifest.json +++ b/docs/i18n-manifest.json @@ -8,7 +8,7 @@ ], "sources": { "README.md": "9ccd334628d9bb03bba3a08d0fd67a46ab48124733e4cf0b6565f034680db441", - "RELEASING.md": "b0682b5f68e72730fb060da69bb71eca60cff8b9638bbc6a34ee9d89b447a96c", + "RELEASING.md": "b23b741c9eb15cb796382aacd9c897ee27cc9cf970606a84398201effc891132", "SECURITY.md": "8f018f6f98002312e143609b9734aeb971ca5217e146597c06b57b5645031046", "docs/README.md": "03a461054c1570741c2022685014a1b947f0234145b83f4c8297241d5edcf327", "docs/agent-adapters.md": "bf185d3121c94829bb412071a25c4d943302e10a6b2e713111e653b8f8c3ea91", @@ -51,7 +51,7 @@ "docs/releases/v1.1.1.md": "e7d5b6060098be0d4db06a7c2845955ea46084cdecd3fe8e5dc6c44324c09cc0", "docs/releases/v1.1.2.md": "3ffe3d6daa8e403e9f3c5e83ec81c3afa9f10750627b31362990ec5b92326f3a", "docs/releases/v1.2.0.md": "9a153493fb3d25306306a05f6c1f5672d7d7becfe008f371770ce2d13d7e9b38", - "docs/releases/v1.2.1.md": "7690a9e0602add79e66dd7436592dd3000b8bedebc1c308405f230d6d4fa1c47", + "docs/releases/v1.2.1.md": "2f847353a45bc8920470649e49d7a49cfcbd1d553148609bed38ce070e380971", "docs/validation/69-rc.md": "e490c6a9ad0fec9108b91c74922cedac7ddf214ed405f8f5523da22f48a4b222", "docs/validation/85-antigravity.md": "f89b175191cd98ab03d4029b487065133814b3c8dd8de8cd0a5cc367e2579e4f", "docs/wake.md": "cde135da2ea7be21c815bb265e694f737dbe467d8e76bb82eb118e3b86e29d22", diff --git a/docs/ja/releases/v1.2.1.md b/docs/ja/releases/v1.2.1.md index c9e5dfd..ae24707 100644 --- a/docs/ja/releases/v1.2.1.md +++ b/docs/ja/releases/v1.2.1.md @@ -4,19 +4,19 @@ 公開済み1.2.0を基準に2026-10-19に準備しました。ソースの準備であり、公開完了の告知ではありません。最後に確認した安定版は[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)と[PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)です。 -統合記録です(未確定の行はレビュー前に確定します)。統合ソースの基準は`PENDING`であり、最終準備・公開コミットではありません。 +対象PR 3件を以下の順序ですべてマージしました。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。 | PR | Issue | mainマージコミット | | --- | --- | --- | | #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | | #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | -| #303 | #302 | `PENDING` | +| #303 | #302 | `32e76d2c85d945d66466f630d9729ec0be5288d8` | ## パッチの範囲 - #319: 明示的な`CLAUDE_CONFIG_DIR`または`ANTHROPIC_CONFIG_DIR`がない場合、macOSの同じユーザーが所有する既知のOrcaプロファイルでnative Claude登録を検索します。明示指定の範囲・優先順位は維持します。制限付きメタデータ検索は一部失敗時も正常な行を残しますが、検索が不完全か生存記録が矛盾する場合はすべての送信先選択を拒否します。選択した記録・プロファイル・受信箱の証拠を保持して再確認します。通常のソケット別名は維持し、既存の任意世代検査の制限も維持します。検索は認証情報・会話履歴を読まず受信箱に接続せず、受信証明も提供しません。Orca自動検索は新しいWindows/Linux対応ではありません。 -- #320: 文書全体の大きさに依存せず、制限した先頭のスキルメタデータを読みます。16 KiBのヘッダー上限は区切りと改行を含み、先読みは最大1バイトです。完全なUTF-8ヘッダーだけを解釈し、読み取り不能・未終端・上限超過・不正UTF-8のヘッダーはunknownのままです。既存の限定的なフィールド抽出は汎用YAML検証器ではなく、従来認識した形式は維持します。既存のフィールド・管理者・シンボリックリンク動作を維持し、通常ファイル以外のメタデータはunknownとします。不正な数値フィールドは別の有効なフィールドを消しません。YAMLやスキル指示は実行しません。 -- #303: companion v0.3.3のソース`eb239fb358336d85b49bab2c80e4ea39037d1374`、SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`から互換スキルコピーを更新します。メタデータはPython 1.2.1と独立した0.3.3 / 最小0.9.1 / 全機能1.0.1です。グローバルインストールや管理者が所有するインストールの更新ではありません。 +- #320: 文書全体の大きさに依存せず、制限した先頭のスキルメタデータを読みます。16 KiBのヘッダー上限は区切りと改行を含み、先読みは最大1バイトです。完全なUTF-8ヘッダーだけを解釈し、読み取り不能・未終端・上限超過・不正UTF-8のヘッダーはunknownのままです。既存の限定的なフィールド抽出は汎用YAML検証器ではなく、従来認識した形式は維持します。既存のフィールド・管理ツール・シンボリックリンク動作を維持し、通常ファイル以外のメタデータはunknownとします。不正な数値フィールドは別の有効なフィールドを消しません。YAMLやスキル指示は実行しません。 +- #303: companion v0.3.3のソース`eb239fb358336d85b49bab2c80e4ea39037d1374`、SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`から互換スキルコピーを更新します。メタデータはPython 1.2.1と独立した0.3.3 / 最小0.9.1 / 全機能1.0.1です。グローバルへのスキル導入や、別の管理ツールで導入したスキルの更新ではありません。 ## 検証と制限 diff --git a/docs/ko/releases/v1.2.1.md b/docs/ko/releases/v1.2.1.md index f368ad5..9fc050b 100644 --- a/docs/ko/releases/v1.2.1.md +++ b/docs/ko/releases/v1.2.1.md @@ -4,19 +4,19 @@ 공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. 이는 소스 준비이며 공개 완료 안내가 아닙니다. 마지막 확인 안정판은 [GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)과 [PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)입니다. -통합 기록입니다(대기 행은 검토 전에 확정해야 합니다). 통합 소스 기준은 `PENDING`이며 최종 릴리스 준비·공개 커밋이 아닙니다. +범위 내 PR 3개를 아래 순서로 모두 병합했습니다. 통합 소스 기준은 `32e76d2c85d945d66466f630d9729ec0be5288d8`이며 최종 릴리스 준비·공개 커밋이 아닙니다. | PR | 이슈 | main 병합 커밋 | | --- | --- | --- | | #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | | #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | -| #303 | #302 | `PENDING` | +| #303 | #302 | `32e76d2c85d945d66466f630d9729ec0be5288d8` | ## 패치 범위 - #319: 명시적 `CLAUDE_CONFIG_DIR` 또는 `ANTHROPIC_CONFIG_DIR`이 없을 때 macOS의 알려진 같은 사용자 소유 Orca 프로필에서 native Claude 등록을 검색합니다. 명시적 범위와 우선순위는 유지합니다. 제한된 메타데이터 검색은 일부 실패 시 정상 행을 보존하지만 검색이 불완전하거나 살아 있는 기록이 충돌하면 모든 대상 선택을 거부합니다. 선택한 기록·프로필·수신함 증거를 유지하고 다시 확인합니다. 일반 소켓 별칭은 유지하되 기존 선택적 세대 검사 제한도 유지합니다. 검색은 인증정보·대화 기록을 읽거나 수신함에 연결하지 않으며 수신을 증명하지도 않습니다. Orca 프로필 자동 검색은 새로운 Windows/Linux 지원이 아닙니다. -- #320: 문서 전체 크기와 별개로 제한된 앞부분의 스킬 메타데이터를 읽습니다. 16 KiB 헤더 한도에는 구분자와 줄 끝이 포함되며 추가 확인은 최대 1바이트입니다. 완결된 UTF-8 헤더만 해석하며 읽을 수 없거나 닫히지 않았거나 한도를 넘거나 UTF-8이 잘못된 헤더는 unknown으로 유지합니다. 기존의 제한된 필드 추출은 일반 YAML 검증기가 아니며 이전에 인식하던 형식은 계속 인식합니다. 기존 필드·관리자·심볼릭 링크 동작은 유지하며 일반 파일이 아닌 입력의 메타데이터는 unknown으로 처리합니다. 잘못된 숫자 필드가 별도로 유효한 필드를 지우지 않습니다. YAML이나 스킬 지침은 실행하지 않습니다. -- #303: companion v0.3.3의 소스 `eb239fb358336d85b49bab2c80e4ea39037d1374`, SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`에서 호환 스킬 사본을 갱신합니다. 스킬 메타데이터는 Python 1.2.1과 별개인 0.3.3 / 최소 0.9.1 / 전체 1.0.1입니다. 전역 스킬 설치나 관리자가 소유한 설치의 갱신은 아닙니다. +- #320: 문서 전체 크기와 별개로 제한된 앞부분의 스킬 메타데이터를 읽습니다. 16 KiB 헤더 한도에는 구분자와 줄 끝이 포함되며 추가 확인은 최대 1바이트입니다. 완결된 UTF-8 헤더만 해석하며 읽을 수 없거나 닫히지 않았거나 한도를 넘거나 UTF-8이 잘못된 헤더는 unknown으로 유지합니다. 기존의 제한된 필드 추출은 일반 YAML 검증기가 아니며 이전에 인식하던 형식은 계속 인식합니다. 기존 필드·관리 도구·심볼릭 링크 동작은 유지하며 일반 파일이 아닌 입력의 메타데이터는 unknown으로 처리합니다. 잘못된 숫자 필드가 별도로 유효한 필드를 지우지 않습니다. YAML이나 스킬 지침은 실행하지 않습니다. +- #303: companion v0.3.3의 소스 `eb239fb358336d85b49bab2c80e4ea39037d1374`, SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`에서 호환 스킬 사본을 갱신합니다. 스킬 메타데이터는 Python 1.2.1과 별개인 0.3.3 / 최소 0.9.1 / 전체 1.0.1입니다. 전역 스킬 설치나 다른 관리 도구로 설치한 사본의 갱신을 수행하는 변경은 아닙니다. ## 검증과 한계 diff --git a/docs/releases/v1.2.1.md b/docs/releases/v1.2.1.md index 8120784..8361bc4 100644 --- a/docs/releases/v1.2.1.md +++ b/docs/releases/v1.2.1.md @@ -4,13 +4,13 @@ Prepared on 2026-10-19 against published 1.2.0. This is a source preparation, not a publication announcement. The last verified stable release is [v1.2.0 on GitHub](https://github.com/abruption/session-peer/releases/tag/v1.2.0) and [1.2.0 on PyPI](https://pypi.org/pypi/session-peer/1.2.0/json). -Integration record (pending rows must be resolved before review). The integrated source base is `PENDING`; it is not the final release-preparation or publication commit. +All three scoped PRs are merged in the order below. The integrated source base is `32e76d2c85d945d66466f630d9729ec0be5288d8`; it is not the final release-preparation or publication commit. | PR | Issue | Main merge commit | | --- | --- | --- | | #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | | #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | -| #303 | #302 | `PENDING` | +| #303 | #302 | `32e76d2c85d945d66466f630d9729ec0be5288d8` | ## Patch scope diff --git a/docs/zh-CN/releases/v1.2.1.md b/docs/zh-CN/releases/v1.2.1.md index 2b246ea..274d593 100644 --- a/docs/zh-CN/releases/v1.2.1.md +++ b/docs/zh-CN/releases/v1.2.1.md @@ -4,13 +4,13 @@ 于2026-10-19基于已发布的1.2.0准备。这是源码准备,不是发布完成公告。最后验证的稳定版本为[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)和[PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)。 -集成记录如下(待定行必须在审核前确定)。集成源码基准为`PENDING`,并非最终发布准备或发布提交。 +范围内3项PR已按下列顺序全部合并。集成源码基准为`32e76d2c85d945d66466f630d9729ec0be5288d8`,并非最终发布准备或发布提交。 | PR | 议题 | main合并提交 | | --- | --- | --- | | #319 | #317 | `ba00540e24e4e378c002c11e7cbeb23b85003b9f` | | #320 | #318 | `c5625a1667de50b2684067febed1772ed693eca7` | -| #303 | #302 | `PENDING` | +| #303 | #302 | `32e76d2c85d945d66466f630d9729ec0be5288d8` | ## 补丁范围 diff --git a/tests/docs/test_stable_candidate.py b/tests/docs/test_stable_candidate.py index a1f73b9..a5642e2 100644 --- a/tests/docs/test_stable_candidate.py +++ b/tests/docs/test_stable_candidate.py @@ -14,17 +14,23 @@ class StableCandidate(unittest.TestCase): def test_v121_preparation_records_patch_sources_and_publication_gates(self): notes = [(ROOT / ("docs/" + locale + "releases/v1.2.1.md")).read_text(encoding="utf-8") for locale in ("", "ko/", "ja/", "zh-CN/")] - expected_pairs = ((319, 317), (320, 318), (303, 302)) + source_base = "32e76d2c85d945d66466f630d9729ec0be5288d8" + expected_pairs = ((319, 317, "ba00540e24e4e378c002c11e7cbeb23b85003b9f"), + (320, 318, "c5625a1667de50b2684067febed1772ed693eca7"), + (303, 302, source_base)) for locale, text in zip(("", "ko/", "ja/", "zh-CN/"), notes): with self.subTest(locale=locale): self.assertNotIn("PENDING", text) positions = [] - for pr, issue in expected_pairs: + for pr, issue, expected_sha in expected_pairs: row = re.search(r"\| #%d \| #%d \| `([0-9a-f]{40})` \|" % (pr, issue), text) self.assertIsNotNone(row) positions.append(row.start()) - self.assertIn(row.group(1), notes[0]) + self.assertEqual(expected_sha, row.group(1)) self.assertEqual(positions, sorted(positions)) + self.assertIn(source_base, text) + suffix = "." + locale.rstrip("/") if locale else "" + self.assertIn(source_base, (ROOT / ("RELEASING" + suffix + ".md")).read_text(encoding="utf-8")) for marker in ("1.2.1", "1.2.0", "2026-10-19", "macOS", "Windows/Linux", "CLAUDE_CONFIG_DIR", "ANTHROPIC_CONFIG_DIR", "16 KiB", "UTF-8", "0.3.3", "0.9.1", "1.0.1", "#316", "#161", "20/21", From e8f1e7dccfd204939028bc0c4d0d39da381eee47 Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Mon, 19 Oct 2026 14:10:07 +0900 Subject: [PATCH 3/6] docs(release): tighten v1.2.1 provenance and readiness guards --- RELEASING.ja.md | 2 +- RELEASING.ko.md | 2 +- RELEASING.md | 2 +- RELEASING.zh-CN.md | 2 +- docs/i18n-manifest.json | 4 ++-- docs/ja/releases/v1.2.1.md | 4 +++- docs/ko/releases/v1.2.1.md | 4 +++- docs/releases/v1.2.1.md | 4 +++- docs/zh-CN/releases/v1.2.1.md | 4 +++- tests/docs/test_stable_candidate.py | 17 ++++++++++++++++- 10 files changed, 34 insertions(+), 11 deletions(-) diff --git a/RELEASING.ja.md b/RELEASING.ja.md index ff2e8b7..d4d923d 100644 --- a/RELEASING.ja.md +++ b/RELEASING.ja.md @@ -34,7 +34,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ 公開済み1.2.0を基準に2026-10-19に準備しました。[候補ノート](docs/ja/releases/v1.2.1.md)はPR #319/#317(macOS Orca Claudeの制限付き検索)、#320/#318(制限付きスキルfrontmatter)、#303/#302(正本の互換スキル0.3.3)を記録します。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。プラグイン・スキルのバージョンはPython 1.2.1と独立し、グローバル導入や本番配備は含みません。 -順次統合後に最終コミット検証、独立レビュー、パッケージ導入検査、最新依存関係監査を実行します。別途承認された準備PRのマージ後、正確な保護mainのCI成功が必要です。2026-10-19のタグ・PyPI未使用確認は日時点の観察であり、バージョン予約ではありません。現在の非公開Trusted Publisher設定の検証は主張せず、必須の人手pypi環境承認を維持します。#316と残るnative・handoff受け入れ条件は別で、この準備では閉じません。 +対象PR 3件はすべてマージ済みです。最終コミット検証、独立レビュー、パッケージ導入検査、最新依存関係監査を完了します。別途承認された準備PRのマージ後、正確な保護mainのCI成功が必要です。2026-10-19のタグ・PyPI未使用確認は日時点の観察であり、バージョン予約ではありません。現在の非公開Trusted Publisher設定の検証は主張せず、必須の人手pypi環境承認を維持します。#316と残るnative・handoff受け入れ条件は別で、この準備では閉じません。 この節は実行用コマンドを提供せず、マージ、タグ・ドラフト作成、ワークフロー実行、公開・配備を承認しません。別途承認後に全ゲートを再確認し、実行依頼後はattach-draft成功まで停止して、不変資産7個、SHA256SUMS、release-provenance.jsonと認証された証明を正確なタグ・コミットと照合します。ローカル準備ビルドは公開用資産ではなく、公開完了を先に宣言したりメタデータ変更のため不変資産を置換したりしません。 diff --git a/RELEASING.ko.md b/RELEASING.ko.md index 77441b1..9a169eb 100644 --- a/RELEASING.ko.md +++ b/RELEASING.ko.md @@ -34,7 +34,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ 공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. [후보 노트](docs/ko/releases/v1.2.1.md)는 PR #319/#317(macOS Orca Claude의 제한된 검색), #320/#318(제한된 스킬 frontmatter), #303/#302(정본 호환 스킬 0.3.3)을 기록합니다. 통합 소스 기준 `32e76d2c85d945d66466f630d9729ec0be5288d8`은 최종 준비·공개 커밋이 아닙니다. 플러그인·스킬 버전은 Python 1.2.1과 별개이며 전역 설치나 운영 배포는 포함하지 않습니다. -순차 통합 후 최종 커밋 검증·독립 검수·패키지 설치 검사·최신 의존성 감사를 수행합니다. 별도 승인으로 준비 PR을 병합한 뒤 정확한 보호 main의 CI 성공이 필요합니다. 2026-10-19 태그·PyPI 미사용 검사는 해당 시점의 관찰이지 버전 예약이 아닙니다. 현재 비공개 Trusted Publisher 검증은 주장하지 않으며 필수 사람 pypi 환경 승인은 유지합니다. #316과 남은 native·handoff 수락 조건은 별개이며 이 준비로 닫지 않습니다. +범위 내 PR 3개를 모두 병합했습니다. 최종 커밋 검증·독립 검수·패키지 설치 검사·최신 의존성 감사를 완료합니다. 별도 승인으로 준비 PR을 병합한 뒤 정확한 보호 main의 CI 성공이 필요합니다. 2026-10-19 태그·PyPI 미사용 검사는 해당 시점의 관찰이지 버전 예약이 아닙니다. 현재 비공개 Trusted Publisher 검증은 주장하지 않으며 필수 사람 pypi 환경 승인은 유지합니다. #316과 남은 native·handoff 수락 조건은 별개이며 이 준비로 닫지 않습니다. 이 절에는 실행용 릴리스 명령이 없으며 병합, 태그·초안 생성, 워크플로 실행 요청, 공개·배포를 승인하지 않습니다. 별도 승인 후 모든 조건을 재확인하고 실행 요청 뒤 attach-draft 성공까지 멈추며 불변 자산 7개, SHA256SUMS, release-provenance.json과 인증된 증명을 정확한 태그·커밋에 대조합니다. 로컬 준비 빌드는 게시할 릴리스 자산이 아니며 공개 완료를 미리 선언하거나 메타데이터 갱신을 위해 불변 자산을 교체하지 않습니다. diff --git a/RELEASING.md b/RELEASING.md index d765724..bca4040 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -34,7 +34,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ Prepared on 2026-10-19 against published 1.2.0. The [candidate notes](docs/releases/v1.2.1.md) record PR #319/#317 (bounded macOS Orca Claude inventory), #320/#318 (bounded skill frontmatter) and #303/#302 (canonical compatibility skill 0.3.3). Integrated source base: `32e76d2c85d945d66466f630d9729ec0be5288d8`, not the final preparation or publication commit. Plugin and skill versions remain independent of Python 1.2.1; no global installation or operational deployment is included. -Finish sequential integration before final-head validation, independent review, package installation checks and current dependency audits. Require successful CI on the exact protected main after a separately authorized preparation-PR merge. The 2026-10-19 unused-tag/PyPI checks are dated observations, not a version reservation. No current private Trusted Publisher verification is claimed; the required human pypi environment approval remains mandatory. #316 and the remaining native/handoff acceptance gates remain separate and unclosed by this preparation. +The three scoped PRs are merged; complete final-head validation, independent review, package installation checks and current dependency audits. Require successful CI on the exact protected main after a separately authorized preparation-PR merge. The 2026-10-19 unused-tag/PyPI checks are dated observations, not a version reservation. No current private Trusted Publisher verification is claimed; the required human pypi environment approval remains mandatory. #316 and the remaining native/handoff acceptance gates remain separate and unclosed by this preparation. This section supplies no executable release commands and authorizes no merge, tag/draft creation, workflow dispatch, publication or deployment. After separate authorization, recheck all gates, stop after dispatch until attach-draft succeeds, and review all seven immutable assets, SHA256SUMS, release-provenance.json and authenticated attestations against the exact tag/commit. Local preparation builds are not publishable release assets; do not announce publication or replace immutable assets to update metadata. diff --git a/RELEASING.zh-CN.md b/RELEASING.zh-CN.md index d799a53..c70c200 100644 --- a/RELEASING.zh-CN.md +++ b/RELEASING.zh-CN.md @@ -34,7 +34,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ 于2026-10-19基于已发布的1.2.0准备。[候选说明](docs/zh-CN/releases/v1.2.1.md)记录PR #319/#317(macOS Orca Claude有界搜索)、#320/#318(有界技能frontmatter)、#303/#302(正本兼容技能0.3.3)。集成源码基准`32e76d2c85d945d66466f630d9729ec0be5288d8`不是最终准备或发布提交。插件与技能版本独立于Python 1.2.1,不包括全局安装或生产部署。 -顺序集成完成后执行最终提交验证、独立审核、软件包安装检查及最新依赖审计。另行批准并合并准备PR后,须通过准确受保护main的CI。2026-10-19的标签/PyPI未使用检查仅是当时观察,不是版本预留。不声称验证了当前私有Trusted Publisher绑定,仍须人工pypi环境批准。#316及剩余native/handoff验收条件独立,不因本准备关闭。 +范围内3项PR已全部合并;接着完成最终提交验证、独立审核、软件包安装检查及最新依赖审计。另行批准并合并准备PR后,须通过准确受保护main的CI。2026-10-19的标签/PyPI未使用检查仅是当时观察,不是版本预留。不声称验证了当前私有Trusted Publisher绑定,仍须人工pypi环境批准。#316及剩余native/handoff验收条件独立,不因本准备关闭。 本节不提供可执行命令,也不授权合并、创建标签/草稿、派发工作流、发布或部署。另行批准后须复核所有门禁,派发后等待attach-draft成功,再核对7项不可变资产、SHA256SUMS、release-provenance.json及认证证明与准确标签/提交一致。本地准备构建不是发布资产,不得提前宣布发布或为更新元数据而替换不可变资产。 diff --git a/docs/i18n-manifest.json b/docs/i18n-manifest.json index 2ed623f..0009566 100644 --- a/docs/i18n-manifest.json +++ b/docs/i18n-manifest.json @@ -8,7 +8,7 @@ ], "sources": { "README.md": "9ccd334628d9bb03bba3a08d0fd67a46ab48124733e4cf0b6565f034680db441", - "RELEASING.md": "b23b741c9eb15cb796382aacd9c897ee27cc9cf970606a84398201effc891132", + "RELEASING.md": "4dd26ed935ea9afd706302cac112ac99dea9154b02d73a282c48752201f854a6", "SECURITY.md": "8f018f6f98002312e143609b9734aeb971ca5217e146597c06b57b5645031046", "docs/README.md": "03a461054c1570741c2022685014a1b947f0234145b83f4c8297241d5edcf327", "docs/agent-adapters.md": "bf185d3121c94829bb412071a25c4d943302e10a6b2e713111e653b8f8c3ea91", @@ -51,7 +51,7 @@ "docs/releases/v1.1.1.md": "e7d5b6060098be0d4db06a7c2845955ea46084cdecd3fe8e5dc6c44324c09cc0", "docs/releases/v1.1.2.md": "3ffe3d6daa8e403e9f3c5e83ec81c3afa9f10750627b31362990ec5b92326f3a", "docs/releases/v1.2.0.md": "9a153493fb3d25306306a05f6c1f5672d7d7becfe008f371770ce2d13d7e9b38", - "docs/releases/v1.2.1.md": "2f847353a45bc8920470649e49d7a49cfcbd1d553148609bed38ce070e380971", + "docs/releases/v1.2.1.md": "948f94a548a998c4c67c25a0de3995d32855195c186010589b20553c18c223ce", "docs/validation/69-rc.md": "e490c6a9ad0fec9108b91c74922cedac7ddf214ed405f8f5523da22f48a4b222", "docs/validation/85-antigravity.md": "f89b175191cd98ab03d4029b487065133814b3c8dd8de8cd0a5cc367e2579e4f", "docs/wake.md": "cde135da2ea7be21c815bb265e694f737dbe467d8e76bb82eb118e3b86e29d22", diff --git a/docs/ja/releases/v1.2.1.md b/docs/ja/releases/v1.2.1.md index ae24707..0a9d992 100644 --- a/docs/ja/releases/v1.2.1.md +++ b/docs/ja/releases/v1.2.1.md @@ -24,7 +24,9 @@ #319最終候補のローカル全体実行は1,294テストOK・19スキップでしたが、asyncio AssertionErrorと無視されたunclosed socket・transport ResourceWarningも出力されました。その改訂の最初のログを残し、診断を隠すために再実行していません。#316は未解決で、テスト成功や無関係な変更は原因・修正を証明しません。#161と#180/#181/#268/#304/#306/#307の残る受け入れ条件は別です。過去のRC4 ACK証拠は20/21のままです。 -一般的なCodex ACK・世代、初回入力前の配送、Antigravity安定対応、完全なnative・プラットフォーム受け入れは追加しません。固定handoff契約・fixtureは不変です。submitted/queuedは消費やACKではなく、unknownは自動再送を許可しません。プラグインのバージョンは独立です。所有するMacBookへのソース転送SSH検査では、導入やnative受信箱入力なしでメタデータ検索・任意世代メタデータ・明示指定範囲を確認しましたが、配送証拠ではありません。SSH・Relay・MCP経由の実エージェントメッセージ・ACK、OAuth・fleet・運用の受け入れは主張しません。パッケージ公開に本番配備は含まれず、Control/Relayや導入済み端末の更新には別の承認・検証が必要です。 +一般的なCodex ACK・世代、初回入力前の配送、Antigravity安定対応、完全なnative・プラットフォーム受け入れは追加しません。固定handoff契約・fixtureは不変です。submitted/queuedは消費やACKではなく、unknownは自動再送を許可しません。プラグインのバージョンは独立です。SSH・Relay・MCP経由の実エージェントメッセージ・ACK、OAuth・fleet・運用の受け入れは主張しません。パッケージ公開に本番配備は含まれず、Control/Relayや導入済み端末の更新には別の承認・検証が必要です。 + +2026-10-19に所有するMacBook上で#319ソース`ad4aa0e464fb142424f6fb6a30303bb88e47163e`を転送するSSHメタデータ専用検査により、既定検索、任意の`generationStatus=available`メタデータ、明示した既定ルート範囲を確認しました。最終#319ソース`4cd202af4b6a2f0b5e7daa1e7f9d960eb7a67217`による既定検索の再確認でも、対象はreachableでした。いずれもランタイム導入やnative受信箱入力は行っていません。これらは時点のメタデータ観測であり、新しいPython 1.2.1の実メッセージ・ACKや全プラットフォーム受け入れ証拠ではありません。 ## 公開の境界 diff --git a/docs/ko/releases/v1.2.1.md b/docs/ko/releases/v1.2.1.md index 9fc050b..36a2dd1 100644 --- a/docs/ko/releases/v1.2.1.md +++ b/docs/ko/releases/v1.2.1.md @@ -24,7 +24,9 @@ #319 최종 후보의 로컬 전체 실행은 1,294개 테스트 OK와 skip 19개로 끝났지만 asyncio AssertionError와 무시된 unclosed socket·transport ResourceWarning도 출력했습니다. 해당 소스 개정의 최초 로그를 보존했으며 진단을 숨기기 위해 재실행하지 않았습니다. #316은 열려 있고 테스트 성공이나 무관한 변경만으로 원인·수정을 입증하지 않습니다. #161과 #180/#181/#268/#304/#306/#307의 남은 수락 조건은 별도입니다. 과거 RC4 ACK 증거는 20/21로 유지합니다. -일반 Codex ACK·세대, 첫 입력 전 전달, Antigravity 정식 지원이나 완전한 native·플랫폼 수락을 추가하지 않습니다. 고정 handoff 계약·fixture는 불변이며 submitted/queued는 소비나 ACK가 아니고 unknown은 자동 재전송을 허용하지 않습니다. 플러그인 버전은 별개입니다. 소유한 MacBook의 소스 스트리밍 SSH 검사로 설치나 native 수신함 입력 없이 메타데이터 전용 검색·선택적 세대 메타데이터·명시적 경로 범위를 확인했지만 전달 증거는 아닙니다. SSH·Relay·MCP를 통한 실제 에이전트 메시지·ACK 수락이나 OAuth·fleet·운영 수락은 주장하지 않습니다. 패키지 공개에는 운영 배포가 포함되지 않으며 Control/Relay와 설치된 기기의 갱신은 별도 승인·검증이 필요합니다. +일반 Codex ACK·세대, 첫 입력 전 전달, Antigravity 정식 지원이나 완전한 native·플랫폼 수락을 추가하지 않습니다. 고정 handoff 계약·fixture는 불변이며 submitted/queued는 소비나 ACK가 아니고 unknown은 자동 재전송을 허용하지 않습니다. 플러그인 버전은 별개입니다. SSH·Relay·MCP를 통한 실제 에이전트 메시지·ACK 수락이나 OAuth·fleet·운영 수락은 주장하지 않습니다. 패키지 공개에는 운영 배포가 포함되지 않으며 Control/Relay와 설치된 기기의 갱신은 별도 승인·검증이 필요합니다. + +2026-10-19에 소유한 MacBook에서 #319 소스 `ad4aa0e464fb142424f6fb6a30303bb88e47163e`를 소스 스트리밍 SSH로 실행해 메타데이터만 확인했습니다. 기본 검색, 선택적 `generationStatus=available` 메타데이터, 명시적으로 지정한 기본 경로 범위를 검증했습니다. 최종 #319 소스 `4cd202af4b6a2f0b5e7daa1e7f9d960eb7a67217`로 기본 검색을 다시 확인했을 때도 대상이 reachable로 나타났습니다. 두 검사 모두 런타임 설치나 native 수신함 입력은 수행하지 않았습니다. 이는 메타데이터 시점 관측이며 새로운 Python 1.2.1 실제 메시지·ACK 또는 전체 플랫폼 수락 증거는 아닙니다. ## 공개 경계 diff --git a/docs/releases/v1.2.1.md b/docs/releases/v1.2.1.md index 8361bc4..a149d76 100644 --- a/docs/releases/v1.2.1.md +++ b/docs/releases/v1.2.1.md @@ -24,7 +24,9 @@ Review the final integrated source, generated standalone, translation hashes, pa A local full run of the final #319 candidate returned 1,294 tests OK with 19 skips, but also emitted an asyncio AssertionError and ignored unclosed-socket/transport ResourceWarnings. The first log for that revision was preserved, not rerun to hide diagnostics. #316 remains open; neither a passing test result nor unrelated changes establish a cause or fix. #161 and the remaining #180/#181/#268/#304/#306/#307 acceptance work are separate. Historical RC4 ACK evidence remains 20/21. -This patch adds no general Codex ACK/generation, first-input delivery, Antigravity stable support or full native/platform acceptance. The frozen handoff contract and fixture remain unchanged; submitted/queued is not consumption or ACK, and unknown never permits automatic resend. Plugin versions remain independent. An owned MacBook source-streamed SSH check verified metadata-only discovery, optional generation metadata and explicit-root scope without installation or native inbox input; it is not delivery evidence. No live agent-message/ACK acceptance over SSH, Relay or MCP, or OAuth/fleet/operational acceptance, is claimed. Package publication does not include operational deployment; Control/Relay updates and installed-device changes require separate authorization and verification. +This patch adds no general Codex ACK/generation, first-input delivery, Antigravity stable support or full native/platform acceptance. The frozen handoff contract and fixture remain unchanged; submitted/queued is not consumption or ACK, and unknown never permits automatic resend. Plugin versions remain independent. No live agent-message/ACK acceptance over SSH, Relay or MCP, or OAuth/fleet/operational acceptance, is claimed. Package publication does not include operational deployment; Control/Relay updates and installed-device changes require separate authorization and verification. + +On 2026-10-19, a source-streamed SSH metadata-only check on an owned MacBook using #319 source `ad4aa0e464fb142424f6fb6a30303bb88e47163e` verified default discovery, optional `generationStatus=available` metadata and explicit default-root scope. A repeated default-discovery check using the final #319 source `4cd202af4b6a2f0b5e7daa1e7f9d960eb7a67217` again showed the reachable target. Neither check installed the runtime or supplied native inbox input. These are metadata snapshots, not new Python 1.2.1 native-message/ACK or full-platform acceptance. ## Publication boundary diff --git a/docs/zh-CN/releases/v1.2.1.md b/docs/zh-CN/releases/v1.2.1.md index 274d593..1aaa4dc 100644 --- a/docs/zh-CN/releases/v1.2.1.md +++ b/docs/zh-CN/releases/v1.2.1.md @@ -24,7 +24,9 @@ #319最终候选的本地全量运行返回1,294项测试OK、19项跳过,但也输出asyncio AssertionError及被忽略的unclosed socket/transport ResourceWarning。保留该源码修订的首份日志,未为隐藏诊断而重跑。#316仍开放;测试成功或无关变更不能证明原因或修复。#161和#180/#181/#268/#304/#306/#307剩余验收工作是独立事项。历史RC4 ACK证据保留20/21。 -本补丁不增加通用Codex ACK/代际、首次输入前投递、Antigravity稳定支持或完整native/平台验收。固定handoff契约和fixture不变;submitted/queued不代表消费或ACK,unknown不允许自动重发。插件版本独立。对自有MacBook的源码流式SSH检查在不安装、不输入native收件箱的情况下验证了元数据搜索、可选代际元数据和显式目录范围,但不是投递证据。不声称SSH、Relay或MCP上的实际代理消息/ACK验收,或OAuth/fleet/运维验收。软件包发布不包括生产部署;Control/Relay和已安装设备的更新须另行授权并验证。 +本补丁不增加通用Codex ACK/代际、首次输入前投递、Antigravity稳定支持或完整native/平台验收。固定handoff契约和fixture不变;submitted/queued不代表消费或ACK,unknown不允许自动重发。插件版本独立。不声称SSH、Relay或MCP上的实际代理消息/ACK验收,或OAuth/fleet/运维验收。软件包发布不包括生产部署;Control/Relay和已安装设备的更新须另行授权并验证。 + +2026-10-19在自有MacBook上使用#319源码`ad4aa0e464fb142424f6fb6a30303bb88e47163e`进行源码流式SSH元数据检查,验证了默认搜索、可选`generationStatus=available`元数据及显式默认目录范围。用最终#319源码`4cd202af4b6a2f0b5e7daa1e7f9d960eb7a67217`重复默认搜索时,目标仍显示reachable。两次检查均未安装运行时或输入native收件箱。这些是时点元数据观察,不是新的Python 1.2.1实际消息/ACK或全平台验收证据。 ## 发布边界 diff --git a/tests/docs/test_stable_candidate.py b/tests/docs/test_stable_candidate.py index a5642e2..38526e2 100644 --- a/tests/docs/test_stable_candidate.py +++ b/tests/docs/test_stable_candidate.py @@ -18,6 +18,16 @@ def test_v121_preparation_records_patch_sources_and_publication_gates(self): expected_pairs = ((319, 317, "ba00540e24e4e378c002c11e7cbeb23b85003b9f"), (320, 318, "c5625a1667de50b2684067febed1772ed693eca7"), (303, 302, source_base)) + locale_boundaries = { + "": ("unknown never permits automatic resend", + "does not authorize its own merge, tag/draft creation, workflow dispatch, publication or deployment"), + "ko/": ("unknown은 자동 재전송을 허용하지 않습니다", + "준비 PR 자체의 병합, 태그·초안 생성, 워크플로 실행 요청, 공개·배포를 승인하지 않습니다"), + "ja/": ("unknownは自動再送を許可しません", + "この準備自身のマージ、タグ・ドラフト作成、ワークフロー実行、公開・配備も承認しません"), + "zh-CN/": ("unknown不允许自动重发", + "也不授权准备自身合并、创建标签/草稿、派发工作流、发布或部署"), + } for locale, text in zip(("", "ko/", "ja/", "zh-CN/"), notes): with self.subTest(locale=locale): self.assertNotIn("PENDING", text) @@ -36,9 +46,13 @@ def test_v121_preparation_records_patch_sources_and_publication_gates(self): "0.3.3", "0.9.1", "1.0.1", "#316", "#161", "20/21", "#180", "#181", "#268", "#304", "#306", "#307", "Control/Relay", "pypi", "attach-draft", "SHA256SUMS", "release-provenance.json", + "ad4aa0e464fb142424f6fb6a30303bb88e47163e", + "4cd202af4b6a2f0b5e7daa1e7f9d960eb7a67217", "generationStatus=available", "eb239fb358336d85b49bab2c80e4ea39037d1374", "15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f"): self.assertIn(marker, text) + for marker in locale_boundaries[locale]: + self.assertIn(marker, text) self.assertNotIn("```", text) for marker in ("not a publication announcement", "No YAML or skill instructions are executed", "refuses all target selection", "ordinary socket aliases remain supported", @@ -287,7 +301,8 @@ def test_stable_release_keeps_operational_deployment_separate(self): text = (ROOT / ("README" + suffix + ".md")).read_text(encoding="utf-8") self.assertIn(source_version, text) self.assertIn(dated_checkpoint, text) - self.assertNotIn(stale_unpublished, text) + for stale_version in ("1.2.0", "1.2.1"): + self.assertNotIn(stale_unpublished.replace("1.2.1", stale_version), text) self.assertIn("https://github.com/abruption/session-peer/releases", text) self.assertIn("https://pypi.org/project/session-peer/", text) self.assertNotIn("**1.0.3**", text) From 6289997a2df0028799f018b9b9a334de32b8deb7 Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Mon, 19 Oct 2026 14:41:54 +0900 Subject: [PATCH 4/6] fix(update): close handled-signal staging ownership gap --- RELEASING.ja.md | 2 +- RELEASING.ko.md | 2 +- RELEASING.md | 2 +- RELEASING.zh-CN.md | 2 +- docs/i18n-manifest.json | 4 +- docs/ja/releases/v1.2.1.md | 4 +- docs/ko/releases/v1.2.1.md | 4 +- docs/releases/v1.2.1.md | 4 +- docs/zh-CN/releases/v1.2.1.md | 4 +- session_peer.py | 15 +++- session_peer_core/ssh.py | 15 +++- tests/core/test_remote_update.py | 106 ++++++++++++++++++++++++++++ tests/docs/test_release_commands.py | 2 +- tests/docs/test_stable_candidate.py | 5 +- 14 files changed, 155 insertions(+), 16 deletions(-) diff --git a/RELEASING.ja.md b/RELEASING.ja.md index d4d923d..d23e560 100644 --- a/RELEASING.ja.md +++ b/RELEASING.ja.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1準備 — 公開権限なし -公開済み1.2.0を基準に2026-10-19に準備しました。[候補ノート](docs/ja/releases/v1.2.1.md)はPR #319/#317(macOS Orca Claudeの制限付き検索)、#320/#318(制限付きスキルfrontmatter)、#303/#302(正本の互換スキル0.3.3)を記録します。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。プラグイン・スキルのバージョンはPython 1.2.1と独立し、グローバル導入や本番配備は含みません。 +公開済み1.2.0を基準に2026-10-19に準備しました。[候補ノート](docs/ja/releases/v1.2.1.md)はPR #319/#317(macOS Orca Claudeの制限付き検索)、#320/#318(制限付きスキルfrontmatter)、#303/#302(正本の互換スキル0.3.3)を記録します。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。プラグイン・スキルのバージョンはPython 1.2.1と独立し、グローバル導入や本番配備は含みません。 準備PR #321には#322の対象信号に対する一時領域の所有パス引き継ぎ修正も含みます。制御したローカル再現と原因未確定の元CI失敗は別です。SIGKILL、ホスト喪失、削除の任意中断は保証せず、unknownは自動再試行を許可しません。 対象PR 3件はすべてマージ済みです。最終コミット検証、独立レビュー、パッケージ導入検査、最新依存関係監査を完了します。別途承認された準備PRのマージ後、正確な保護mainのCI成功が必要です。2026-10-19のタグ・PyPI未使用確認は日時点の観察であり、バージョン予約ではありません。現在の非公開Trusted Publisher設定の検証は主張せず、必須の人手pypi環境承認を維持します。#316と残るnative・handoff受け入れ条件は別で、この準備では閉じません。 diff --git a/RELEASING.ko.md b/RELEASING.ko.md index 9a169eb..f62bb1f 100644 --- a/RELEASING.ko.md +++ b/RELEASING.ko.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1 준비 — 공개 권한 없음 -공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. [후보 노트](docs/ko/releases/v1.2.1.md)는 PR #319/#317(macOS Orca Claude의 제한된 검색), #320/#318(제한된 스킬 frontmatter), #303/#302(정본 호환 스킬 0.3.3)을 기록합니다. 통합 소스 기준 `32e76d2c85d945d66466f630d9729ec0be5288d8`은 최종 준비·공개 커밋이 아닙니다. 플러그인·스킬 버전은 Python 1.2.1과 별개이며 전역 설치나 운영 배포는 포함하지 않습니다. +공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. [후보 노트](docs/ko/releases/v1.2.1.md)는 PR #319/#317(macOS Orca Claude의 제한된 검색), #320/#318(제한된 스킬 frontmatter), #303/#302(정본 호환 스킬 0.3.3)을 기록합니다. 통합 소스 기준 `32e76d2c85d945d66466f630d9729ec0be5288d8`은 최종 준비·공개 커밋이 아닙니다. 플러그인·스킬 버전은 Python 1.2.1과 별개이며 전역 설치나 운영 배포는 포함하지 않습니다. 준비 PR #321에는 #322의 처리 대상 신호에 대한 임시 디렉터리 소유 경로 인계 수정도 포함합니다. 제어된 로컬 재현과 원인 미확정인 원래 CI 실패는 구분합니다. SIGKILL·호스트 손실·정리의 임의 중단은 보장하지 않으며 unknown은 자동 재시도를 허용하지 않습니다. 범위 내 PR 3개를 모두 병합했습니다. 최종 커밋 검증·독립 검수·패키지 설치 검사·최신 의존성 감사를 완료합니다. 별도 승인으로 준비 PR을 병합한 뒤 정확한 보호 main의 CI 성공이 필요합니다. 2026-10-19 태그·PyPI 미사용 검사는 해당 시점의 관찰이지 버전 예약이 아닙니다. 현재 비공개 Trusted Publisher 검증은 주장하지 않으며 필수 사람 pypi 환경 승인은 유지합니다. #316과 남은 native·handoff 수락 조건은 별개이며 이 준비로 닫지 않습니다. diff --git a/RELEASING.md b/RELEASING.md index bca4040..743f7e3 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1 preparation — no publication authorization -Prepared on 2026-10-19 against published 1.2.0. The [candidate notes](docs/releases/v1.2.1.md) record PR #319/#317 (bounded macOS Orca Claude inventory), #320/#318 (bounded skill frontmatter) and #303/#302 (canonical compatibility skill 0.3.3). Integrated source base: `32e76d2c85d945d66466f630d9729ec0be5288d8`, not the final preparation or publication commit. Plugin and skill versions remain independent of Python 1.2.1; no global installation or operational deployment is included. +Prepared on 2026-10-19 against published 1.2.0. The [candidate notes](docs/releases/v1.2.1.md) record PR #319/#317 (bounded macOS Orca Claude inventory), #320/#318 (bounded skill frontmatter) and #303/#302 (canonical compatibility skill 0.3.3). Integrated source base: `32e76d2c85d945d66466f630d9729ec0be5288d8`, not the final preparation or publication commit. Plugin and skill versions remain independent of Python 1.2.1; no global installation or operational deployment is included. Preparation PR #321 also includes the #322 handled-signal staging-ownership fix. Controlled local reproduction is separate from the unproven original CI cause; SIGKILL, host loss and arbitrary interruption of cleanup are not covered, and unknown never grants automatic retry. The three scoped PRs are merged; complete final-head validation, independent review, package installation checks and current dependency audits. Require successful CI on the exact protected main after a separately authorized preparation-PR merge. The 2026-10-19 unused-tag/PyPI checks are dated observations, not a version reservation. No current private Trusted Publisher verification is claimed; the required human pypi environment approval remains mandatory. #316 and the remaining native/handoff acceptance gates remain separate and unclosed by this preparation. diff --git a/RELEASING.zh-CN.md b/RELEASING.zh-CN.md index c70c200..bdd6f8c 100644 --- a/RELEASING.zh-CN.md +++ b/RELEASING.zh-CN.md @@ -32,7 +32,7 @@ gh release edit v1.1.2 --repo abruption/session-peer \ ## v1.2.1准备 — 无发布权限 -于2026-10-19基于已发布的1.2.0准备。[候选说明](docs/zh-CN/releases/v1.2.1.md)记录PR #319/#317(macOS Orca Claude有界搜索)、#320/#318(有界技能frontmatter)、#303/#302(正本兼容技能0.3.3)。集成源码基准`32e76d2c85d945d66466f630d9729ec0be5288d8`不是最终准备或发布提交。插件与技能版本独立于Python 1.2.1,不包括全局安装或生产部署。 +于2026-10-19基于已发布的1.2.0准备。[候选说明](docs/zh-CN/releases/v1.2.1.md)记录PR #319/#317(macOS Orca Claude有界搜索)、#320/#318(有界技能frontmatter)、#303/#302(正本兼容技能0.3.3)。集成源码基准`32e76d2c85d945d66466f630d9729ec0be5288d8`不是最终准备或发布提交。插件与技能版本独立于Python 1.2.1,不包括全局安装或生产部署。 准备PR #321也包含#322针对已处理信号的暂存路径所有权交接修复。受控本地复现与原因未证实的原CI失败分开记录;不保证SIGKILL、主机失联或任意清理中断,unknown也不授予自动重试权限。 范围内3项PR已全部合并;接着完成最终提交验证、独立审核、软件包安装检查及最新依赖审计。另行批准并合并准备PR后,须通过准确受保护main的CI。2026-10-19的标签/PyPI未使用检查仅是当时观察,不是版本预留。不声称验证了当前私有Trusted Publisher绑定,仍须人工pypi环境批准。#316及剩余native/handoff验收条件独立,不因本准备关闭。 diff --git a/docs/i18n-manifest.json b/docs/i18n-manifest.json index 0009566..a5c9f04 100644 --- a/docs/i18n-manifest.json +++ b/docs/i18n-manifest.json @@ -8,7 +8,7 @@ ], "sources": { "README.md": "9ccd334628d9bb03bba3a08d0fd67a46ab48124733e4cf0b6565f034680db441", - "RELEASING.md": "4dd26ed935ea9afd706302cac112ac99dea9154b02d73a282c48752201f854a6", + "RELEASING.md": "b2371ba9b2392e3b95394bb6bb3c2927b0c87ff3a8b307bc90defdad6f0ab8a6", "SECURITY.md": "8f018f6f98002312e143609b9734aeb971ca5217e146597c06b57b5645031046", "docs/README.md": "03a461054c1570741c2022685014a1b947f0234145b83f4c8297241d5edcf327", "docs/agent-adapters.md": "bf185d3121c94829bb412071a25c4d943302e10a6b2e713111e653b8f8c3ea91", @@ -51,7 +51,7 @@ "docs/releases/v1.1.1.md": "e7d5b6060098be0d4db06a7c2845955ea46084cdecd3fe8e5dc6c44324c09cc0", "docs/releases/v1.1.2.md": "3ffe3d6daa8e403e9f3c5e83ec81c3afa9f10750627b31362990ec5b92326f3a", "docs/releases/v1.2.0.md": "9a153493fb3d25306306a05f6c1f5672d7d7becfe008f371770ce2d13d7e9b38", - "docs/releases/v1.2.1.md": "948f94a548a998c4c67c25a0de3995d32855195c186010589b20553c18c223ce", + "docs/releases/v1.2.1.md": "70a3026c2d874a6fd7addcaef840ecfa84bf4f33a0165605217379acffa4fddb", "docs/validation/69-rc.md": "e490c6a9ad0fec9108b91c74922cedac7ddf214ed405f8f5523da22f48a4b222", "docs/validation/85-antigravity.md": "f89b175191cd98ab03d4029b487065133814b3c8dd8de8cd0a5cc367e2579e4f", "docs/wake.md": "cde135da2ea7be21c815bb265e694f737dbe467d8e76bb82eb118e3b86e29d22", diff --git a/docs/ja/releases/v1.2.1.md b/docs/ja/releases/v1.2.1.md index 0a9d992..d08251d 100644 --- a/docs/ja/releases/v1.2.1.md +++ b/docs/ja/releases/v1.2.1.md @@ -4,7 +4,7 @@ 公開済み1.2.0を基準に2026-10-19に準備しました。ソースの準備であり、公開完了の告知ではありません。最後に確認した安定版は[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)と[PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)です。 -対象PR 3件を以下の順序ですべてマージしました。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。 +別途対象となったPR 3件を以下の順序ですべてマージしました。準備PR #321には以下の#322ランタイム修正も含みます。統合ソース基準`32e76d2c85d945d66466f630d9729ec0be5288d8`は最終準備・公開コミットではありません。 | PR | Issue | mainマージコミット | | --- | --- | --- | @@ -18,6 +18,8 @@ - #320: 文書全体の大きさに依存せず、制限した先頭のスキルメタデータを読みます。16 KiBのヘッダー上限は区切りと改行を含み、先読みは最大1バイトです。完全なUTF-8ヘッダーだけを解釈し、読み取り不能・未終端・上限超過・不正UTF-8のヘッダーはunknownのままです。既存の限定的なフィールド抽出は汎用YAML検証器ではなく、従来認識した形式は維持します。既存のフィールド・管理ツール・シンボリックリンク動作を維持し、通常ファイル以外のメタデータはunknownとします。不正な数値フィールドは別の有効なフィールドを消しません。YAMLやスキル指示は実行しません。 - #303: companion v0.3.3のソース`eb239fb358336d85b49bab2c80e4ea39037d1374`、SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`から互換スキルコピーを更新します。メタデータはPython 1.2.1と独立した0.3.3 / 最小0.9.1 / 全機能1.0.1です。グローバルへのスキル導入や、別の管理ツールで導入したスキルの更新ではありません。 +- #322(準備PR #321内): 一時領域の割り当て前に所有する領域の終了時削除を設定し、mktempが正確なパスを返すまで対象の`HUP/INT/TERM`を遅延します。割り当て子プロセスだけが一時的に信号を無視し、転送前に通常の終了処理を復元します。制御したローカルPOSIX受信コードの試験は従来の引き継ぎ窓を再現したもので、元のCI失敗の原因確定ではありません。既存導入とユーザー所有のsentinelを維持します。SIGKILL、ホスト喪失、削除中の任意の反復中断まで保証せず、コミット結果の不確実性と自動再試行禁止の契約は不変です。 保留した中止は割り当て処理・ファイルシステムI/Oの復帰を待つため、普遍的な中止期限は保証しません。外側のSSHタイムアウトもunknownで、自動再試行を許可しません。 + ## 検証と制限 最終統合ソース、生成された単独CLI、翻訳ハッシュ、パッケージ内容とインストール済みCLIを確認します。別ブランチの成功はこの準備の証拠を代替しません。最終コミットCI、独立レビュー、最新の依存関係監査が必要で、別途承認された準備PRのマージ後には正確な保護mainのCIも必要です。ローカルビルドは予行検証の証拠であり、公開用資産ではありません。 diff --git a/docs/ko/releases/v1.2.1.md b/docs/ko/releases/v1.2.1.md index 36a2dd1..886cbd8 100644 --- a/docs/ko/releases/v1.2.1.md +++ b/docs/ko/releases/v1.2.1.md @@ -4,7 +4,7 @@ 공개 버전 1.2.0을 기준으로 2026-10-19에 준비했습니다. 이는 소스 준비이며 공개 완료 안내가 아닙니다. 마지막 확인 안정판은 [GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)과 [PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)입니다. -범위 내 PR 3개를 아래 순서로 모두 병합했습니다. 통합 소스 기준은 `32e76d2c85d945d66466f630d9729ec0be5288d8`이며 최종 릴리스 준비·공개 커밋이 아닙니다. +별도 범위의 PR 3개를 아래 순서로 모두 병합했으며, 준비 PR #321에는 아래에 설명하는 #322 런타임 수정도 포함합니다. 통합 소스 기준은 `32e76d2c85d945d66466f630d9729ec0be5288d8`이며 최종 릴리스 준비·공개 커밋이 아닙니다. | PR | 이슈 | main 병합 커밋 | | --- | --- | --- | @@ -18,6 +18,8 @@ - #320: 문서 전체 크기와 별개로 제한된 앞부분의 스킬 메타데이터를 읽습니다. 16 KiB 헤더 한도에는 구분자와 줄 끝이 포함되며 추가 확인은 최대 1바이트입니다. 완결된 UTF-8 헤더만 해석하며 읽을 수 없거나 닫히지 않았거나 한도를 넘거나 UTF-8이 잘못된 헤더는 unknown으로 유지합니다. 기존의 제한된 필드 추출은 일반 YAML 검증기가 아니며 이전에 인식하던 형식은 계속 인식합니다. 기존 필드·관리 도구·심볼릭 링크 동작은 유지하며 일반 파일이 아닌 입력의 메타데이터는 unknown으로 처리합니다. 잘못된 숫자 필드가 별도로 유효한 필드를 지우지 않습니다. YAML이나 스킬 지침은 실행하지 않습니다. - #303: companion v0.3.3의 소스 `eb239fb358336d85b49bab2c80e4ea39037d1374`, SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`에서 호환 스킬 사본을 갱신합니다. 스킬 메타데이터는 Python 1.2.1과 별개인 0.3.3 / 최소 0.9.1 / 전체 1.0.1입니다. 전역 스킬 설치나 다른 관리 도구로 설치한 사본의 갱신을 수행하는 변경은 아닙니다. +- #322(준비 PR #321): 임시 디렉터리를 할당하기 전에 소유한 경로의 정리 처리를 등록하고, mktemp가 정확한 경로를 반환할 때까지 처리 대상 `HUP/INT/TERM`을 지연합니다. 할당 자식 프로세스만 잠시 이 신호를 무시하며 전송 전에 기존 종료 처리를 복원합니다. 제어된 로컬 POSIX 수신 코드 시험은 이전 인계 창을 재현한 것이지 원래 CI 실패의 원인을 확정한 것은 아닙니다. 기존 설치와 사용자 소유 sentinel을 보존합니다. SIGKILL·호스트 손실·정리 도중 임의의 반복 중단까지 정리를 보장하지 않으며, 커밋 결과의 불확실성과 자동 재시도 금지 계약은 바뀌지 않습니다. 보류된 취소는 할당 도구·파일시스템 I/O가 반환할 때까지 기다리므로 보편적인 취소 시간 제한을 보장하지 않습니다. 바깥 SSH 타임아웃도 계속 unknown이며 자동 재시도를 허용하지 않습니다. + ## 검증과 한계 최종 통합 소스, 생성된 독립 실행형 파일, 번역 해시, 패키지 내용과 설치된 CLI를 검토해야 합니다. 별도 브랜치의 검사 성공은 이번 준비의 증거를 대신하지 않습니다. 최종 커밋 CI·독립 검수·최신 의존성 감사가 남은 조건이며 별도 승인으로 준비 PR을 병합한 뒤에는 정확한 보호 main의 CI도 필요합니다. 로컬 빌드는 연습 검증의 증거이지 게시할 릴리스 자산이 아닙니다. diff --git a/docs/releases/v1.2.1.md b/docs/releases/v1.2.1.md index a149d76..00b9fc7 100644 --- a/docs/releases/v1.2.1.md +++ b/docs/releases/v1.2.1.md @@ -4,7 +4,7 @@ Prepared on 2026-10-19 against published 1.2.0. This is a source preparation, not a publication announcement. The last verified stable release is [v1.2.0 on GitHub](https://github.com/abruption/session-peer/releases/tag/v1.2.0) and [1.2.0 on PyPI](https://pypi.org/pypi/session-peer/1.2.0/json). -All three scoped PRs are merged in the order below. The integrated source base is `32e76d2c85d945d66466f630d9729ec0be5288d8`; it is not the final release-preparation or publication commit. +All three separately scoped PRs are merged in the order below; preparation PR #321 additionally carries the #322 runtime fix described below. The integrated source base is `32e76d2c85d945d66466f630d9729ec0be5288d8`; it is not the final release-preparation or publication commit. | PR | Issue | Main merge commit | | --- | --- | --- | @@ -18,6 +18,8 @@ All three scoped PRs are merged in the order below. The integrated source base i - #320: read bounded leading skill metadata independently of total document size. The 16 KiB header budget includes delimiters and line endings, with at most one extra byte of lookahead. Only the complete UTF-8 header is decoded; unreadable, unterminated, over-budget or invalid-UTF-8 headers remain unknown. Existing constrained field extraction is not a general YAML validator; legacy accepted forms remain accepted. Existing field, manager and symlink behavior is preserved; nonregular input yields unknown metadata, and an invalid numeric field does not erase a separately valid field. No YAML or skill instructions are executed. - #303: refresh the compatibility skill copy from companion v0.3.3, source `eb239fb358336d85b49bab2c80e4ea39037d1374`, SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`. Skill metadata remains 0.3.3 / minimum 0.9.1 / full 1.0.1, independently of Python 1.2.1. This is not a global skill installation or manager-owned update. +- #322 (in preparation PR #321): install owned-staging cleanup before allocation and defer handled `HUP/INT/TERM` until mktemp returns the exact path; only the allocation child temporarily ignores those signals. Restore normal termination handling before transfer. Controlled local POSIX receiver fixtures reproduce the previous hand-off gap, not the proven cause of the original CI failure. Preserve the old installation and user-owned sentinel. Cleanup is not guaranteed under SIGKILL, host loss or arbitrary repeated interruption during cleanup; commit uncertainty and the no-automatic-retry contract are unchanged. Pending cancellation waits for allocator/filesystem IO to return and is not a universal cancellation deadline; the outer SSH timeout still means unknown without automatic retry. + ## Validation and limits Review the final integrated source, generated standalone, translation hashes, package contents and installed CLI; passing checks on separate branches do not certify this preparation. Final-head CI, independent review and current dependency audits are still gates, followed by exact protected-main CI after the separately authorized preparation-PR merge. Local builds are rehearsal evidence, not publishable release assets. diff --git a/docs/zh-CN/releases/v1.2.1.md b/docs/zh-CN/releases/v1.2.1.md index 1aaa4dc..5342e59 100644 --- a/docs/zh-CN/releases/v1.2.1.md +++ b/docs/zh-CN/releases/v1.2.1.md @@ -4,7 +4,7 @@ 于2026-10-19基于已发布的1.2.0准备。这是源码准备,不是发布完成公告。最后验证的稳定版本为[GitHub v1.2.0](https://github.com/abruption/session-peer/releases/tag/v1.2.0)和[PyPI 1.2.0](https://pypi.org/pypi/session-peer/1.2.0/json)。 -范围内3项PR已按下列顺序全部合并。集成源码基准为`32e76d2c85d945d66466f630d9729ec0be5288d8`,并非最终发布准备或发布提交。 +单独范围的3项PR已按下列顺序全部合并;准备PR #321还包含下述#322运行时修复。集成源码基准为`32e76d2c85d945d66466f630d9729ec0be5288d8`,并非最终发布准备或发布提交。 | PR | 议题 | main合并提交 | | --- | --- | --- | @@ -18,6 +18,8 @@ - #320:仅读取有界的起始技能元数据,不依赖文档总大小。16 KiB头部预算包含分隔符和行尾,最多额外预读1字节。只解码完整UTF-8头部;无法读取、未闭合、超限或无效UTF-8头部仍为unknown。既有受限字段提取不是通用YAML验证器,原先接受的形式仍被接受。保留既有字段、管理器和符号链接行为,非常规文件的元数据为unknown。错误数值字段不会清除另一个有效字段。不执行YAML或技能指令。 - #303:从companion v0.3.3的源码`eb239fb358336d85b49bab2c80e4ea39037d1374`、SHA-256 `15378c6d503a69d1d738ac4739182e23257aa6f2f7fd31ef3fd2fa60e692867f`更新兼容技能副本。技能元数据为0.3.3 / 最低0.9.1 / 完整1.0.1,与Python 1.2.1独立。这不是全局技能安装或管理器拥有的安装更新。 +- #322(在准备PR #321中):分配前注册自有暂存目录的退出清理,并将处理范围内的`HUP/INT/TERM`延迟到mktemp返回准确路径之后;仅分配子进程临时忽略这些信号,传输前恢复正常终止处理。受控本地POSIX接收端试验重现了旧的交接窗口,不能证明原CI失败的原因。保留旧安装和用户所有的sentinel。SIGKILL、主机失联或清理中的任意反复中断不在清理保证范围内;提交不确定性及禁止自动重试的契约不变。 待处理取消须等待分配操作/文件系统I/O返回,不保证普遍的有界取消时间;外层SSH超时仍为unknown且不允许自动重试。 + ## 验证与限制 须审核最终集成源码、生成的独立CLI、翻译哈希、包内容和已安装CLI。独立分支的成功不能验证本次准备。最终提交CI、独立审核及最新依赖审计仍是门禁;另行批准并合并准备PR后,还须准确受保护main的CI成功。本地构建仅是演练证据,不是可发布资产。 diff --git a/session_peer.py b/session_peer.py index 4301b6c..7bb8797 100644 --- a/session_peer.py +++ b/session_peer.py @@ -3991,6 +3991,13 @@ def owns_publication(): os.close(lock) """ expected_line = f"session-peer {__version__}" + # Defer handled signals until the exact owned staging path is captured. + # Only the allocation child ignores them: otherwise mktemp can create a + # directory, die before printing it, and leave the parent nothing to clean. + # This is not cleanup assurance for SIGKILL, host loss or repeated signals + # interrupting a later cleanup/publication operation. + # Pending cancellation waits for allocator/filesystem IO to return; it has + # no universal time bound. The outer SSH timeout still means unknown. remote_script = ( "set -eu; umask 077; " 'D="$HOME/.local/share/session-peer"; B="$HOME/.local/bin"; ' @@ -3998,8 +4005,12 @@ def owns_publication(): '[ ! -L "$P" ] || ' "{ echo 'remote update: installation directory is a symlink' >&2; exit 1; }; done; " 'mkdir -p "$D" "$B"; ' - 'T=$(mktemp -d "$D/.session-peer-update.XXXXXXXX"); ' - "trap 'rm -rf \"$T\"' EXIT; trap 'exit 1' HUP INT TERM; " + 'T=""; update_interrupted=0; ' + "trap 'if [ -n \"$T\" ]; then rm -rf \"$T\"; fi' EXIT; " + "trap 'update_interrupted=1' HUP INT TERM; " + 'T=$(trap \'\' HUP INT TERM; mktemp -d "$D/.session-peer-update.XXXXXXXX"); ' + "trap 'exit 1' HUP INT TERM; " + '[ "$update_interrupted" -eq 0 ] || exit 1; ' f'python3 -c {shlex.quote(decoder)} "$T/session_peer.py" ' f"{hashlib.sha256(source).hexdigest()} {len(source)}; " 'V=$(python3 "$T/session_peer.py" --version); ' diff --git a/session_peer_core/ssh.py b/session_peer_core/ssh.py index 5e8b54d..28ff630 100644 --- a/session_peer_core/ssh.py +++ b/session_peer_core/ssh.py @@ -785,6 +785,13 @@ def owns_publication(): os.close(lock) """ expected_line = f"session-peer {__version__}" + # Defer handled signals until the exact owned staging path is captured. + # Only the allocation child ignores them: otherwise mktemp can create a + # directory, die before printing it, and leave the parent nothing to clean. + # This is not cleanup assurance for SIGKILL, host loss or repeated signals + # interrupting a later cleanup/publication operation. + # Pending cancellation waits for allocator/filesystem IO to return; it has + # no universal time bound. The outer SSH timeout still means unknown. remote_script = ( "set -eu; umask 077; " 'D="$HOME/.local/share/session-peer"; B="$HOME/.local/bin"; ' @@ -792,8 +799,12 @@ def owns_publication(): '[ ! -L "$P" ] || ' "{ echo 'remote update: installation directory is a symlink' >&2; exit 1; }; done; " 'mkdir -p "$D" "$B"; ' - 'T=$(mktemp -d "$D/.session-peer-update.XXXXXXXX"); ' - "trap 'rm -rf \"$T\"' EXIT; trap 'exit 1' HUP INT TERM; " + 'T=""; update_interrupted=0; ' + "trap 'if [ -n \"$T\" ]; then rm -rf \"$T\"; fi' EXIT; " + "trap 'update_interrupted=1' HUP INT TERM; " + 'T=$(trap \'\' HUP INT TERM; mktemp -d "$D/.session-peer-update.XXXXXXXX"); ' + "trap 'exit 1' HUP INT TERM; " + '[ "$update_interrupted" -eq 0 ] || exit 1; ' f'python3 -c {shlex.quote(decoder)} "$T/session_peer.py" ' f"{hashlib.sha256(source).hexdigest()} {len(source)}; " 'V=$(python3 "$T/session_peer.py" --version); ' diff --git a/tests/core/test_remote_update.py b/tests/core/test_remote_update.py index c4bc4c6..d0826ec 100644 --- a/tests/core/test_remote_update.py +++ b/tests/core/test_remote_update.py @@ -13,6 +13,7 @@ import os from pathlib import Path import shlex +import shutil import signal import subprocess import sys @@ -120,6 +121,111 @@ def mark_lock_attempt(self, script, marker): self.assertIn(call, script) return script.replace(call, marked) + def controlled_command(self, name, content): + directory = self.root / "controlled-bin" + directory.mkdir(exist_ok=True) + command = directory / name + command.write_text("#!/bin/sh\n" + content, encoding="utf-8") + command.chmod(0o700) + self.environment["PATH"] = str(directory) + os.pathsep + self.environment["PATH"] + + def partial_process(self, script, payload): + process = subprocess.Popen(["sh", "-c", script], stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + text=True, env=self.environment, start_new_session=True) + def cleanup(): + if process.poll() is None: + os.killpg(process.pid, signal.SIGKILL) + process.communicate(timeout=5) + self.addCleanup(cleanup) + process.stdin.write(payload) + process.stdin.flush() + return process + + def decoder_marker(self, script): + call = "staged.write(decoded)" + self.assertIn(call, script) + # Double quotes keep the instrumentation inside the generated shell's + # already-quoted Python argument. This is a local fixture only. + return script.replace(call, call + '; staged.flush(); ' + '__import__("pathlib").Path(__import__("os").environ["HOME"], "decoder-ready").touch()') + + def assert_interrupted_creation(self, signum): + real_mktemp = shutil.which("mktemp", path=self.environment["PATH"]) + self.assertIsNotNone(real_mktemp) + self.controlled_command("mktemp", "set -eu\n" + "stage=$(" + shlex.quote(real_mktemp) + ' "$@")\n' + ': > "$HOME/mktemp-created"\n' + 'while [ ! -e "$HOME/release-mktemp" ]; do sleep 0.01; done\n' + 'printf \'%s\\n\' "$stage"\n') + # The receiver must never clean an inherited, unowned shell variable. + self.environment["T"] = str(self.sentinel) + script, payload = self.script() + process = self.partial_process(script, payload[:4096]) + try: + self.wait_for(self.home / "mktemp-created", process) + self.assertEqual(len(list(self.install.glob(".session-peer-update.*"))), 2) + os.killpg(process.pid, signum) + (self.home / "release-mktemp").touch() + output, error = process.communicate(timeout=5) + self.assertNotEqual(process.returncode, 0) + self.assertEqual(output, "", "Interruption must not produce an installed receipt") + self.assert_preserved() + receipt = subprocess.CompletedProcess([], process.returncode, output, error) + with mock.patch.object(session_peer.Path, "read_bytes", return_value=self.SOURCE), \ + mock.patch.object(session_peer, "__version__", self.VERSION), \ + mock.patch.object(session_peer.subprocess, "run", return_value=receipt) as run, \ + self.assertRaises(session_peer.CcPeerError) as caught: + session_peer.push_to_remote("fixture", [], {}) + self.assertEqual(caught.exception.details["commitStatus"], "unknown") + self.assertFalse(caught.exception.details["retryAllowed"]) + run.assert_called_once() + finally: + (self.home / "release-mktemp").touch() + + def test_hup_between_mktemp_creation_and_return_cleans_owned_staging(self): + self.assert_interrupted_creation(signal.SIGHUP) + + def test_int_between_mktemp_creation_and_return_cleans_owned_staging(self): + self.assert_interrupted_creation(signal.SIGINT) + + def test_term_between_mktemp_creation_and_return_cleans_owned_staging(self): + self.assert_interrupted_creation(signal.SIGTERM) + + def test_signal_during_marked_actual_transfer_preserves_old_installation(self): + script, payload = self.script() + process = self.partial_process(self.decoder_marker(script), payload[:65536]) + self.wait_for(self.home / "decoder-ready", process) + staged = list(self.install.glob(".session-peer-update.*/session_peer.py")) + self.assertEqual(len(staged), 1) + self.assertGreater(staged[0].stat().st_size, 0) + os.killpg(process.pid, signal.SIGTERM) + output, _ = process.communicate(timeout=5) + self.assertNotEqual(process.returncode, 0) + self.assertEqual(output, "") + self.assert_preserved() + + def test_parent_wait_includes_foreground_trap_cleanup(self): + real_rm = shutil.which("rm", path=self.environment["PATH"]) + self.assertIsNotNone(real_rm) + self.controlled_command("rm", ': > "$HOME/cleanup-entered"\n' + 'while [ ! -e "$HOME/release-cleanup" ]; do sleep 0.01; done\n' + "exec " + shlex.quote(real_rm) + ' "$@"\n') + script, payload = self.script() + process = self.partial_process(self.decoder_marker(script), payload[:65536]) + try: + self.wait_for(self.home / "decoder-ready", process) + os.killpg(process.pid, signal.SIGTERM) + self.wait_for(self.home / "cleanup-entered", process) + self.assertIsNone(process.poll(), "Parent must wait for its foreground cleanup") + self.assertEqual(self.target.read_bytes(), self.old) + (self.home / "release-cleanup").touch() + process.communicate(timeout=5) + self.assertNotEqual(process.returncode, 0) + self.assert_preserved() + finally: + (self.home / "release-cleanup").touch() + def test_interleaved_failed_update_cannot_roll_back_successful_different_version(self): first = (b"import os, time\nfrom pathlib import Path\n" b"home = Path(os.environ['HOME'])\n" diff --git a/tests/docs/test_release_commands.py b/tests/docs/test_release_commands.py index fab2fd9..9f58c7a 100644 --- a/tests/docs/test_release_commands.py +++ b/tests/docs/test_release_commands.py @@ -24,7 +24,7 @@ def test_v121_preparation_has_no_executable_publication_instructions(self): self.assertNotRegex(section, r"(?m)^\s*(?:git\s+(?:tag|push)\b|gh\s+(?:release\b|workflow\s+run\b)|release_tag=)") self.assertNotIn("PENDING", section) for marker in ("2026-10-19", "1.2.1", "1.2.0", "#319", "#317", "#320", "#318", - "#303", "#302", "#316", "Trusted Publisher", "pypi", "attach-draft", + "#303", "#302", "#316", "#321", "#322", "SIGKILL", "Trusted Publisher", "pypi", "attach-draft", "SHA256SUMS", "release-provenance.json"): self.assertIn(marker, section) diff --git a/tests/docs/test_stable_candidate.py b/tests/docs/test_stable_candidate.py index 38526e2..019c46f 100644 --- a/tests/docs/test_stable_candidate.py +++ b/tests/docs/test_stable_candidate.py @@ -44,6 +44,7 @@ def test_v121_preparation_records_patch_sources_and_publication_gates(self): for marker in ("1.2.1", "1.2.0", "2026-10-19", "macOS", "Windows/Linux", "CLAUDE_CONFIG_DIR", "ANTHROPIC_CONFIG_DIR", "16 KiB", "UTF-8", "0.3.3", "0.9.1", "1.0.1", "#316", "#161", "20/21", + "#321", "#322", "HUP/INT/TERM", "SIGKILL", "#180", "#181", "#268", "#304", "#306", "#307", "Control/Relay", "pypi", "attach-draft", "SHA256SUMS", "release-provenance.json", "ad4aa0e464fb142424f6fb6a30303bb88e47163e", @@ -58,7 +59,9 @@ def test_v121_preparation_records_patch_sources_and_publication_gates(self): "refuses all target selection", "ordinary socket aliases remain supported", "not publishable release assets", "required human pypi environment approval", "not a reservation", "no executable release commands", - "does not authorize its own merge", "never rebuild or replace immutable assets"): + "does not authorize its own merge", "never rebuild or replace immutable assets", + "not the proven cause of the original CI failure", "only the allocation child", + "no-automatic-retry contract are unchanged", "not a universal cancellation deadline"): self.assertIn(marker, notes[0]) def test_v120_publication_addendum_does_not_erase_candidate_history(self): From 94bdb656c17782040e900add09e705371f084db4 Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Mon, 19 Oct 2026 14:45:33 +0900 Subject: [PATCH 5/6] test(update): prove deferred cancellation prevents decoder entry --- tests/core/test_remote_update.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/core/test_remote_update.py b/tests/core/test_remote_update.py index d0826ec..c208e47 100644 --- a/tests/core/test_remote_update.py +++ b/tests/core/test_remote_update.py @@ -161,6 +161,12 @@ def assert_interrupted_creation(self, signum): # The receiver must never clean an inherited, unowned shell variable. self.environment["T"] = str(self.sentinel) script, payload = self.script() + entry = "digest = hashlib.sha256()" + self.assertEqual(script.count(entry), 1) + # Persist outside staging: cleanup must not hide a decoder that ran + # despite cancellation recorded while allocation was still returning. + script = script.replace(entry, entry + '; ' + '__import__("pathlib").Path(__import__("os").environ["HOME"], "decoder-entered").touch()') process = self.partial_process(script, payload[:4096]) try: self.wait_for(self.home / "mktemp-created", process) @@ -170,6 +176,8 @@ def assert_interrupted_creation(self, signum): output, error = process.communicate(timeout=5) self.assertNotEqual(process.returncode, 0) self.assertEqual(output, "", "Interruption must not produce an installed receipt") + self.assertFalse((self.home / "decoder-entered").exists(), + "Pending cancellation must prevent decoder entry") self.assert_preserved() receipt = subprocess.CompletedProcess([], process.returncode, output, error) with mock.patch.object(session_peer.Path, "read_bytes", return_value=self.SOURCE), \ From 3e65a667b8bb53db1df62c6501554b62c66c132e Mon Sep 17 00:00:00 2001 From: YEONGUK LEE Date: Mon, 19 Oct 2026 14:53:58 +0900 Subject: [PATCH 6/6] test(update): cover allocation cancellation under Bash --- tests/core/test_remote_update.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/core/test_remote_update.py b/tests/core/test_remote_update.py index c208e47..597dbb1 100644 --- a/tests/core/test_remote_update.py +++ b/tests/core/test_remote_update.py @@ -200,6 +200,27 @@ def test_int_between_mktemp_creation_and_return_cleans_owned_staging(self): def test_term_between_mktemp_creation_and_return_cleans_owned_staging(self): self.assert_interrupted_creation(signal.SIGTERM) + def assert_bash_interrupted_creation(self, signum): + bash = shutil.which("bash", path=self.environment["PATH"]) + if bash is None: + self.skipTest("Bash is not installed") + version = subprocess.run([bash, "--version"], capture_output=True, + text=True, check=True, timeout=5) + print("Receiver fixture shell: " + version.stdout.splitlines()[0], flush=True) + # Exercise Bash's ordinary (non-POSIX) invocation as well as the sh + # path above. CI supplies its own installed Bash; no shell is fetched. + self.controlled_command("sh", "exec " + shlex.quote(bash) + ' "$@"\n') + self.assert_interrupted_creation(signum) + + def test_bash_hup_between_mktemp_creation_and_return_cleans_owned_staging(self): + self.assert_bash_interrupted_creation(signal.SIGHUP) + + def test_bash_int_between_mktemp_creation_and_return_cleans_owned_staging(self): + self.assert_bash_interrupted_creation(signal.SIGINT) + + def test_bash_term_between_mktemp_creation_and_return_cleans_owned_staging(self): + self.assert_bash_interrupted_creation(signal.SIGTERM) + def test_signal_during_marked_actual_transfer_preserves_old_installation(self): script, payload = self.script() process = self.partial_process(self.decoder_marker(script), payload[:65536])