Skip to content

os-regen 驱动指示的 gen:schema 在 merge 未 commit 时运行,会把 authorable-surface 锚点倒退回旧 merge-base —— 生成器写入、门全绿、静默撤销 main 的锚点推进 #5370

Description

@os-zhuang

现象(PR #5312 同步接力实测,可复现)

os-regen 合并驱动在 merge 停下时打印的处方是:

⟳ packages/spec/authorable-surface.json
   not text-merged — it is generated. Regenerate from the merged tree:
     pnpm --filter @objectstack/spec gen:schema

逐字照做——在 merge 尚未 commit 时gen:schema——会把 authorable-surface.base.json 的锚点倒退:

为什么这比一般脏产物更值得修

倒退后的锚点依然 authentic——5aae790 是 origin/main 祖先、keys 与该 commit 的 surface 逐行一致——所以 verifyCommittedSurfaceBasecheck:authorable-surface、pre-commit 的 os-regen 守卫全部放行。没有任何门会拦下它。后果:

  1. main 上 feat(spec)!: 退役 ui/ 五个没有承载键的交互配置文件 —— touch/dnd/keyboard/animation/offline (#4988) #5321 那次锚点推进被静默撤销,文件重新胖 109 键;
  2. PR diff 里出现一次「反向锚点移动」,review 时与 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 的攻击形状(手改锚点藏删除)难以一眼区分——尽管这次是生成器写的;
  3. 离线消费者(spec 的 #4650 删除闸门在「按 SHA 钉住的消费者构建」里无法锚定 origin/main,硬失败 —— cloud 的镜像构建与 pin bump 全线卡死 #5235 的 in-tree 锚点用户)拿到一个比 main 已发布状态更旧的基线。

触发条件

分支带 authorable-surface 增量 + merge origin/main 停在冲突/待重生成 + 在 commit 前照驱动提示跑 gen:schema。多 agent 并行、spec 车道高频合并的这个仓库里,这是每天都会走到的路径。

PR #5312 采用的规避(可作修法参考)

deferred 生成物 reset 到 origin/main → 重建 → 先 commit merge → 再跑 gen:schema(此时 merge-base = 刚合入的 main tip,锚点由生成器正向推进,独立 commit)。

候选修法(供 triage,不预设)

  • resolveSurfaceBase() 检测 MERGE 状态($GIT_DIR/MERGE_HEAD 存在)时改用 MERGE_HEAD 与 origin/main 的 merge-base(即被合入的 main tip),或至少拒绝把 baseRev 移向祖先方向(锚点只进不退——gen:schema 自己能判定新旧:旧 rev 是新 rev 的祖先);
  • 驱动的打印处方与 AGENTS.md §11 补一句「先 commit,后 gen:schema」;
  • pre-commit 的 os-regen 守卫在锚点 baseRev 相对 committed 版本后退时警告。

第一条最贴「结构上让 AI 写不错」:处方照抄也不会写出倒退锚点。

发现于 #5312 的同步接力;该 PR 未受影响(已按上面的规避处理)。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions