From 8b050312f1f9e0a04d5c75747712e98a8a21d1eb Mon Sep 17 00:00:00 2001
From: BM Cho
Date: Mon, 20 Jul 2026 13:23:00 +0800
Subject: [PATCH 1/2] release: prepare Evidrift v0.3.3
---
.github/workflows/ci.yml | 5 +--
CHANGELOG.md | 18 +++++++++++
README.md | 57 +++++++++++++++++++++++++++++++---
README.zh-TW.md | 57 +++++++++++++++++++++++++++++++---
docs/UAT.md | 10 ++++++
docs/ci.md | 66 ++++++++++++++++++++++++++++++++++++++++
docs/index.html | 8 ++---
docs/llms.txt | 1 +
docs/zh-TW/faq.html | 4 +--
docs/zh-TW/index.html | 8 ++---
package-lock.json | 4 +--
package.json | 2 +-
server.json | 4 +--
src/cli.ts | 2 +-
src/types.ts | 2 +-
tests/onboarding.test.ts | 2 +-
tests/package.test.ts | 16 ++++++++++
tests/seo.test.ts | 24 +++++++++++++++
18 files changed, 260 insertions(+), 30 deletions(-)
create mode 100644 docs/ci.md
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 83fdce8..37a4da7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,12 +10,13 @@ permissions:
jobs:
verify:
- name: Node.js ${{ matrix.node }}
- runs-on: ubuntu-latest
+ name: ${{ matrix.os }} / Node.js ${{ matrix.node }}
+ runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
+ os: [ubuntu-latest, windows-latest]
node: [22, 24]
steps:
- name: Check out repository
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1d2ee4f..200b1ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,24 @@ All notable changes are documented here. The project follows [Semantic Versionin
No changes yet.
+## [0.3.3] - 2026-07-20
+
+### Added
+
+- An inline architecture flow that connects coding-agent assumptions, content-addressed Receipts, Git review, and deterministic CI outcomes.
+- A copy-pasteable GitHub Actions adoption guide with read-only permissions, locked npm installation, and commit-pinned Actions.
+- Regression tests that keep the public support scope, architecture, CI instructions, and cross-platform CI matrix aligned.
+
+### Changed
+
+- Project CI now runs the complete release gate on Linux and Windows with Node.js 22 and 24.
+- English and Traditional Chinese first-visit documentation now state the supported and deliberately unsupported surfaces explicitly.
+- The demo promise now describes a reproducible one-command path instead of making a network-dependent timing claim.
+
+### Not included
+
+- No Receipt schema, verification policy, network access, cloud service, or runtime-correctness claim changed in this release.
+
## [0.3.2] - 2026-07-17
### Added
diff --git a/README.md b/README.md
index fa73895..26a0096 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,11 @@ It deterministically catches selected TypeScript overload and parameter drift, r

-[](#quick-start--try-it-in-10-seconds)
+[](#quick-start--see-drift-in-one-command)
The animation is rendered from a [captured CLI transcript](https://github.com/bm1016bm-svg/evidrift/blob/main/docs/assets/evidrift-demo-transcript.txt). The PASS, changed signatures, affected file, and deterministic FAIL come from an actual local `evidrift demo` run; only the scene headings are editorial.
-## Quick Start — Try It in 10 Seconds
+## Quick Start — See Drift in One Command
Requires Node.js 22 or newer. Nothing to install globally:
@@ -32,6 +32,15 @@ The command creates a disposable local fixture, records the optional `options` p
**If that is a failure you want caught before merge, [star Evidrift on GitHub](https://github.com/bm1016bm-svg/evidrift).**
+## Supported Today
+
+| Surface | Deterministic evidence | Status |
+| -------------------------------- | ----------------------------------------------------------------------- | ------------------ |
+| Installed TypeScript dependency | Selected call signature, parameter, package version, and declaration | Supported |
+| Repository OpenAPI / JSON Schema | Canonical value selected through an RFC 6901 JSON Pointer | Supported for JSON |
+| CLI and local STDIO MCP | The same record and revalidation core | Supported |
+| YAML, URLs, remote `$ref` | None; Evidrift refuses these inputs instead of making an unsafe promise | Not supported |
+
## Installation — Add It to a Repository
Initialize the current repository without a global install, account, API key, or cloud backend:
@@ -84,6 +93,23 @@ JSON Pointer follows RFC 6901, including `~1` for `/` and `~0` for `~`. Evidrift
Coding agents call the same core through `evidrift_record` and `evidrift_record_json_pointer`. Minimal [Codex, Claude Code, and Cursor setup](docs/mcp.md) is included.
+## How It Works
+
+```mermaid
+flowchart LR
+ Author["Coding agent or developer"] --> Record["Record one assumption"]
+ Record --> Adapter["TypeScript or JSON adapter"]
+ Adapter --> Receipt["Content-addressed Receipt"]
+ Receipt --> Review["Git review"]
+ Review --> Check["evidrift check in CI"]
+ Check --> Result{"Contract still matches?"}
+ Result -->|Yes| Pass["PASS"]
+ Result -->|Source unavailable| Warn["WARNING"]
+ Result -->|No or tampered| Fail["FAIL"]
+```
+
+The CLI and MCP server are thin entry points over the same core. The complete component map, check policy, resource bounds, and trust boundary are documented in [Architecture](docs/architecture.md).
+
## The Files
Evidrift writes one lock and one immutable JSON file per Receipt:
@@ -106,6 +132,27 @@ There is no `.evidrift/receipts.json`. `evidence.lock` contains only content-add
Each Receipt stores the claim and affected code plus one deterministic contract: an installed TypeScript symbol signature, or a repository JSON path, pointer, canonical value, and hashes. See the [Receipt schema](docs/receipt-schema.md).
+## Add It to CI
+
+Pin Evidrift as a development dependency and expose one stable package script:
+
+```json
+{
+ "scripts": {
+ "evidrift:check": "evidrift check"
+ }
+}
+```
+
+After `npm ci`, make that script a required CI step:
+
+```yaml
+- name: Revalidate Evidrift receipts
+ run: npm run evidrift:check
+```
+
+The complete [GitHub Actions setup](docs/ci.md) uses read-only permissions, locked npm dependencies, and commit-pinned Actions.
+
## CI Behavior
`evidrift check` does not trust saved `matched` or `verified` flags. It validates the Receipt, reloads the source, and recomputes the selected signature or JSON value.
@@ -127,7 +174,7 @@ Receipt ID: sha256:...
Action: Do not trust or hand-edit this Receipt. Restore it from version control, or intentionally create a new Receipt with `evidrift record`.
```
-The included GitHub Actions workflow runs the full gate on Node.js 22 and 24. Third-party Actions are pinned to full commit SHAs.
+The project workflow runs the full gate on Linux and Windows with Node.js 22 and 24. Third-party Actions are pinned to full commit SHAs.
In a human TTY, `check`, `diff`, `explain`, and `demo` use a spinner plus green `✅`, yellow `⚠`, and red `❌` status output. Redirected output, CI, `TERM=dumb`, and `NO_COLOR` stay ANSI-free and keep the stable plain-text format used by agents and tests.
@@ -145,7 +192,7 @@ Use all of them if they help. Evidrift covers one gap: the reason code was writt
### What is API drift?
-API drift is a change to a dependency or contract after code was written against it. Evidrift v0.3.2 checks two deterministic forms: the TypeScript call signature selected at an affected code location, and a canonical value selected from repository-local OpenAPI JSON or JSON Schema.
+API drift is a change to a dependency or contract after code was written against it. Evidrift v0.3.3 checks two deterministic forms: the TypeScript call signature selected at an affected code location, and a canonical value selected from repository-local OpenAPI JSON or JSON Schema.
### Is Evidrift a contract-testing tool?
@@ -157,7 +204,7 @@ Yes. They can call the local STDIO MCP server to create Receipts through the sha
### Does Evidrift fetch OpenAPI URLs or execute package code?
-No. The v0.3.2 adapters inspect installed TypeScript declarations and repository-local `.json` files. They do not fetch URLs, resolve remote `$ref`, import dependency JavaScript, or execute arbitrary commands.
+No. The v0.3.3 adapters inspect installed TypeScript declarations and repository-local `.json` files. They do not fetch URLs, resolve remote `$ref`, import dependency JavaScript, or execute arbitrary commands.
### Does Evidrift prove that AI-generated code is correct?
diff --git a/README.zh-TW.md b/README.zh-TW.md
index d31b267..df803c3 100644
--- a/README.zh-TW.md
+++ b/README.zh-TW.md
@@ -16,11 +16,11 @@ Evidrift 能確定性偵測指定的 TypeScript overload/parameter drift、透

-[](#快速開始--10-秒看到-drift)
+[](#快速開始--用一個指令看到-drift)
這段動畫由[實際擷取的 CLI transcript](https://github.com/bm1016bm-svg/evidrift/blob/main/docs/assets/evidrift-demo-transcript.txt)產生。`PASS`、改變前後的 signature、affected file 與 deterministic `FAIL` 都來自本機執行的 `evidrift demo`;只有場景標題是後製文字。
-## 快速開始 — 10 秒看到 drift
+## 快速開始 — 用一個指令看到 drift
需要 Node.js 22 或更新版本。不必全域安裝:
@@ -34,6 +34,15 @@ npx --yes evidrift@latest demo
完整推演請看:[TypeScript 編譯通過,但 dependency signature 已漂移](https://bm1016bm-svg.github.io/evidrift/zh-TW/cases/typescript-signature-drift.html)。
+## 目前支援範圍
+
+| Surface | Deterministic evidence | 狀態 |
+| -------------------------------- | ------------------------------------------------------------------ | --------- |
+| 已安裝的 TypeScript dependency | Selected call signature、parameter、package version 與 declaration | 支援 |
+| Repository OpenAPI / JSON Schema | 透過 RFC 6901 JSON Pointer 選取的 canonical value | 支援 JSON |
+| CLI 與 local STDIO MCP | 共用相同的 record 與 revalidation core | 支援 |
+| YAML、URL、remote `$ref` | 無;Evidrift 會拒絕輸入,不會做出不安全的保證 | 不支援 |
+
## 安裝 — 加入現有 Repository
不需要全域安裝、Evidrift 帳號、API key 或雲端後端:
@@ -86,6 +95,23 @@ JSON Pointer 遵循 RFC 6901,其中 `~1` 代表 `/`、`~0` 代表 `~`。Evidri
Coding Agent 透過 `evidrift_record` 與 `evidrift_record_json_pointer` 呼叫相同核心。Repository 包含 [Codex、Claude Code 與 Cursor 的最小 MCP 設定](docs/mcp.md)。
+## 運作方式
+
+```mermaid
+flowchart LR
+ Author["Coding Agent 或開發者"] --> Record["記錄一項 assumption"]
+ Record --> Adapter["TypeScript 或 JSON adapter"]
+ Adapter --> Receipt["Content-addressed Receipt"]
+ Receipt --> Review["Git review"]
+ Review --> Check["CI 執行 evidrift check"]
+ Check --> Result{"Contract 仍相同?"}
+ Result -->|是| Pass["PASS"]
+ Result -->|Source 無法使用| Warn["WARNING"]
+ Result -->|否或遭竄改| Fail["FAIL"]
+```
+
+CLI 與 MCP Server 都是相同 core 的入口。完整 component map、check policy、resource bound 與 trust boundary 請參考英文版 [Architecture](docs/architecture.md)。
+
## 產生的檔案
Evidrift 會寫入一份 lock,以及每張 Receipt 對應的一個 immutable JSON file:
@@ -108,6 +134,27 @@ Evidrift 會寫入一份 lock,以及每張 Receipt 對應的一個 immutable J
每張 Receipt 會保存 claim、affected code,以及一項 deterministic contract:已安裝 TypeScript symbol signature,或 repository JSON path、pointer、canonical value 與 hashes。請參考英文版 [Receipt schema](docs/receipt-schema.md)。
+## 加入 CI
+
+把 Evidrift 固定為 development dependency,並提供穩定的 package script:
+
+```json
+{
+ "scripts": {
+ "evidrift:check": "evidrift check"
+ }
+}
+```
+
+在 `npm ci` 後把它設為必要 CI step:
+
+```yaml
+- name: Revalidate Evidrift receipts
+ run: npm run evidrift:check
+```
+
+完整 [GitHub Actions 設定](docs/ci.md)使用 read-only permission、鎖定的 npm dependency 與固定到 commit 的 Actions。
+
## CI 行為
`evidrift check` 不信任儲存的 `matched` 或 `verified` flag。它會驗證 Receipt、重新載入來源,再計算 selected signature 或 JSON value。
@@ -129,7 +176,7 @@ Receipt ID: sha256:...
Action: Do not trust or hand-edit this Receipt. Restore it from version control, or intentionally create a new Receipt with `evidrift record`.
```
-內附的 GitHub Actions workflow 會在 Node.js 22 與 24 執行完整 gate。第三方 Actions 全部固定到完整 commit SHA。
+專案的 GitHub Actions workflow 會在 Linux 與 Windows 使用 Node.js 22、24 執行完整 gate。第三方 Actions 全部固定到完整 commit SHA。
在人類操作的 TTY 中,`check`、`diff`、`explain` 與 `demo` 會顯示 spinner 和綠色 `✅`、黃色 `⚠`、紅色 `❌` 狀態。Redirected output、CI、`TERM=dumb` 與 `NO_COLOR` 會維持無 ANSI 的穩定純文字格式,方便 Coding Agent 與測試解析。
@@ -147,7 +194,7 @@ Action: Do not trust or hand-edit this Receipt. Restore it from version control,
### 什麼是 API drift?
-API drift 是 dependency 或 contract 在消費端程式寫完後發生改變。Evidrift v0.3.2 檢查兩種 deterministic evidence:affected code location 實際選到的 TypeScript call signature,以及 repository-local OpenAPI JSON 或 JSON Schema 中選定的 canonical value。
+API drift 是 dependency 或 contract 在消費端程式寫完後發生改變。Evidrift v0.3.3 檢查兩種 deterministic evidence:affected code location 實際選到的 TypeScript call signature,以及 repository-local OpenAPI JSON 或 JSON Schema 中選定的 canonical value。
### Evidrift 是 contract-testing tool 嗎?
@@ -159,7 +206,7 @@ API drift 是 dependency 或 contract 在消費端程式寫完後發生改變。
### Evidrift 會抓 OpenAPI URL 或執行 package code 嗎?
-不會。v0.3.2 adapters 只檢查已安裝的 TypeScript declaration 與 repository-local `.json` file;不會抓 URL、解析 remote `$ref`、import dependency JavaScript 或執行 arbitrary command。
+不會。v0.3.3 adapters 只檢查已安裝的 TypeScript declaration 與 repository-local `.json` file;不會抓 URL、解析 remote `$ref`、import dependency JavaScript 或執行 arbitrary command。
### Evidrift 能證明 AI 產生的程式碼正確嗎?
diff --git a/docs/UAT.md b/docs/UAT.md
index 54a7906..accc27c 100644
--- a/docs/UAT.md
+++ b/docs/UAT.md
@@ -14,6 +14,16 @@ npm run uat
`npm run verify` runs formatting, lint, typecheck, all automated tests, the end-to-end smoke test, and a check of this repository's committed Receipt. `npm run uat` isolates the user-facing acceptance cases.
+Local v0.3.3 flagship-release checkpoint on 2026-07-20:
+
+- Platform: Windows, Node.js `v24.13.0`, npm `11.6.2`.
+- Automated result: `npm run verify` passed 62/62 tests with 0 failures and 0 skips, then passed the end-to-end smoke test and repository Receipt check. Formatting, lint, typecheck, and release metadata alignment at `v0.3.3` also passed.
+- Cross-platform gate: the CI matrix covers `ubuntu-latest` and `windows-latest` with Node.js 22 and 24. The local Windows run passed; GitHub Actions remains the authoritative Linux and clean-checkout result.
+- Packed-install result: a fresh isolated consumer installed `evidrift-0.3.3.tgz`; `--version` returned `0.3.3`, bare invocation exposed the one-command demo, `init` created `.evidrift/`, and `demo` reproduced deterministic PASS-to-FAIL drift.
+- Package-content result: the tarball contains 64 entries, including both READMEs and the CLI/MCP entrypoints, while excluding `src`, `tests`, and `examples`.
+- Pack result: 58,351 packed bytes, 256,275 unpacked bytes, SHA-256 `42b60686bdcb551208653f2b9b8d52ea875275ccd8838b5a5256a6022946dc61`. The counts and sizes come from `npm pack --json`; the hash comes from PowerShell `Get-FileHash` against that exact tarball.
+- Dependency advisory result: the isolated consumer's official-registry install audited 113 packages and reported 0 known vulnerabilities. This is registry output, not proof that the code has no vulnerability.
+
Local v0.3.2 bilingual-release checkpoint on 2026-07-17:
- Platform: Windows, Node.js `v24.13.0`, npm `11.6.2`.
diff --git a/docs/ci.md b/docs/ci.md
new file mode 100644
index 0000000..f8614f2
--- /dev/null
+++ b/docs/ci.md
@@ -0,0 +1,66 @@
+# GitHub Actions
+
+Evidrift should run after the repository's locked dependencies are installed. Store `.evidrift/evidence.lock` and `.evidrift/receipts/` in Git so reviewers can see when an assumption is added or replaced.
+
+## Package script
+
+Install Evidrift as a development dependency and expose a stable command for local development and CI:
+
+```bash
+npm install --save-dev evidrift
+npx evidrift init
+```
+
+```json
+{
+ "scripts": {
+ "evidrift:check": "evidrift check"
+ }
+}
+```
+
+Commit the resulting package lock, package manifest, and `.evidrift/` files.
+
+## Complete workflow
+
+```yaml
+name: Evidrift
+
+on:
+ pull_request:
+ push:
+ branches: [main]
+
+permissions:
+ contents: read
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Set up Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version: 22
+ package-manager-cache: false
+
+ - name: Install locked dependencies
+ run: npm ci --ignore-scripts
+
+ - name: Revalidate Evidrift receipts
+ run: npm run evidrift:check
+```
+
+The workflow grants read-only repository access. It installs from the committed npm lockfile, does not execute dependency lifecycle scripts, and pins third-party Actions to complete commit SHAs.
+
+## Result policy
+
+- Exit `0`: every deterministic contract matches, or a source is visibly unavailable or changed without a selected-contract mismatch.
+- Exit `1`: a selected TypeScript signature or JSON value changed or disappeared.
+- Exit `2`: the lock or a Receipt is malformed, missing, forged, or hash-invalid.
+
+Warnings are intentionally non-blocking. Review them in logs; Evidrift only blocks when it has a deterministic mismatch or integrity failure.
diff --git a/docs/index.html b/docs/index.html
index 9c0c535..2c70d50 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -50,7 +50,7 @@
"alternateName": "Evidrift evidence lockfile",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Windows, macOS, Linux",
- "softwareVersion": "0.3.2",
+ "softwareVersion": "0.3.3",
"description": "A local-first CLI and MCP server that detects TypeScript API and OpenAPI contract drift in AI-generated code by revalidating deterministic evidence in CI.",
"url": "https://bm1016bm-svg.github.io/evidrift/",
"codeRepository": "https://github.com/bm1016bm-svg/evidrift",
@@ -386,7 +386,7 @@