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

### v1.14.23 — Fix batch: effective compressible accounting, emergency no-target notice, fixed growth threshold, tag-aware auto-update

**Problem**: Four fix clusters since v1.14.22: (1) nudge accounting counted messages the compression pipeline soft-filters (protected anchors, empty messages, last user message) as "compressible", so the model was pointed at phantom ranges and every failed retry re-armed the same nudge — the repeated-compression loop of issue #37 (floors 156-175, ~10 phantom retries); (2) under emergency override with nothing valid to compress, ACP still demanded "compress now" every turn (~12 failed compressions; #216 residual surviving the v1.14.4 fix through the emergency path); (3) `nudgeGrowthTokens` defaulted adaptively to `min(50K, max(6K, modelContextLimit×5%))`, so nudge cadence silently scaled 5× between a 262K and a 1M model with identical configs — and since v1.14.15 users with any compress key got the adaptive value while users with none got fixed 50K; (4) auto-update never fired for `opencode-acp@stable` installs (bare dist-tag words failed the updatable-spec gate) and compared against the hardcoded `latest` dist-tag, which can never land for a tagged install (#328).

**Fix**:
- **#325** `CompressibleRange.effectiveTokens` counts only messages that survive pipeline soft-filters; `resolveEffectiveFloor` derives the floor from `minCompressRange÷4` (0 when `minCompressRange: 0`); universal `effective > 0` guard stops phantom-range recommendations; `nothingToCompress` extended with `allBelowMin`. Fixes the phantom retry loop of issue #37.
- **#326** emergency + no valid targets now emits a single actionable `/compact` notice (via reply tool) instead of demanding compressions that cannot succeed — closes the #216 residual.
- **#327** `nudgeGrowthTokens` is a fixed `50000` default for all models (T2/T3 tier triggers and growthFloor uniform at 22.5K); `compress.nudgeGrowthTokens` remains the single tuning knob.
- **#330** auto-update tracks the dist-tag the plugin was installed from (`@stable` follows `stable`, `@pr-N` follows `pr-N`, ranges follow `latest`); registry version check hits `/name/<tag`; version-locked and non-registry specs never update. Closes #328.

Files: `lib/messages/inject/inject.ts`, `lib/messages/inject/utils.ts`, `lib/update.ts`, `dcp.schema.json`, docs (README×2, CONFIGURATION×2). Tests: 1024 pass / 0 fail; E2E scenarios pass with pinned scenario configs.

Closes: #328 (also resolves the phantom-loop and emergency-demand symptoms of #37/#216).

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

### v1.14.22 — Stable system prompt token estimate (#255)

**Problem**: After ACP compression physically removes the true first assistant message from visible history, nudge and `acp_status` each re-derived the system prompt token estimate from the _first visible assistant_ — a much later turn whose `input` includes large accumulated history. Both inflated the estimate (a real ~10K system reported as ~200K), and because each consumer saw a different message view (post-prune transform array vs. a fresh store fetch), the two numbers diverged from each other. The `state.systemPromptTokens` cache (written pre-prune every turn) existed but was never read.
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# 更新日志

### v1.14.23 — 修复批次:有效可压缩记账、紧急无目标通知、固定增长阈值、tag 感知自动更新

**问题**:v1.14.22 以来的四个修复簇:(1)nudge 记账把被压缩管线软过滤的消息(受保护锚点、空消息、最后一条用户消息)算作"可压缩",模型被指向幻影区间,每次失败重试又重新武装同一个 nudge —— 即 issue #37 的连续压缩死循环(floors 156-175,约 10 次幻影重试);(2)紧急覆盖 + 无有效压缩目标时,ACP 仍每轮要求"立即压缩"(约 12 次失败压缩;#216 残留,经 emergency 路径活过了 v1.14.4 修复);(3)`nudgeGrowthTokens` 自适应默认 `min(50K, max(6K, modelContextLimit×5%))`,相同配置下 262K 与 1M 模型的 nudge 节奏相差 5 倍——且自 v1.14.15 起,带任意 compress 配置键的用户拿到自适应值,完全不配的用户反而拿到固定 50K;(4)`opencode-acp@stable` 安装的自动更新从不触发(裸 dist-tag 词过不了可更新判定),且对比硬编码的 `latest` dist-tag —— 对 tag 安装永远无法落地(#328)。

**修复**:
- **#325** `CompressibleRange.effectiveTokens` 只统计通过管线软过滤的消息;`resolveEffectiveFloor` 由 `minCompressRange÷4` 推导(`minCompressRange: 0` 时为 0);统一的 `effective > 0` 守卫阻止幻影区间推荐;`nothingToCompress` 扩展 `allBelowMin`。修复 issue #37 的幻影重试循环。
- **#326** 紧急 + 无有效目标时改发一条可执行的 `/compact` 通知(经 reply 工具),不再要求不可能成功的压缩 —— 关闭 #216 残留。
- **#327** `nudgeGrowthTokens` 对所有模型固定默认 `50000`(T2/T3 层触发与 growthFloor 统一为 22.5K);`compress.nudgeGrowthTokens` 仍是唯一调节旋钮。
- **#330** 自动更新跟踪安装时所用 dist-tag(`@stable` 跟随 `stable`,`@pr-N` 跟随 `pr-N`,范围规范跟随 `latest`);registry 版本检查改查 `/name/<tag>`;版本锁定与非 registry 规范永不更新。关闭 #328。

文件:`lib/messages/inject/inject.ts`、`lib/messages/inject/utils.ts`、`lib/update.ts`、`dcp.schema.json`、文档(README×2、CONFIGURATION×2)。测试:1024 通过 / 0 失败;E2E 场景在钉住场景配置后全部通过。

关闭:#328(同时解决 #37/#216 的幻影循环与紧急命令症状)。

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

### v1.14.22 — 稳定的 system prompt token 估计 (#255)

**问题**:ACP 压缩把真正的首条 assistant 消息从可见历史中物理剪掉后,nudge 和 `acp_status` 各自从"第一个可见 assistant"(实际是后轮次,其 `input` 含大量累积历史)重新推导 system prompt token 估计。两者都会把估计值吹大(真实 ~10K 的 system 被报成 ~200K),且因各用各的消息视图(剪枝后的 transform 数组 vs 重新拉取的 store),两个数字还会互相不一致。`state.systemPromptTokens` 缓存(每轮在剪枝前写入)一直存在,但从未被读取。
Expand Down
30 changes: 30 additions & 0 deletions devlog/2026-08-21_release-v1.14.23/REQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# REQ — v1.14.23: fix batch (#325, #326, #327, #328)

## Problem

Patch release shipping four fix clusters accumulated on master since v1.14.22:

1. **#325** (issue #37 phantom loop): nudge accounting counted pipeline-soft-filtered messages
as compressible → phantom-range recommendations → ~10 failed retries re-arming the same nudge.
2. **#326** (#216 residual): emergency override + `nothingToCompress` still demanded "compress
now" every turn (~12 failed compressions in incident `ses_7fb5cbc8`).
3. **#327**: `nudgeGrowthTokens` adaptive default (`window×5%`) scaled nudge cadence 5× between
262K/1M models with identical config; config-default vs policy-default divergence since
v1.14.15.
4. **#328**: auto-update never fired for `@stable` installs (dist-tag gate) and compared against
hardcoded `latest` — unlandable for tagged installs.

## Content since v1.14.22

- `a6921bd` Merge PR #325 — `fix: effective compressible accounting stops phantom-range retry loops`
- `e9a6b08` Merge PR #326 — `fix: emergency + nothing-to-compress emits /compact notice (#216 residual)`
- `c2c863b` Merge PR #327 — `fix: nudgeGrowthTokens fixed default 50K — removes window-percentage scaling`
- `971d9b7` Merge PR #330 — `fix: auto-update tracks installed dist-tag, not hardcoded latest (#328)`

## Acceptance

- All existing tests pass (1024 expected)
- Version bump on this release branch only; `CHANGELOG.md` and `CHANGELOG.zh-CN.md` updated
with `### v1.14.23`
- typecheck green
- release.yml publishes v1.14.23 to npm `latest` after merge
26 changes: 26 additions & 0 deletions devlog/2026-08-21_release-v1.14.23/WORKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# WORKLOG — v1.14.23

## Commits on this release (since v1.14.22)

1. `a6921bd` Merge PR #325 — effective compressible accounting:
`CompressibleRange.effectiveTokens` (soft-filter survivors only), `resolveEffectiveFloor`
(`minCompressRange÷4`, 0 when disabled), universal `effective > 0` guard, `nothingToCompress.allBelowMin`
2. `e9a6b08` Merge PR #326 — emergency no-target path emits actionable `/compact` notice
(reply tool) instead of compress demands; stacked on #325
3. `c2c863b` Merge PR #327 — `nudgeGrowthTokens` fixed default 50K (uniform growthFloor 22.5K);
E2E scenario configs pinned; stale adaptive docs dropped
4. `971d9b7` Merge PR #330 — auto-update by installed dist-tag: `specUpdateTag`, `updateTarget`,
`isDistTag`, `/name/<tag>` registry check (fixes #328); +6 fail-first tests; docs ×4

## Release steps

- `npm version 1.14.23 --no-git-tag-version` (bump `package.json` + `package-lock.json`)
- `### v1.14.23` entries added to `CHANGELOG.md` and `CHANGELOG.zh-CN.md`
- Devlog: this folder (REQ.md + WORKLOG.md)
- Commit `release: v1.14.23 — fix batch (#325 #326 #327 #328)`

## Verification

- `npx tsc --noEmit` — green
- `node --import tsx --test tests/*.test.ts` — 1024 pass, 0 fail
- release.yml publishes v1.14.23 to npm `latest` after merge (tag v1.14.23 + GitHub Release)
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.14.22",
"version": "1.14.23",
"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