Skip to content

OpenCode: 压缩后缺少显式的 bootstrap 重新注入 | No explicit post-compaction re-injection of workflow bootstrap #69

Description

@cinvymoe

问题概述 | Summary

中文:OpenCode 插件(.opencode/plugins/spec-superflow.js)没有针对 OpenCode 上下文压缩(compaction) 的专门处理。压缩之后,<EXTREMELY_IMPORTANT> bootstrap 的恢复只是 experimental.chat.messages.transform 去重检查的意外副作用,而非有意设计。

English: The OpenCode plugin (.opencode/plugins/spec-superflow.js) has no dedicated handling for OpenCode's context compaction. After compaction, recovery of the <EXTREMELY_IMPORTANT> bootstrap only happens as an accidental side effect of the experimental.chat.messages.transform dedup check — not by design.

当前行为 | Current behavior

中文:插件注册了两个钩子:

  1. config — 注册 skills 目录
  2. experimental.chat.messages.transform — 把 bootstrap(包裹在 <EXTREMELY_IMPORTANT> 中的 GEMINI.md)插入第一条 user 消息,由去重检查保护:
if (firstUser.parts.some(p => p.type === 'text' && p.text.includes('EXTREMELY_IMPORTANT'))) return;

OpenCode 压缩会话后,消息历史被摘要替换。第一条 "user" 消息(压缩摘要)不再包含 EXTREMELY_IMPORTANT,去重检查失败,于是 bootstrap 会在下一次发送消息时被静默重新注入。

English: The plugin registers two hooks:

  1. config — registers the skills directory.
  2. experimental.chat.messages.transform — prepends the bootstrap (GEMINI.md wrapped in <EXTREMELY_IMPORTANT>) to the first user message, guarded by a dedup check:
if (firstUser.parts.some(p => p.type === 'text' && p.text.includes('EXTREMELY_IMPORTANT'))) return;

After OpenCode compacts the session, the message history is replaced by a summary. The first "user" message (the compaction summary) no longer contains EXTREMELY_IMPORTANT, so the dedup check fails and the bootstrap is silently re-injected on the next message send.

存在的问题 | Problems

中文:

  1. 时机滞后:重新注入发生在下一条消息发送时,而不是压缩完成的那一刻——压缩后的首个模型回合在没有 bootstrap 上下文的情况下运行
  2. 脆弱性:依赖压缩摘要永远不含字面字符串 EXTREMELY_IMPORTANT。如果未来 OpenCode 版本把先前上下文纳入摘要,重新注入会静默失效
  3. 未被记录:全仓库搜索 compacting / compaction 无任何匹配——这一行为是涌现的副作用,不是经过测试的契约

English:

  1. Timing: re-injection happens on the next outgoing message, not at compaction time — the first post-compaction model turn runs without the bootstrap context.
  2. Fragility: it depends on the compaction summary never containing the literal string EXTREMELY_IMPORTANT. If a future OpenCode version includes prior context in the summary, re-injection silently stops.
  3. Undocumented: a repo-wide search for compacting / compaction finds nothing — this behavior is an emergent side effect, not a tested contract.

建议 | Suggestion

中文:添加显式的 experimental.session.compacting 钩子,将 bootstrap 追加到 output.context,例如:

English: Add an explicit experimental.session.compacting hook that appends the bootstrap to output.context, e.g.:

'experimental.session.compacting': async (_input, output) => {
  const bootstrap = getBootstrapContent();
  if (!bootstrap) return;
  output.context.push(bootstrap);
},

中文:这样可以保证工作流 bootstrap 在压缩发生的瞬间确定性地存活下来。

English: This guarantees the workflow bootstrap survives compaction deterministically, at the moment compaction happens.

环境 | Environment

  • spec-superflow 版本 | version: 当前 main(v0.10.0)| current main (v0.10.0)
  • 平台 | Platform: OpenCode

Supersedes #68 / 替代 #68

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions