Skip to content

[design] squash 后 sync 取不回基线:浅修复被 harness 的 readBrief+write 两处堵死,需契约变更 #65

Closed

Description

@stack-wuh

结论:浅修复不可行,这条需要改 harness 契约

原设想:sync plan 在 brief(r, n) 抛 BRIEF_NOT_FOUND 时,退到 git show origin/main:shadow-docs/changes/<name>/brief.md 取 blob 解析。

实测该方案卡在两处(都试过并回退):

  1. 抛错点不在 sync 域内。 cli.mjs:61 的 planDomain 在进入域逻辑之前就 readBrief(mod, r, o),缺省实现是硬 brief(r, name(o));cli.mjs:44 的 executeDomain 同样。域侧改 planData 无效——它根本没被调用。
  2. 取回 blob 也过不了持久化。 cli.mjs:62-64 无条件 b.data.workflow.planHash = e.planHash; write(b)。blob 派生的 brief 没有真实 path,write() 会 mkdirSync(dirname(null)) 崩;若给它造一个 path,就等于在 fast-forward 之前往工作树落一份 untracked 副本,随后 git merge --ff-only 因「untracked 文件会被覆盖」直接失败(GIT_FAST_FORWARD_FAILED),把死结换成更坏的结。

另外,sync 的凭证模型本身依赖 brief:executeDomain 用 b.data.workflow.planHash === e.planHash 做前置校验。工作树没有 brief 时这个凭证无处存放。

真修复的形状(择一,需设计决策)

  • A. 给 plan 加只读声明:域导出 transientPlan: true 时,planDomain 跳过 write(b),executeDomain 改走 --plan-hash 显式凭证(与 index rebuild、blog publish 这类无 brief 域同构)。改动面:cli.mjs 两处 + sync.mjs + 文档与插件 SKILL 的 sync execute 调用形态(需带 --plan-hash,属对外契约变更,要走 CLI 版本 bump)。
  • B. 让 sync 不需要 brief:squash 收口场景里调用者已在基线分支上,upstream 可直接取 origin/<当前分支>,baseBranch 无需从 brief 读。凭证改由 --plan-hash 承载(同 A 的持久化跳过)。这条比 A 更窄,但语义损失是:非 main 基线的 sync 要显式传 --base-branch。
  • C. 维持现状:明确把「squash 合并后收口」定义为人工 git merge --ff-only origin/<base> + 在 main 上重跑 review,插件 SKILL §4 写清,不再假装 CLI 覆盖该路径。

我倾向 B(最小且不改现有凭证语义,只把无 brief 的分支场景显式化),但它仍是对外契约变更,该由你定方向后再动。

已验证不受影响

Activity

  1. changed the title [-][fix] squash 合并后 sync 死结:main 工作树无 brief 时 BRIEF_NOT_FOUND[/-] [+][design] squash 后 sync 取不回基线:浅修复被 harness 的 readBrief+write 两处堵死,需契约变更[/+] on Oct 12, 2026
  2. stack-wuh commented on Oct 12, 2026

    @stack-wuh
    OwnerAuthor

    本轮另两条修复已就绪:PR #64(bind dirHash 子目录 EISDIR)、PR #67(CLI 发布链缺工作流)。本 issue 记录的 sync 死结经实测无法浅修(抛错点在 cli.mjs 的 readBrief 与 planDomain 的无条件 write(b)),代码已全部回退、未留半成品;三个可选设计与推荐见正文。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions