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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Changelog

### v1.18.3 — decompress correctness hardening + host permission respect + one-click release workflow

**Bundles six runtime fixes, one CI feature, and doc updates since v1.18.2** (issues #405, #444, #446, #447, #457, #461, #465; CI #443/#474; docs #441/#442/#450/#471). No config or state-format changes.

**1. Decompress correctness (#446, #447):**
- **Source availability verification** (#446): before committing a decompression, ACP now verifies that every message whose visibility would change is still present in the fetched host history. If originals were removed externally (native compaction, manual deletion), the call aborts with an explicit error and **no state is mutated** — previously it reported phantom restorations, decremented stats by phantom tokens, and irreversibly discarded summary coverage. The check is fail-closed and conservative: over-requiring an ID can only cause a safe-direction abort, never a false "restored" claim.
- **`decompress.toFile` exports original text** (#447): the exporter previously read non-existent `content`/`text` fields off SDK messages and fell back to `JSON.stringify` garbage. It now serializes message parts (text verbatim, tool outputs via `extractToolContent`); when originals are gone it writes the block summary with an explicit note instead of empty files.

**2. Quality-gate rejection conciseness (#444):** the model-facing rejection error no longer dumps internal metrics (gate layer, rougeF1, top20Recall, threshold details) — it now carries the core reason, one Original/Summary/Retention stats line, and retry guidance. Full diagnostics go to the ACP log via `logger.warn`. The `acknowledgeRisk` bypass hint is retained.

**3. Host permission respect (#457, #465):** ACP's config write no longer overrides user permission decisions on `acp_status`:
- Exact keys (#457): an explicit `acp_status: "deny"`/`"ask"` used to be silently rewritten to `"allow"` (inverting the decision); it now survives.
- Wildcards (#465): user rules like `"*": "deny"` or `"acp*": "deny"` used to be erased because the appended default won last-match resolution; they now survive.
- Behavior preserved: an explicit user `compress` rule still defers fully (the map is returned unchanged), and unrelated host rules are untouched.

**4. truncate-tools overhead-error set bound (#461):** the once-per-session "window too small" ERROR dedup set was unbounded (one key per session forever on long-lived servers). It is now capped at 1024 sessions with oldest-first eviction; the worst cost of evicting a still-active session is one duplicate ERROR line.

**5. Yield to billion-context native mode (#405):** ACP now recognizes both billion-context ownership markers — `BILLION_CONTEXT_PROXY` (launcher) and `BILLION_CONTEXT_NATIVE` (native plugin) — and re-samples env at action time (hook calls, config runs, every tool call via `resolveToolContext`) instead of trusting the setup-time snapshot. This closes the race where native mode's marker landed after ACP setup, letting both plugins run simultaneously. After handoff, all five ACP tools throw a clear error naming the owning mode.

**6. CI: one-click release workflow (#443, #474):** new `Release (one-click)` workflow (`workflow_dispatch`) — resolves the version (blank = auto next-patch over npm latest), drift-guards master vs npm, bumps `package.json` + `package-lock.json`, verifies the bump diff, runs the full pre-flight gate, then pushes to master or falls back to a release branch + PR. Follow-up fix heals package-lock.json version drift instead of failing.

**Docs:** OpenCode 2.x users pointed to [billion-context](https://github.com/ranxianglei/billion-context) (README callout + AGENTS.md migration/triage rule codified, #442); new QQ group 1108730198 added with original 1056132097 marked full; AGENTS.md version table corrected (1.10.0 → 1.18.2).

**Install**: `opencode plugin opencode-acp@latest --global`

### v1.18.2 — strip leaked bare ACP refs from assistant text tail + fix silent no-op in Windows path protection

**PR #432 + PR #403.** Two bug fixes bundled — no config or state-format changes.
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# 更新日志

### v1.18.3 — decompress 正确性加固 + 宿主权限尊重 + 一键发布 workflow

**自 v1.18.2 以来捆绑六个运行时修复、一个 CI 特性与文档更新**(issue #405、#444、#446、#447、#457、#461、#465;CI #443/#474;文档 #441/#442/#450/#471)。无配置或状态格式变更。

**1. Decompress 正确性(#446、#447):**
- **源消息可用性校验**(#446):提交解压前,ACP 现在校验所有可见性将发生变化的消息仍存在于拉取的宿主历史中。若原始消息已被外部移除(原生压缩、手动删除),调用以显式错误中止且**不改动任何状态** —— 此前会报告幻影恢复、按幻影 token 扣减统计,并不可逆地丢弃摘要覆盖。该检查 fail-closed 且保守:多要求某个 ID 只可能导致安全方向的中止,绝不会产生虚假的"已恢复"声明。
- **`decompress.toFile` 导出原始文本**(#447):旧导出器读取 SDK 消息上不存在的 `content`/`text` 字段并退化为 `JSON.stringify` 垃圾。现改为序列化消息 parts(文本原样、工具输出经 `extractToolContent`);原始消息缺失时写入带明确标注的块摘要而非空文件。

**2. 质量门拒绝信息精简(#444):** 面向模型的拒绝错误不再倾倒内部指标(gate 层、rougeF1、top20Recall、阈值细节)—— 现在只含核心原因、一行 Original/Summary/Retention 统计与重试指引。完整诊断经 `logger.warn` 写入 ACP 日志。`acknowledgeRisk` 旁路提示保留。

**3. 宿主权限尊重(#457、#465):** ACP 的配置写入不再覆盖用户对 `acp_status` 的权限决定:
- 精确键(#457):显式的 `acp_status: "deny"`/`"ask"` 过去会被静默改写为 `"allow"`(反转决定);现在得以保留。
- 通配符(#465):用户规则如 `"*": "deny"` 或 `"acp*": "deny"` 过去会被追加的默认值以 last-match 胜出而抹掉;现在得以保留。
- 保持的行为:用户显式 `compress` 规则仍然完全让位(map 原样返回),无关宿主规则不受影响。

**4. truncate-tools 开销错误集合设界(#461):** 每会话一次的 "window too small" ERROR 去重集合原先无界(长驻服务器每会话永久累积一个 key)。现上限 1024 个会话、最旧优先驱逐;驱逐仍活跃会话的最坏代价是多一条重复 ERROR 行。

**5. 向 billion-context 原生模式让位(#405):** ACP 现在识别 billion-context 的两个所有权标记 —— `BILLION_CONTEXT_PROXY`(launcher)与 `BILLION_CONTEXT_NATIVE`(native 插件)—— 并在动作时(hook 调用、config 运行、每次工具调用经 `resolveToolContext`)重新采样 env,而不是信任 setup 时的快照。这消除了原生模式标记晚于 ACP setup 落盘、导致两个插件同时运行的竞态。交接后,全部五个 ACP 工具抛出指明接管模式的清晰错误。

**6. CI:一键发布 workflow(#443、#474):** 新增 `Release (one-click)` workflow(`workflow_dispatch`)—— 解析版本(留空 = 自动取 npm latest 的下一 patch)、master 与 npm 漂移守卫、bump `package.json` + `package-lock.json`、校验 bump diff、跑完整 pre-flight 门,然后推 master 或回退到 release 分支 + PR。后续修复使 package-lock.json 版本漂移被修复而非失败。

**文档:** OpenCode 2.x 用户引导至 [billion-context](https://github.com/ranxianglei/billion-context)(README callout + AGENTS.md 迁移/triage 规则固化,#442);新增 QQ 群 1108730198,原群 1056132097 标记为满员;AGENTS.md 版本表修正(1.10.0 → 1.18.2)。

**安装**:`opencode plugin opencode-acp@latest --global`

### v1.18.2 — 剥离助手文本尾部泄漏的裸 ACP 引用 + 修复 Windows 路径保护静默失效

**PR #432 + PR #403。** 捆绑两个 bug 修复 —— 无配置或状态格式变更。
Expand Down
45 changes: 45 additions & 0 deletions devlog/2026-09-30_release-v1.18.3/REQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# REQ - Release v1.18.3 (patch)

- Task ID: `2026-09-30_release-v1.18.3`
- Home Repo: `opencode-acp`
- Created: 2026-09-30
- Status: InProgress
- Priority: P1
- Owner: ranxianglei
- References: https://github.com/ranxianglei/opencode-acp/pull/475 (one-click release fallback PR)

## Scope

Bump `package.json` 1.18.2 → 1.18.3 and ship everything merged to master since v1.18.2:

| PR / commit | Content | Issue |
|-------------|---------|-------|
| #406 | Yield to billion-context native mode via action-time env re-check (`index.ts`, `lib/bili-proxy.ts`, `lib/compress/types.ts`); includes dual-agent review follow-ups | fixes #405 |
| #447 | Keep quality-gate rejection concise — strip internal details from model-facing error, log full diagnostics (`lib/compress/quality-gate/rejection.ts`, `lib/compress/range.ts`) | fixes #444 |
| #449 | Verify source-message availability before committing decompression (`lib/compress/decompress-logic.ts`, `lib/compress/decompress.ts`) | fixes #446 |
| #448 | `decompress.toFile` exports serialized original messages, not JSON garbage (`lib/compress/decompress.ts`) | — |
| #466 | Never override explicit/wildcard user decisions on `acp_status` in host config write (`lib/host-permissions.ts`, `index.ts`) | fixes #457, #465 |
| #473 | Bound `overheadErrorLogged` Set in truncate-tools (cap 1024, oldest-first eviction) | fixes #461 |
| #443 | One-click release workflow (`release-manual.yml`, `workflow_dispatch`) + devlog | — |
| #474 | One-click release heals package-lock.json version drift instead of failing | — |
| #441 | README: point OpenCode 2.x users to billion-context | — |
| #471 | AGENTS.md: codify OpenCode V2 → billion-context migration + triage rule; stale version table fix; stray-space nit | refs #442 |
| #450/#451 | README(±zh): new QQ group 1108730198 added, original 1056132097 marked full; Community section moved to top | — |

All runtime changes are bug fixes → semver PATCH: **v1.18.3**.

## Changes in this branch

1. `package.json`: `version` 1.18.2 → 1.18.3 (done by the one-click workflow)
2. `package-lock.json`: synced (done by the one-click workflow)
3. `CHANGELOG.md`: new `### v1.18.3` entry at top (added in review fix-up — see WORKLOG step 2)
4. `CHANGELOG.zh-CN.md`: new `### v1.18.3` entry at top (same reason)
5. This devlog folder (`REQ.md` + `WORKLOG.md`) (same reason)

No other code changes. Merging this PR triggers `release.yml`: auto-tag `v1.18.3` → build → test → npm publish to `latest` → GitHub Release.

## Verification plan

- `./scripts/ci/check-pr.sh 2026-09-30_release-v1.18.3 origin/master` — must pass all checks (it failed 3 before the fix-up commit; see WORKLOG)
- Version-range regression audit v1.18.2..HEAD performed during PR #475 review (see WORKLOG "Audit")
- After human merge: verify `npm view opencode-acp dist-tags.latest` = 1.18.3 and the GitHub Release exists
36 changes: 36 additions & 0 deletions devlog/2026-09-30_release-v1.18.3/WORKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# WORKLOG - Release v1.18.3

## Steps

1. One-click release workflow (`release-manual.yml`, triggered 2026-09-30) resolved version 1.18.3, passed drift guard + pre-flight gate, and committed the bump. Direct push to master was blocked by branch protection → fallback branch `2026-09-30_release-v1.18.3` pushed, PR #475 opened automatically.
2. Review of PR #475 ran `./scripts/ci/check-pr.sh 2026-09-30_release-v1.18.3 origin/master` locally: **3 failures** — missing `devlog/2026-09-30_release-v1.18.3/{REQ,WORKLOG}.md` and no CHANGELOG update. Root cause: the one-click workflow only bumps `package.json` + `package-lock.json` (its "Verify bump diff" step enforces exactly those two files) and generates neither devlog nor changelog, although its step summary claims "with the generated changelog". This is the first release to reach the fallback path, so the gap surfaced now. The workflow defect is tracked in a separate issue with a 来源 marker pointing at #475.
3. Fix-up commit on the release branch: this devlog folder + `### v1.18.3` entries in both changelogs. No code touched.
4. Version-range regression audit (v1.18.2..HEAD, 19 non-merge commits) completed during PR #475 review — see "Audit" below.
5. Pushed fix-up to the PR branch; `pr-validation` re-runs and must pass. Human merges → `release.yml` auto-publishes.

## Audit (v1.18.2 → v1.18.3, from PR #475 review)

Per-change regression verdicts — existing behavior of each touched path inventoried before judging:

| Change | Verdict |
|--------|---------|
| #405 bili native yield | Intended behavior change (old: yield only on `BILLION_CONTEXT_PROXY` sampled once at setup + `/bili/` baseURL detection; new: also yields on `BILLION_CONTEXT_NATIVE`, re-sampled at every hook call / config run / tool action). No collateral regressions: yield paths skip `hostPermissions.global` assignment exactly as the old proxy path did; false positives limited to the two dedicated env vars; all five tools gated at `resolveToolContext`. Tests: `tests/bili-native-yield.test.ts` (+355). |
| #446 decompress source availability | Intended fail-closed change (old: phantom "restored N" claims + stats underflow + irreversible summary discard when originals absent; new: explicit abort, zero state mutation). Check precedes all mutations; `toFile` path unaffected (no state change; falls back to annotated summary export). Conservative direction verified: over-requiring IDs ⇒ safe-direction abort only. Tests: +426/+248 lines. |
| #447 toFile originals | Intended output-format fix (old format was broken — read non-existent `content`/`text` fields off SDK messages, exported JSON garbage; new: parts serialization, text verbatim + `[tool] output`). |
| #444 quality rejection concise | Intended output-format change (model-facing error shrunk to core reason + 1 stats line + retry hint; full metrics → `logger.warn`). Single call site (`lib/compress/range.ts:323`) passes the logger; `acknowledgeRisk` hint retained. |
| #457/#465 acp_status respect | Intended semantics restoration (user exact/wildcard decisions on `acp_status` no longer inverted/erased by ACP's default write). Preserved: explicit-user-`compress` deferral returns the map unchanged — identical to old behavior; unrelated host rules untouched. Tests: `tests/host-permissions.test.ts` (+102, issue-numbered regression tests). |
| #461 overhead set bound | No behavior change except the leak fix (dedup semantics kept; worst case one duplicate ERROR line after eviction past cap 1024). Test: +73 lines. |
| #443/#474 one-click release CI | `workflow_dispatch`-only, no runtime impact. Contains the devlog/changelog gap found in step 2 above (separate issue filed). |
| Docs (#441/#442/#450/#451/#471) | Cosmetic; no runtime impact (README Community/QQ groups + V2 pointer, AGENTS.md codification, devlogs). |

**Regressions introduced in this version: none.** Major intended behavior changes listed above (all disclosed old→new).

## Known operational notes

- Merge method matters: `release.yml` detects release merges by commit title. Standard merge ("Merge pull request #475 from ranxianglei/2026-09-30_release-v1.18.3") matches Pattern 1 ✓. A squash merge titled "release v1.18.3 (#475)" would NOT match Pattern 2 (`^release: v...` requires the colon) and publishing would be silently skipped — use the standard Merge button.
- Workflow defect (fallback PRs always lack devlog/changelog) tracked in a separate issue with 来源 marker pointing here.

## Post-merge (human merge + automated CI)

- Human merges the PR → `release.yml` detects release branch → tags `v1.18.3` → `npm ci` → `check:package` → full test → publishes to npm `latest` → creates GitHub Release.
- Verify after publish: `npm view opencode-acp dist-tags.latest` = 1.18.3; `gh release view v1.18.3`.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "opencode-acp",
"version": "1.18.2",
"version": "1.18.3",
"type": "module",
"description": "Active Context Pruning — model-driven context management for OpenCode (hardened fork of DCP with 35 bug fixes)",
"main": "./dist/index.js",
Expand Down
Loading