From 4c1804d196378e7ce19f4faec6e8dde3d03c6b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=90=EC=84=B1=EC=A4=80?= Date: Wed, 2 Sep 2026 08:09:47 +0900 Subject: [PATCH] =?UTF-8?q?RC3=20=EA=B3=B5=EA=B0=9C=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EB=9F=BF=20=EC=9A=B4=EC=98=81=20=EB=AC=B8=EC=84=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 3 + .github/workflows/release.yml | 3 + README.md | 6 +- SECURITY.md | 57 +++++++ docs/development/npm-distribution.md | 9 +- .../rc3-developer-preview-pilot.md | 147 ++++++++++++++++++ docs/development/rc3-release-candidate.md | 5 + docs/development/releasing.md | 6 +- docs/getting-started.md | 97 +++++++++++- scripts/check-rc3-public-docs.sh | 84 ++++++++++ 10 files changed, 410 insertions(+), 7 deletions(-) create mode 100644 SECURITY.md create mode 100644 docs/development/rc3-developer-preview-pilot.md create mode 100644 scripts/check-rc3-public-docs.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e9107d..f965817 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,9 @@ jobs: sh scripts/check-release-workflow.sh sh scripts/check-npm-distribution-workflow.sh + - name: Check RC3 public documentation + run: sh scripts/check-rc3-public-docs.sh + - name: Build release workspace run: cargo build --workspace --release --locked diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f93c7f9..131be96 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -132,6 +132,9 @@ jobs: sh scripts/check-release-workflow.sh sh scripts/check-npm-distribution-workflow.sh + - name: Check RC3 public documentation + run: sh scripts/check-rc3-public-docs.sh + build: name: Build / ${{ matrix.target }} needs: quality diff --git a/README.md b/README.md index ec8151a..4dc7b7b 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,8 @@ Process는 shell 없이 실행되지만 별도 `--allow-execute` 전에는 code를 실행하므로 이는 sandbox가 아니다. 승인·재개 예시는 [시작하기](docs/getting-started.md)를 따른다. RC3의 포함 범위와 알려진 한계는 [Developer Preview RC3 후보](docs/development/rc3-release-candidate.md)에 -정리되어 있다. +정리되어 있다. 일반 문제는 GitHub Issues, 민감한 취약점은 [보안 정책](SECURITY.md)의 비공개 신고 +경로를 사용한다. 대화형 모드는 현재 디렉터리 전체를 workspace catalog로 열되 실제 read/write/execute와 model egress를 각각 별도로 승인한다. `/model`, `/status`, `/permissions`, `/resume`, `/clear`, `/exit`을 지원하며 줄 끝 @@ -168,7 +169,8 @@ cargo run --locked --quiet -p xgeny-cli -- protocol check 상세한 로컬·CI 검증 범위는 [Rust 워크스페이스 개발 환경](docs/development/rust-workspace.md)을 참고합니다. Router의 fail-closed filter, ranking과 권한 경계는 [결정론적 Capability Router 기본형](docs/development/deterministic-router.md), 재시작 전 실행 인자 경계는 [Recoverable Invocation Material 기본형](docs/development/recoverable-invocation-material.md), exact adapter 실행 경계는 [Direct Executor 기본형](docs/development/direct-executor.md), 검증과 Receipt 종결은 [Core Verification과 Execution Receipt 기본형](docs/development/execution-receipt.md), 장기 Run 검증 비용은 [Verified Run Index와 장기 Run 검증](docs/development/verified-run-index.md), dependency와 재개 순서는 [Persistent WorkGraph와 재개 frontier](docs/development/persistent-workgraph.md), 계획 수락·예산·재시작 계약은 [Durable Planner와 bounded AgentLoop](docs/development/durable-planner-loop.md), provider 호출 전 예약·불확정 복구 경계는 [Durable model-call lifecycle](docs/development/durable-model-call-lifecycle.md), 첫 실제 모델 연결은 [OpenAI-compatible Provider Adapter](docs/development/openai-compatible-provider.md), ReadOnly와 CLI 조합 기반은 [ReadOnly와 bounded CLI driver 기반](docs/development/read-only-driver-foundation.md), 제품 workspace read 경계는 [Capability-confined filesystem read adapter](docs/development/filesystem-read-adapter.md), 프로젝트 탐색과 dynamic material 재개는 [Workspace filesystem discovery](docs/development/workspace-filesystem-discovery.md), whole-file mutation은 [Workspace atomic write](docs/development/workspace-atomic-write.md), strict small edit는 [Workspace apply patch](docs/development/workspace-apply-patch.md), 공개 명령과 process 재개 절차는 [Public local run/resume prototype](docs/development/public-local-run-resume.md), 실제 OS I/O를 쓰는 비제품 기준은 [Preopened Reference Adapter Conformance](docs/development/reference-adapter-conformance.md), 기능 개발 순서와 테스트 계층·완료 기준은 [XGENy 개발 방법론과 테스트 전략](docs/development/engineering-method.md)을 따릅니다. Bare 명령의 입력, 승인, 진행 event와 Ctrl+C 의미는 [대화형 REPL](docs/development/interactive-repl.md)을 -따릅니다. +따릅니다. 실제 게시물의 Rust/Node.js/Python 제한 검증 절차와 비민감 결과 형식은 +[RC3 Developer Preview 파일럿](docs/development/rc3-developer-preview-pilot.md)을 따릅니다. ## Research diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..6049d12 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,57 @@ +# XGENy 보안 정책 + +## 지원 범위 + +XGENy는 Developer Preview다. 새 보안 수정은 원칙적으로 가장 최근에 게시된 immutable preview version에 +더 높은 새 version으로 제공한다. 이미 게시된 GitHub tag, Release asset 또는 npm package version을 +이동·교체·재사용하지 않는다. + +`v0.1.0-rc.3`이 게시되기 전의 최신 immutable release는 `v0.1.0-rc.2`다. RC3가 게시된 뒤에는 RC2에 새 +기능이나 보안 수정을 backport한다고 약속하지 않는다. RC2/RC3 Run의 호환·rollback 경계는 +[시작하기](docs/getting-started.md#업데이트와-rc2-rollback)를 따른다. + +## 비공개 신고 + +민감한 취약점은 public issue, discussion 또는 pull request에 작성하지 말고 GitHub의 +[비공개 취약점 신고](https://github.com/PlateerLab/xgeny-cli/security/advisories/new)를 사용한다. + +다음과 같은 최소 정보만 먼저 제공한다. + +- 영향을 받는 exact XGENy version과 설치 채널 +- OS family와 architecture +- 고정된 오류 코드 또는 민감정보를 제거한 재현 단계 +- 예상한 보안 경계와 실제 관찰의 차이 + +API key, endpoint credential, 실제 업무 source, prompt, model 원문 응답, tool stdout/stderr, Run state DB와 +개인 경로를 첨부하지 않는다. 추가 자료가 필요하면 private advisory 안에서 범위와 전달 방식을 먼저 +합의한다. Developer Preview에는 응답 시간 SLA가 없다. 공개 disclosure 시점과 교정 방안은 private +advisory에서 먼저 조율한다. 기존 immutable version은 수정하지 않고 필요한 경우 더 높은 새 version으로 +대응한다. + +일반 설치·사용 오류와 민감정보 없는 버그는 +[GitHub Issues](https://github.com/PlateerLab/xgeny-cli/issues)를 사용한다. + +## 주요 보안 경계 + +특히 다음 문제를 보안 신고 대상으로 본다. + +- model/read/write/execute 승인 우회 또는 승인 전 물리 I/O +- workspace scope 밖의 file 접근, symlink/reparse-point escape 또는 atomic write 경계 위반 +- API key나 protected environment의 model, child process, log, manifest 또는 artifact 유출 +- 불확정 model/effect의 자동 replay, 중복 non-idempotent 실행 또는 Receipt 검증 우회 +- checksum, provenance, npm package integrity나 installer destination 검증 우회 +- timeout/종료 뒤 descendant process tree가 계속 실행되는 문제 + +Model이 부정확한 답을 생성하는 것 자체는 보안 취약점이 아니다. 다만 비신뢰 model 제안이 위 승인, +capability, durable no-replay 또는 정보 노출 경계를 우회한다면 보안 문제다. + +`process.execute`는 shell을 사용하지 않지만 OS sandbox가 아니다. 사용자가 허용한 compiler, package +manager, interpreter와 그 child는 현재 사용자 권한으로 project code를 실행할 수 있다. 이 명시된 경계 +자체와, 구현이 그 경계를 위반하는 문제를 구분한다. + +## 게시물 확인 + +재현에는 가능하면 exact version을 사용한다. GitHub asset은 `checksums.sha256`과 build attestation을, +npm package는 exact version, registry integrity와 provenance를 확인한다. Checksum은 전송 무결성을 +확인하지만 publisher identity나 OS code signing을 대신하지 않는다. RC3 macOS/Windows binary에는 아직 +notarization/Authenticode가 없다. diff --git a/docs/development/npm-distribution.md b/docs/development/npm-distribution.md index d5a90a5..b322788 100644 --- a/docs/development/npm-distribution.md +++ b/docs/development/npm-distribution.md @@ -4,6 +4,10 @@ 사용자는 Node.js가 필요 없고, npm 경로를 고른 사용자는 Node.js 22.14 이상이 필요하다. 두 경로는 같은 release binary를 실행한다. +이 package 이름은 설치 entrypoint를 뜻하며 화면 구현을 뜻하지 않는다. 현재 가벼운 REPL이나 향후 같은 +`xgeny` binary에 포함될 TUI는 동일한 `@xgen/cli`로 배포할 수 있다. TUI를 별도 제품·release cadence로 +분리할 때만 별도 package naming ADR을 먼저 작성한다. + ## Package 구성 | Package | 대상 | @@ -96,7 +100,8 @@ npm test --prefix npm sh scripts/check-npm-distribution-workflow.sh ``` -각 platform CI는 release binary를 platform tarball에 넣고 loopback registry에서 `npm install -g`를 -수행한다. Release assemble은 여섯 tarball의 file allow-list, 고지와 raw binary byte parity를 확인한다. +각 platform CI는 release binary를 platform tarball에 넣고 loopback registry에서 `npm install -g`, +대화형 `/status`/`/exit`, 동일 version 재설치와 `npm uninstall -g`를 수행한다. Release assemble은 여섯 +tarball의 file allow-list, 고지와 raw binary byte parity를 확인한다. 로컬이나 PR에서는 실제 npm publish, package bootstrap, Trusted Publisher 변경과 release tag 생성을 수행하지 않는다. diff --git a/docs/development/rc3-developer-preview-pilot.md b/docs/development/rc3-developer-preview-pilot.md new file mode 100644 index 0000000..3f726aa --- /dev/null +++ b/docs/development/rc3-developer-preview-pilot.md @@ -0,0 +1,147 @@ +# RC3 Developer Preview 파일럿 + +이 문서는 게시된 `v0.1.0-rc.3` artifact가 일반 개발자의 작은 코딩 작업을 끝까지 수행하는지 확인하는 +제한 파일럿 runbook이다. Release 이전 source checkout이나 local build 결과를 사용자 결과로 대체하지 +않는다. 파일럿 project와 state는 폐기 가능한 전용 위치에서 만들고 실제 업무 source나 credential을 +사용하지 않는다. + +## 사전 조건과 중단 조건 + +- GitHub Release `v0.1.0-rc.3`과 `@xgen/cli@0.1.0-rc.3`이 게시됐고 provenance, checksum과 package + integrity 검증이 끝나야 한다. +- 각 참여자는 repository checkout이나 Rust compiler 없이 먼저 설치·온보딩 smoke를 통과한다. 언어별 + compiler/interpreter는 해당 coding fixture 실행을 위해서만 사용한다. +- Fixture의 실패 test와 acceptance condition은 model 실행 전에 고정한다. 실행 결과를 보고 task를 + 바꾸거나 성공 사례만 남기지 않는다. +- API key, endpoint 전체 URL, prompt, model 원문 응답, source, tool stdout/stderr 또는 state DB가 결과 + 기록에 들어가면 해당 기록을 폐기하고 보안 사고 절차를 우선한다. +- 예상하지 못한 외부 변경, credential 노출, workspace 밖 mutation 또는 자동 replay 징후가 있으면 즉시 + 파일럿을 중단한다. + +## 사전 고정 사용자 matrix + +| Pilot | Project | 진입 경로 | 허용 executable | 필수 관찰 | +| --- | --- | --- | --- | --- | +| `rust-bare` | 작은 Cargo project | bare `xgeny` | `cargo` | 탐색, 수정, 실패 test 관찰, 교정, test/build 성공, `/status`, `/exit` | +| `node-resume` | Node.js built-in test fixture | `run` → `resume` | `node` | read/write와 분리된 execute 승인, `node --test`, `node --check`, offline replay | +| `python-resume` | 표준 `unittest` fixture | `run` → `resume` | `python3` 또는 `python` | 별도 execute 승인, 실패 분석, `-m unittest`, `-m compileall`, offline replay | + +각 fixture는 작은 논리 오류 하나와 이를 검출하는 기존 test를 가진다. Model이 test를 삭제·완화하거나 +acceptance를 바꾸면 실패다. Rust scenario는 대화형 UX를, Node.js와 Python scenario는 process를 실행하기 +직전 pause한 durable Run을 별도 `resume --allow-execute`로 계속하는 경계를 담당한다. + +## 공통 설치와 온보딩 + +각 OS/architecture에서 native installer와 npm 중 배정된 공개 채널만 사용한다. 설치 후 아래 순서를 +repository 밖의 깨끗한 home/state에서 실행한다. + +```text +install exact version + -> xgeny --version + -> xgeny model setup + -> xgeny model check --compatibility + -> bare xgeny + -> /status + -> /exit + -> same-version reinstall + -> remove +``` + +온보딩 key는 숨김 입력 또는 secret manager의 stdin으로만 전달한다. 일반 설정, shell script, command +argument나 결과 ledger에 복사하지 않는다. `model setup`이 catalog와 실제 structured inference를 모두 +통과하지 않으면 coding pilot을 시작하지 않는다. + +## 대화형 Rust 절차 + +1. 폐기 가능한 Rust fixture root에서 `xgeny`를 실행하고 `/status`로 active model과 idle 상태를 확인한다. +2. 기존 실패 test를 유지하면서 project를 탐색하고 원인을 수정한 뒤 test/build하도록 요청한다. +3. Model egress, read, write와 execute 승인이 각각 별도로 나타나는지 확인한다. +4. 첫 실행 실패가 있으면 bounded durable output을 다음 turn이 관찰해 교정하는지 확인한다. +5. 성공 후 `/status`, `/exit`으로 정상 종료하고 새 process에서 완료 Run을 offline replay한다. + +자유 형식 token streaming이나 prompt 품질을 평가하지 않는다. 합격 기준은 acceptance test/build와 durable +상태 전이이며, 최종 source나 output은 결과 ledger에 복사하지 않는다. + +## 비대화형 Node.js와 Python 절차 + +각 fixture에서 처음에는 `--allow-execute`를 빼고 실행한다. `RUNTIME_ID`는 Node.js의 `node`, Python의 +`python`이고 `EXE`는 operator가 신뢰한 executable의 absolute path다. Model에는 logical ID만 보인다. + +```bash +xgeny run \ + --workspace . \ + --allow-dir . \ + --allow-executable RUNTIME_ID="EXE" \ + --allow-remote-model-egress \ + --allow-read \ + --allow-write \ + '기존 테스트를 유지하며 실패 원인을 수정하고 테스트와 구문 검사를 통과시켜줘.' +``` + +`execute_approval_required`로 pause한 exact Run ID를 같은 workspace, directory scope와 executable binding으로 +재개한다. + +```bash +xgeny resume RUN_ID \ + --workspace . \ + --allow-dir . \ + --allow-executable RUNTIME_ID="EXE" \ + --allow-remote-model-egress \ + --allow-read \ + --allow-write \ + --allow-execute +``` + +Node.js fixture는 shell script나 package lifecycle hook 대신 `node --test`와 `node --check`만 사용한다. +Python fixture는 추가 package 설치 없이 `python -m unittest`와 `python -m compileall`만 사용한다. 완료 뒤 +model credential, workspace와 executable 없이 `xgeny resume RUN_ID`가 같은 completion을 offline +replay해야 한다. + +## 복구·중단 안전성 확인 + +사용자 파일럿과 같은 release SHA의 필수 CI가 다음 회귀를 모두 통과한 상태여야 한다. + +- read/write/execute 승인 분리와 승인 전 물리 I/O 0회 +- idle 및 model call 중 Ctrl+C의 safe pause 또는 Unknown 종결 +- timeout과 정상 leader 종료 뒤 descendant process tree 정리 +- process/model outcome commit 장애와 process exit 뒤 effect/model call 자동 replay 0회 +- 완료 Run offline replay와 journal 불변성 + +파일럿에서는 한 대화형 Run을 model call 중 Ctrl+C로 중단하고 `/status`와 `/resume`의 redacted 상태가 +위 계약과 일치하는지 확인한다. 불확정 call/effect가 Unknown이면 성공으로 바꾸거나 다시 실행하지 않는다. +Fault injection이나 process-tree sentinel 검증은 동일 SHA의 자동화 test 결과를 권위로 사용하며 일반 +사용자 PC에서 임의로 장애를 주입하지 않는다. + +## 비민감 결과 ledger + +한 행은 사전 고정 pilot 한 번이다. 다음 필드만 기록한다. + +| 필드 | 허용 값 | +| --- | --- | +| release | tag, immutable release commit SHA, npm/native channel | +| host | OS family/version, architecture, 설치 성공 여부 | +| runtime | Rust/Node.js/Python version과 scenario ID | +| model | 공개 가능한 served model ID만 기록하거나 `redacted` | +| mode | `bare` 또는 `run-resume` | +| outcome | `pass`, `product-failure`, `model-variance`, `environment-failure`, `security-stop` | +| stage | `install`, `onboarding`, `explore`, `edit`, `test`, `correct`, `build`, `replay`, `remove` | +| metrics | elapsed seconds, model call 수, tool step 수, approval 수, retry 수 | +| invariants | Unknown 수, duplicate effect 수, process-tree leak 여부, offline replay 여부 | +| diagnostic | 고정된 redacted error code만 허용 | + +Run ID, path, filename, goal, prompt, endpoint, credential, response, source diff, tool output과 state digest는 +기록하지 않는다. Aggregate 문서에는 scenario별 시도/성공 수, 중앙 elapsed time, 실패 stage 빈도와 +invariant 위반 수만 남긴다. 표본이 작으므로 모델 품질의 일반적 우월성이나 통계적 유의성을 주장하지 +않는다. + +## 합격 기준과 결과 처리 + +- 세 사전 고정 scenario가 각각 최소 한 번 성공하고 실패 실행도 삭제하지 않고 분류한다. +- `bare`와 `run-resume`, 설치·온보딩·재설치·제거, 실제 model 연결과 offline replay가 모두 관찰된다. +- Model/read/write/execute 승인 분리가 유지되고 duplicate effect, process-tree leak과 민감정보 기록은 0이다. +- Unknown은 자동 재실행 0회를 유지해야 하며, Unknown 자체를 억지로 성공 처리하지 않는다. +- 제품 결함은 재현 test와 별도 PR로 수정한 뒤 전체 필수 CI와 해당 pilot을 다시 수행한다. +- 치명적 공개 결함은 기존 immutable release나 npm version을 수정하지 않고 새 version으로 교정한다. + +결과 집계는 게시 artifact와 commit을 명시하되 원문 실행 자료를 포함하지 않는다. 이 기준을 모두 만족한 +경우에만 RC3 제한 파일럿을 통과했다고 기록한다. diff --git a/docs/development/rc3-release-candidate.md b/docs/development/rc3-release-candidate.md index 67a35c5..df2b8cb 100644 --- a/docs/development/rc3-release-candidate.md +++ b/docs/development/rc3-release-candidate.md @@ -88,6 +88,11 @@ GitHub PR에서는 Quality/Linux와 Linux x86-64/ARM64, macOS Intel/Apple Silico clippy, protocol check, native dependency audit, release binary staging, installer smoke와 npm pack/global install smoke를 수행한다. +실제 게시물의 Rust/Node.js/Python 제한 사용자 검증은 +[RC3 Developer Preview 파일럿](rc3-developer-preview-pilot.md)의 사전 고정 matrix, 개인정보 경계와 +합격 조건을 따른다. 파일럿 중 prompt, source, endpoint, credential과 원문 tool/model output은 결과 +기록에 남기지 않는다. + ## 알려진 한계 - `process.execute`는 command injection을 줄이는 capability boundary이지 OS sandbox가 아니다. 허용한 diff --git a/docs/development/releasing.md b/docs/development/releasing.md index 703deea..6628459 100644 --- a/docs/development/releasing.md +++ b/docs/development/releasing.md @@ -97,8 +97,10 @@ Publish 이전에는 다음을 다시 확인한다. 10. 최종 asset allow-list, `sha256sum -c`, 조립된 Linux fixture installer smoke와 GitHub artifact attestation 11. GitHub 게시 뒤 npm OIDC Trusted Publishing으로 platform package 다섯 개와 launcher 순차 게시, provenance·SRI·dist-tag 검증 -12. 게시 뒤 다섯 target에서 GitHub public exact-tag 및 exact npm version 설치, stable release의 - `releases/latest/download` bootstrap과 내부 `latest` 해석, state 미생성 +12. 게시 뒤 다섯 target에서 GitHub public exact-tag 및 exact npm version 설치, 대화형 `/status`/`/exit`, + 동일 version 재설치·제거, stable release의 `releases/latest/download` bootstrap과 내부 `latest` + 해석 +13. 게시된 artifact만 사용한 Rust/Node.js/Python 제한 파일럿과 비민감 집계 결과 검토 Read-only assemble job은 검증된 target artifact와 installer·고지를 조립하고 checksum을 확인한 뒤 하나의 allow-listed bundle로 전달한다. Checkout이나 repository script를 실행하지 않는 publish job은 diff --git a/docs/getting-started.md b/docs/getting-started.md index 190619c..fa84b51 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -9,6 +9,25 @@ Node.js, SQLite 실행 파일, Docker 또는 XGENy state용 별도 daemon이 필 launcher용 Node.js 22.14 이상이 필요하다. 사용할 model endpoint 자체는 로컬 또는 원격에 별도로 실행 중이어야 한다. +## 5분 빠른 시작 + +먼저 사용할 OpenAI-compatible endpoint URL, served model ID와 필요한 경우 API key를 준비한다. Node.js +22.14 이상이 있는 지원 OS에서는 아래 순서가 가장 짧다. + +```bash +npm install --global --include=optional @xgen/cli@0.1.0-rc.3 +xgeny --version +xgeny model setup +xgeny model check --compatibility +cd my-project +xgeny +``` + +대화형 화면에서 `/status`로 선택 model과 idle 상태를 확인하고, 작은 읽기 전용 작업으로 첫 승인을 +확인한 뒤 `/exit`으로 종료한다. Model egress와 file read는 서로 다른 승인이다. Node.js를 설치하지 +않으려면 아래 checksum installer를 사용한 뒤 `xgeny model setup`부터 같은 순서로 진행한다. API key를 +명령행 인자, shell history 또는 일반 설정 파일에 넣지 않는다. + ## 게시 target과 CI 검증 OS | CI runner OS | Architecture | Release asset | @@ -325,9 +344,54 @@ RC3는 workspace discovery, bounded atomic text write/patch와 명시적 shell-f [Workspace filesystem discovery](development/workspace-filesystem-discovery.md), write 경계는 [Workspace atomic write](development/workspace-atomic-write.md)를 따른다. +## 업데이트와 RC2 rollback + +npm 설치본은 새 exact version을 다시 설치해 업데이트한다. `next`는 시간이 지나면 다른 prerelease를 +가리킬 수 있으므로 파일럿과 장애 재현에는 사용하지 않는다. + +```bash +npm install --global --include=optional @xgen/cli@0.1.0-rc.3 +xgeny --version +``` + +Native 설치본은 위 installer를 같은 install directory에 exact tag로 다시 실행한다. Installer는 새 +binary의 checksum, version과 protocol을 먼저 확인하고 성공한 파일만 같은 directory rename으로 교체한다. +실행 중인 `xgeny`를 교체하지 말고 모든 session을 종료한 뒤 업데이트한다. + +RC3 npm package만 문제가 있고 같은 RC3 GitHub Release가 정상이라면 npm 설치본을 제거하고 exact RC3 +native installer로 전환할 수 있다. 두 채널은 같은 release binary를 담으므로 이는 제품 version +rollback이 아니라 설치 채널 전환이다. + +제품 version을 RC2로 되돌려야 하면 기존 RC3 binary와 state를 지우거나 덮어쓰지 말고 RC2를 별도 +user-owned directory에 설치한다. RC3가 만든 Run을 RC2로 열거나 resume하는 것은 지원하지 않는다. +RC2에서 시작해 아직 model egress가 필요한 Run은 원래 RC2 binary로 마치고, 새 작업은 RC3에서 새 Run으로 +시작한다. 완료된 RC2 Run은 RC3에서 offline replay할 수 있다. + +```bash +rollback_dir="$HOME/.local/xgeny-rc2/bin" +installer=$(mktemp "${TMPDIR:-/tmp}/xgeny-installer.XXXXXX") +curl -q --proto '=https' --proto-redir '=https' --tlsv1.2 \ + --connect-timeout 15 --max-time 60 --max-filesize 1048576 -fsSLo "$installer" \ + https://github.com/PlateerLab/xgeny-cli/releases/download/v0.1.0-rc.2/xgeny-installer.sh +sh "$installer" --version v0.1.0-rc.2 --install-dir "$rollback_dir" +rm -f "$installer" +"$rollback_dir/xgeny" --version +``` + +Immutable GitHub Release나 npm version에 치명적 문제가 있으면 기존 tag나 package를 이동·교체·재사용하지 +않는다. 수정은 더 높은 새 version으로 게시하고, 영향을 받은 exact version과 우회 방법을 release note에 +남긴다. + ## 삭제 -Installer는 runtime state를 삭제하지 않는다. Binary만 제거하려면 설치한 exact regular file을 지운다. +npm 설치본은 launcher와 현재 platform package를 함께 제거한다. + +```bash +npm uninstall --global @xgen/cli +``` + +Native installer는 runtime state를 삭제하지 않는다. Binary만 제거하려면 설치한 exact regular file을 +지운다. ```bash rm "$HOME/.local/bin/xgeny" @@ -340,3 +404,34 @@ Remove-Item -LiteralPath "$env:LOCALAPPDATA\XGENy\bin\xgeny.exe" Run state는 별도로 보존된다. Linux는 `$XDG_STATE_HOME/xgeny` 또는 `$HOME/.local/state/xgeny`, macOS는 `$HOME/Library/Application Support/XGENy`, Windows는 `%LOCALAPPDATA%\XGENy`를 사용한다. State 삭제는 Run 기록과 durable recovery 정보를 잃으므로 uninstall에 자동 포함하지 않는다. + +## 문제 해결과 지원 정보 + +| 증상 | 확인과 조치 | +| --- | --- | +| `xgeny: command not found` | npm global bin 또는 native install directory가 현재 `PATH`에 있는지 확인하고 새 terminal에서 다시 실행한다. | +| `unsupported_platform` 또는 platform package 없음 | 지원 OS/architecture와 Node.js version을 확인하고 `--omit=optional` 없이 exact package를 재설치한다. | +| Installer가 destination을 거부 | 관리자 공용 경로 대신 user-owned directory를 사용하고 symbolic link/reparse point나 broadly writable directory를 제거하지 말고 다른 빈 경로를 선택한다. | +| PowerShell에서 installer 차단 | Script를 먼저 검토한다. 현재 process 한정 execution-policy 예외는 조직 정책이 허용할 때만 사용한다. SmartScreen 경고는 RC3에 Authenticode가 없기 때문이다. | +| `credential_store_unavailable` | 평문 저장 fallback은 없다. Secret manager 출력을 `--token-stdin`이나 현재 process의 `XGENY_OPENAI_API_KEY`로 전달한다. | +| `model_not_advertised` 또는 compatibility 실패 | URL이 `/v1`로 끝나는지, exact served model ID와 strict JSON Schema Chat Completions 지원을 확인한다. Redirect나 자동 retry에 의존하지 않는다. | +| `configuration_mismatch` | 원래 workspace, file/directory scope, executable와 model profile binding으로 resume한다. 자동 대체하지 말고 필요하면 새 Run을 시작한다. | +| `model_call_unknown` 또는 `effect_outcome_unknown` | 불확정 작업을 자동 반복하지 않는다. `/status`와 `/resume`의 고정 진단을 확인하고 외부 상태를 별도로 검증한다. | + +지원 요청에는 `xgeny --version`, OS/architecture, 설치 채널, 종료 코드와 고정된 오류 코드만 우선 제공한다. +API key, endpoint 전체 URL, prompt, model 원문 응답, source, process stdout/stderr, state DB와 Run ID는 공개 +issue에 첨부하지 않는다. 일반 버그는 +[GitHub Issues](https://github.com/PlateerLab/xgeny-cli/issues), 보안 취약점은 공개 issue가 아닌 +[비공개 취약점 신고](https://github.com/PlateerLab/xgeny-cli/security/advisories/new)를 사용한다. 재현용 +project는 민감정보가 없는 최소 fixture로 새로 만든다. 세부 범위는 [보안 정책](../SECURITY.md)을 따른다. + +## 보안 경계 + +- XGENy는 model egress, read, write와 execute를 독립적으로 승인한다. 한 승인이 다른 권한을 포함하지 않는다. +- `process.execute`는 shell injection을 줄이지만 OS sandbox가 아니다. 허용한 compiler, package manager와 + child process는 현재 사용자 권한으로 project code를 실행한다. +- Run state에는 goal과 bounded tool output이 포함될 수 있으므로 state root 전체를 민감 데이터로 취급한다. +- SQLite는 binary에 내장된 local library다. SQLite server나 별도 database 설치가 필요하지 않다. +- 전송 여부가 불확정한 model/effect는 Unknown으로 보존하며 자동 replay하지 않는다. +- macOS/Windows RC3 binary에는 OS code signing/notarization이 없다. Checksum과 GitHub attestation은 + 전송 무결성과 build provenance를 확인하지만 OS publisher 서명을 대신하지 않는다. diff --git a/scripts/check-rc3-public-docs.sh b/scripts/check-rc3-public-docs.sh new file mode 100644 index 0000000..85de16d --- /dev/null +++ b/scripts/check-rc3-public-docs.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +set -eu + +script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P) +repo_root=$(CDPATH= cd -- "$script_dir/.." && pwd -P) + +python3 - "$repo_root" <<'PY' +from pathlib import Path +import sys + +root = Path(sys.argv[1]) +getting_started = (root / "docs/getting-started.md").read_text(encoding="utf-8") +pilot = (root / "docs/development/rc3-developer-preview-pilot.md").read_text( + encoding="utf-8" +) +readme = (root / "README.md").read_text(encoding="utf-8") +candidate = (root / "docs/development/rc3-release-candidate.md").read_text( + encoding="utf-8" +) +security = (root / "SECURITY.md").read_text(encoding="utf-8") + + +def require(document: str, fragments: tuple[str, ...], label: str) -> None: + for fragment in fragments: + if fragment not in document: + raise SystemExit(f"{label}: required public contract is missing: {fragment}") + + +require( + getting_started, + ( + "## 5분 빠른 시작", + "@xgen/cli@0.1.0-rc.3", + "xgeny model setup", + "xgeny model check --compatibility", + "## 업데이트와 RC2 rollback", + "v0.1.0-rc.2", + "npm uninstall --global @xgen/cli", + "## 문제 해결과 지원 정보", + "credential_store_unavailable", + "model_call_unknown", + "## 보안 경계", + "security/advisories/new", + ), + "getting-started", +) + +require( + pilot, + ( + "## 사전 조건과 중단 조건", + "## 사전 고정 사용자 matrix", + "rust-bare", + "node-resume", + "python-resume", + "## 공통 설치와 온보딩", + "## 복구·중단 안전성 확인", + "## 비민감 결과 ledger", + "## 합격 기준과 결과 처리", + "duplicate effect", + "process-tree leak", + "offline replay", + ), + "rc3-pilot", +) + +link = "docs/development/rc3-developer-preview-pilot.md" +require(readme, (link,), "README") +require(readme, ("SECURITY.md",), "README") +require(candidate, ("rc3-developer-preview-pilot.md",), "rc3-release-candidate") +require( + security, + ( + "## 지원 범위", + "## 비공개 신고", + "security/advisories/new", + "## 주요 보안 경계", + ), + "SECURITY", +) + +print("RC3 public documentation contract: PASS") +PY