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

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions