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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ Utsuri は何もインストールせず、最初に利用可能な capability

レポートは source identity、evidence hash、review gap を保持し、別の reviewer が確認範囲を監査できるようにします。

- **自動のレビュー優先度** は、リスク・未検証事項・意図不明の理由を、検出事項や人の判断と分けて示します。レビュー済みを非表示にしても根拠は残ります。
- **範囲コメント** は、同じファイル・before/after の同じ側の行番号をクリックし、Shiftクリックで終点を指定します。統合表示・左右表示に対応し、再読み込み、レビューexport/import、Feedback Batchでも範囲を保持します。
- **Feedback Batch** は、データを変更せず折りたたみ・再展開できます。保存済みプレビューはready/consumed/answeredへ追従し、対応する回答へ移動でき、処理開始後は引き継ぎ操作を表示しません。新着回答は未読で、本文が画面に700ミリ秒表示されると既読になります。手動で未読へ戻した回答は、画面外へ移動して再閲覧するか、画面移動後に再び開くまで未読を保持します。
- **登録した検証結果** は、単体テスト・型チェック・Lint・ビルド・アプリE2E・外部サービスを区別します。annotationsにSHA、argv、終了コード、成功数、警告、環境、ハッシュ付きテキストログを登録できます。`verification/` のログをimmutableなreport資産に組み込み、作者申告とログ添付を区別します。ローカル・モックの成功で画面カバレッジを`PASS`へ変更しません。

<a id="security-privacy"></a><!-- section:security-privacy -->

## セキュリティとプライバシー
Expand All @@ -129,6 +134,7 @@ Utsuri は何もインストールせず、最初に利用可能な capability
- 生成済み `report/` は immutable です。変更可能な review / feedback record は run の `review/` directory に保存します。
- Marketplace MCP は任意の path、working directory、command、provider、model、destination、raw session input を公開しません。
- MCP tool が扱えるのは canonical な現在の project と同じ Origin Session に登録された schema-valid report だけです。別 project、別 host、別 session、stale または swapped registration は fail closed します。
- 対話 viewer は認証済み capability を sessionStorage に最大8時間保存し、再読み込み時に復元します。origin/port・viewer path・report ID ごとに分離します。同一 origin の JavaScript が読め、タブ複製時はコピーされる場合があります。期限切れや認証拒否時はそのタブの保存を消去し、現在の対話リンクを開き直す必要があります。8時間はクライアント保存期限であり、サーバー側 TTL ではありません。サーバー再起動で capability は変わります。localStorage・レビュー export・log には含めません。
- Raw host session value は equality check と opaque hash にだけ使用し、persist、log、diagnostic、tool return には含めません。
- Marketplace broker が受け付ける host contract は `CODEX_THREAD_ID`、または `CLAUDE_CODE_SESSION_ID` + `CLAUDE_PROJECT_DIR` だけです。Fixed-run の `finalize`、`feedback`、`review-mcp` は `UTSURI_CODEX_SESSION_ID` と `CLAUDE_SESSION_ID` の互換性も維持しますが、legacy/new の値が競合する場合は拒否します。Claude Plugin の finalize は child directory から起動しても canonical な host project root に binding します。
- Release artifact には production dependency graph の決定的な SPDX と license inventory を含めます。その identity は lockfile の正確な integrity value と install 済み package の byte から算出し、無関係な development-only lock 変更では published inventory を変更しません。
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ In a human conversation, the Agent authors the evidence-backed interpretation in

The report preserves source identity, evidence hashes, and review gaps so another reviewer can audit what was and was not checked.

- **Automatic review priority** explains risk, gaps and unknown intent separately from findings and human judgment. Reviewed changes can be hidden without removing their evidence.
- **Range comments** use line-number selection followed by Shift-click on the same file and before/after side, in unified or side-by-side diffs. Ranges survive reload, review export/import and Feedback Batches.
- **Feedback Batch** can be collapsed without changing review data. Saved previews follow ready/consumed/answered state, link to the corresponding answer, and stop offering a handoff after consumption. New answers start unread; a visible answer becomes read after 700 ms. Manual unread lasts until the answer leaves the viewport and is viewed again, or is reopened after navigation.
- **Registered verification results** distinguish unit tests, typecheck, lint, build, application E2E and external services. Annotations can include SHA, argv, exit code, passed count, warnings, environment and hashed text logs. Logs under `verification/` become immutable report assets; author reports and log attachments remain distinguishable. Local or mock success never promotes visual coverage to `PASS`.

<a id="security-privacy"></a><!-- section:security-privacy -->

## Security and privacy
Expand All @@ -129,6 +134,7 @@ The report preserves source identity, evidence hashes, and review gaps so anothe
- Generated `report/` files are immutable. Mutable review and feedback records live under the run's `review/` directory.
- The Marketplace MCP exposes no arbitrary path, working directory, command, provider, model, destination, or raw session input.
- MCP tools can use only schema-valid reports registered for the canonical current project and the same Origin Session. Cross-project, cross-host, cross-session, stale, or swapped registrations fail closed.
- Interactive viewers resume reloads using an authenticated, tab-scoped sessionStorage capability cache (up to eight hours), scoped to origin/port, viewer path and report ID. Same-origin JavaScript can read it and duplicated tabs may copy it. Expired or rejected caches are cleared; reopen the current server link. This client cache age does not set a server TTL: restart rotates the capability. Capabilities never enter localStorage, review exports or logs.
- Raw host session values are used only for equality checking and opaque hashing. They are not persisted, logged, diagnosed, or returned by tools.
- The Marketplace broker accepts only `CODEX_THREAD_ID` or the `CLAUDE_CODE_SESSION_ID` + `CLAUDE_PROJECT_DIR` host contract. Fixed-run `finalize`, `feedback`, and `review-mcp` also retain `UTSURI_CODEX_SESSION_ID` and `CLAUDE_SESSION_ID` compatibility; conflicting legacy/new values are rejected. Claude Plugin finalization always binds to the canonical host project root, including when launched from a child directory.
- Release artifacts include deterministic SPDX and license inventories for the production dependency graph. Its identity uses exact lockfile integrity values and installed package bytes; unrelated development-only lock changes do not alter the published inventory.
Expand Down
6 changes: 6 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ Utsuri 首先检查可用 capability,不会安装任何内容。未请求浏

报告保留 source identity、evidence hash 和 review gap,让其他审查者能够核查哪些内容已检查、哪些尚未检查。

- **自动审查优先级** 将风险、未验证事项和未知意图区别于发现及人工判断。隐藏已审查的更改不会删除证据。
- **范围评论** 在同一文件的before/after同一侧点击行号,再Shift点击终点;支持统一与左右差异视图。范围在重新加载、review export/import及Feedback Batch中保留。
- **Feedback Batch** 可折叠和展开而不修改数据。已保存的预览同步ready/consumed/answered,可跳转到回答,处理开始后不再提供交接操作。新回答为未读,正文进入视口700毫秒后变为已读。手动恢复未读后,离开视口并再次查看或导航后重新打开才会自动变为已读。
- **登记的验证结果** 区分单元测试、类型检查、Lint、构建、应用E2E和外部服务。annotations可登记SHA、argv、退出码、成功数、警告、环境及带哈希的文本日志。`verification/`日志成为immutable report资产,作者报告与日志附件保持区别。本地或mock成功不会将画面覆盖率提升为`PASS`。

<a id="security-privacy"></a><!-- section:security-privacy -->

## 安全与隐私
Expand All @@ -129,6 +134,7 @@ Utsuri 首先检查可用 capability,不会安装任何内容。未请求浏
- 生成的 `report/` 是 immutable。可变的 review / feedback record 保存在 run 的 `review/` directory。
- Marketplace MCP 不暴露任意 path、working directory、command、provider、model、destination 或 raw session input。
- MCP tool 只能处理为 canonical 当前 project 和同一 Origin Session 注册的 schema-valid report。跨 project、跨 host、跨 session、stale 或 swapped registration 都会 fail closed。
- Interactive viewer 使用认证后的 sessionStorage capability cache 恢复刷新,最多八小时,并按 origin/port、viewer path 和 report ID 隔离。同源 JavaScript 可读取,复制 tab 可能复制 cache。过期或认证失败时清除当前 tab cache,需要重新打开当前 server link。八小时仅是客户端缓存期限,不是 server TTL;server 重启会更换 capability。不会写入 localStorage、review export 或 log。
- Raw host session value 只用于 equality check 和 opaque hash,不会被 persist、log、diagnose 或通过 tool 返回。
- Marketplace broker 只接受 `CODEX_THREAD_ID`,或 `CLAUDE_CODE_SESSION_ID` + `CLAUDE_PROJECT_DIR` host contract。Fixed-run 的 `finalize`、`feedback` 与 `review-mcp` 继续兼容 `UTSURI_CODEX_SESSION_ID` 和 `CLAUDE_SESSION_ID`,但 legacy/new 值冲突时会拒绝。即使从 child directory 启动,Claude Plugin finalize 也始终绑定 canonical host project root。
- Release artifact 包含 production dependency graph 的确定性 SPDX 与 license inventory。其 identity 来自 lockfile 的精确 integrity value 和已安装 package 字节;无关的 development-only lock 变更不会改变发布的 inventory。
Expand Down
17 changes: 17 additions & 0 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,7 @@ With `--interactive`:

- Generate a high-entropy capability token at every start.
- Pass the token to the browser in the URL fragment and remove it from the address bar after JavaScript reads it.
- Cache an authenticated capability in sessionStorage for at most eight hours, keyed by exact origin (including port), viewer path, and report ID. Reload preserves the original expiry; expired/malformed caches and HTTP 401/403 clear the tab copy and require reopening the current interactive link. This is a client cache age, not a server TTL: the server capability remains valid until server close/restart, and every startup rotates it. Same-origin JavaScript can read the cache; duplicated tabs may inherit a copy, with independent expiry/clearing. Do not put capabilities in localStorage, review exports, diagnostics, or logs.
- Enable only the fixed-report same-origin loopback API.
- Fix report ID, Origin Session binding, and review-state directory at server startup.
- Do not accept arbitrary session IDs, commands, or paths from browser APIs.
Expand Down Expand Up @@ -4836,3 +4837,19 @@ The synchronized public CLI and Git Plugin version `0.3.5` satisfies this defini
| design-v1.6-publication-and-safe-chain | 1.6 | 2026-08-07 | Fixed publisher, npm maintainer, trusted-publishing, and SPDX metadata; replaced the local absolute-path Safe-chain requirement with exact-version discovery at the standard user installation; pinned official platform SHA-256 digests for verification before first execution. |
| design-v1.5-english-canonical | 1.5 | 2026-08-06 | Established English as the living canonical design; retained the verified Japanese v1.4 source for review; fixed npm identifiers at `@utsu-ri/*`; selected `review-answer.schema.json` and `run/review/`; added the locked Nix, Bun, Safe-chain, Apple HIG, synchronized README, and documentation-review gates. |
| design-v1.4-product-name | 1.4 | 2026-08-06 | Established Utsuri as the product name and unified Plugin, Skill, CLI, configuration, artifact, and display identifiers. |

## Reviewer controls and registered verification results

The viewer labels its queue as automatic review priority (priority review, review suggested, routine review), exposes the risk/gap/unknown-intent reasons and independently shows human judgment. The hide-reviewed filter does not mutate risk, findings, gaps or viewed state.

Line-number buttons select the start of a continuous range; Shift-click selects the end in the same hunk and before/after side. A changed side/file starts a fresh selection. Selection is bounded to 1,001 lines and must reconstruct exactly from the immutable diff. Range anchors carry path, side, startLine, endLine and a content-derived fingerprint. Dynamic range refs use `HUNK:range:SIDE:START:END`; Node, browser, interactive mutation and bundle import reconstruct them from current report data. A changed range is stale on reanchor; an unavailable range is orphaned. Single-line and hunk comments remain available. Context Packs preserve the exact range in both the anchor and code reference.

Saved Feedback Batch previews follow authoritative batch/item state returned with review-state and mutation responses. Consumed/answered batches do not offer another pending handoff. Items navigate to their comment and answer. Collapse/expand changes only the viewer layout and always shows requested-item and unread-answer counts. Unpersisted draft input is not overwritten by state refresh; responses older than the current revision are ignored.

`unreadAnswerItemIds` is a subset of answered item IDs, including the empty subset; legacy all-unread 0.3.5 data remains valid. `answer-read.changed` mutates only Inbox read state through the existing revision-checked generation transaction. New answers are unread; identical retries do not create revisions or reset read state. The viewer serializes read changes and retries revision conflicts against refreshed state. Automatic read requires at least 48 pixels (or the full height of a shorter answer) of answer text visible in an active document for 700 ms. A manual unread pauses automatic read until the answer leaves the viewport and returns, or is reopened after navigation. Read state is independent of human judgment, viewed markers and resolution.

`annotations.verificationResults` is optional and contains at most 100 records. Every record includes `id`, `kind` (`unit-tests`, `typecheck`, `lint`, `build`, `app-e2e`, `external-service`), `environment`, `command` as argv, `subjectSha` (full SHA or null), `exitCode` (null means not run), `passedCount` (or null), `warnings`, `changeRefs` (empty means whole report) and `completedAt`. A completed command requires a completion timestamp. Record IDs are unique and change references must exist.

Optional `logRef` and `logSha256` occur together. Only normalized `verification/` text files with `.txt`, `.log` or `.ndjson` suffixes are accepted. The operator registers sanitized UTF-8 logs inside the run; Utsuri neither executes the recorded command nor installs dependencies. Logs use contained regular-file reads, the existing 16 MiB per-artifact bound, independent SHA-256 comparison, immutable publication, exact report inventory and strict digest revalidation. Active HTML/SVG, traversal, symlink and special files are rejected. Log bytes are copied unchanged, so operators must remove secrets before registration.

The published `report.verificationResults` adds derived `provenance` (`reported` or `log-attached`) and `shaMatch` (`match`, `mismatch`, `unknown`). SHA matching compares the record to the collected input's full head SHA; patch/worktree subjects without a fixed SHA remain unknown. A log attachment proves the registered bytes and matching subject identity; it does not independently attest execution. Summary and change panels display the same applicable records, environment, command, exit code, counts, warning, timestamp, SHA, log link and hash. Mocked/SQLite success is not translated into real D1/API/E2E success. Visual coverage explicitly counts visual usages/targets, and neither registered tests nor reported E2E changes comparison status or fills unmapped visual coverage.
2 changes: 1 addition & 1 deletion fixtures/code-only-review/expected/report/assets/app.css

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions fixtures/code-only-review/expected/report/assets/app.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions fixtures/code-only-review/expected/report/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
"toolVersion": "0.1.0",
"generatedAt": "1970-01-01T00:00:00.000Z",
"sourceSnapshotHash": "1fc0429fabe7310908065f76abc977c2070f4e01576a4ba00e18ad368cf23ce4",
"semanticHash": "a82a7674b5dc28090e53cf9580e4527c471795418c16a566789f41c46e5bec99",
"semanticHash": "f81524062cd1c980aa62a94fbfb2d91da0bda291c4642b3bec7a0d95c2f9051b",
"assetHashes": {
"assets/app.css": "26db3b18b936af3b1cf306bbc984db50d7144d1706712bcad400e5e3af3d485a",
"assets/app.js": "3cdb480bc5330e46be21153aab6c67cc8b5d72df16aed0b04b43bcf76d6688e2",
"assets/app.css": "e3a13751daed2f092852837659997d863ba24dfb7fc8e1f23dc82ec8b9762e2a",
"assets/app.js": "45f3af65efeedfe618c42daffdeef64f442cd863d87465ebbca8e7340953b4ce",
"context-pack.schema.json": "5b407ebe4e0adebcf12b4c4233700c344276950c91a621003b1302a7cc0033dc",
"diagnostics/summary.json": "7daf08a35f68041e75083352a89dca517fe209d9ba1997a5075b049a79139d17",
"index.html": "58872c19bdd494a46b599a6928489fb485ac960f02f22a7899c186f15cf746aa",
"report.json": "a1e0dc8dafdbd1e7aa7c1323f0e95e2baeded9fa15aa2f76c73c88f124065f4c",
"review-answer.schema.json": "5b94d3f42d5e1a204a343263f68080c050a69143a90a47ef12951fff1e4cb9e7",
"review-bundle.schema.json": "c5b6adecab6039a7bb61ecfdcd62c4e4c7ad287faa45ffc9e2e52743540b3a49",
"review-event.schema.json": "8a6d7ea5e9a13ea7a7ee37e0602c5c84df2b533077bdb7252bd8b15e604fff96",
"review-event.schema.json": "ee4af771d1091a5c13296d62b87d98cf9414d889426bfbacb0ac6119223393ce",
"review-state.schema.json": "a8dbb075460a0eb41fab81b34fe2290ac4832b2453bf85d14d934fc3d916b181",
"review-thread.schema.json": "13199007c2291bc595c20149bbb7c675097574b5327fbbef80d8008c7b063bba"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"feedback-batch.stored",
"feedback-batch.claimed",
"feedback-batch.released",
"feedback-batch.answered"
"feedback-batch.answered",
"answer-read.changed"
]
},
"createdAt": {
Expand Down Expand Up @@ -135,6 +136,9 @@
"export-only"
]
},
"answerUnread": {
"type": "boolean"
},
"originSessionMatched": {
"type": "boolean"
}
Expand Down Expand Up @@ -304,6 +308,22 @@
"itemIds"
]
}
},
{
"if": {
"properties": {
"type": {
"const": "answer-read.changed"
}
}
},
"then": {
"required": [
"batchId",
"itemIds",
"answerUnread"
]
}
}
],
"$defs": {
Expand Down
2 changes: 1 addition & 1 deletion fixtures/empty-report/run/report/assets/app.css

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions fixtures/empty-report/run/report/assets/app.js

Large diffs are not rendered by default.

Loading
Loading