Skip to content

ci.yml 的 TURBO_SCM_BASE 吃同一个冻结 base.sha —— turbo --affected 在 merge ref 上把 main 漂移算成本 PR 改动(方向保守:多跑,不会少跑) #6195

Closed

Description

@hotlong

#6129 的同族第三个消费者,在 ci.yml。#6129 的实现单(PR #6192)按派单约束不碰 ci.yml,故按 Prime Directive #10 单开、不认领。

事实(读的是 origin/main 的 ci.yml,不是推的)

.github/workflows/ci.yml Compute this shard's package set 步骤:

        env:
          TURBO_SCM_BASE: ${{ github.event.pull_request.base.sha }}
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            pnpm exec turbo ls --affected --output=json ...

同一个 job 的 checkout 是 actions/checkout@v7 + fetch-depth: 0、没有 ref: —— 即 pull_request 事件上的默认 merge ref。于是它和 #6129 是同一对输入:

  1. base.sha 在 PR 创建时冻结,不随 main 前进;
  2. HEAD 是 merge ref,含 当前 main 的一切。

两者之间的 main 漂移,会被 turbo ls --affected 当成本 PR 改动的文件,从而把别人 PR 动过的包算进本 PR 的 affected 集合。

方向:保守失效,不是假绿 —— 所以按 observation 立单

冻结的 base 是 HEAD 的祖先,所以 base..HEAD 的文件集是本 PR 真实改动的超集(三点写法同理:祖先自己就是自己的 merge base,#6129 已实测)。affected 包集合因此只会变大,不会变小:

  • 不存在「本该跑的包没跑」这种漏测;
  • 实际后果是 affected-only 这项优化随 PR 在飞时长而衰减 —— PR 开得越久,main 合得越多,分片跑的包越多,直到接近全量。本仓一天合 ~18 个 PR,衰减不慢。

也就是说这不是发版安全问题,今天没有用户会撞上,只是 CI 时长与算力。故打 finding、不打 pm:queue,请分诊按队列节奏定级。

若要修

git merge-base "origin/$BASE_REF" HEAD,与 PR #6192 给 pr-automation.yml 用的是同一条:在 merge ref 上它恰好落在 parent^1,diff 只剩本 PR 自己那侧。PR #6192 的 workflow 注释里记了两个「看着像修法、实际不是」的写法(三点、HEAD^1),可直接复用,不必重新推导。

顺带一提:该 job 的 fetch-depth: 0 已经在了(注释写的就是 "Full history so turbo --affected can diff against the PR base"),所以 origin/main 本地可解析 —— PR #6192 在真实 CI 上实测过这一点(Resolve the diff base 步骤没有触发回退 fetch)。

查重与串行

Activity

  1. added
    domain:devxDomain lane — seat card indexed by label:pm:seat
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 7, 2026
  2. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    Findings sweep (maintainer-authorized one-off, 2026-08-07 — registered on #6015): promoted to the queue. Third member of the #6129 frozen-base family; the fix pattern shipped in PR #6192 and ci.yml was explicitly scoped out of it. Direction is conservative (over-runs, never under-runs) so no urgency, but the fix is mechanical with a fresh template. finding → pm:queue.


    Generated by Claude Code

  3. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 8, 2026
  4. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    Claim: PM loop round 1 (devx seat, new tenure)
    Session: session_01F8q5J1MQyocgtNspb15fSn
    Branch: claude/issue-6195-turbo-scm-base
    Worktree: objectstack-issue-6195
    Domain: domain:devx
    File surface: .github/workflows/ci.yml (the Compute this shard's package set step only)
    Container: S — mode:subagent, shared container.
    Serial constraints cleared: .github/workflows/ci.yml — #6082, the in-flight card the body names as sharing this file, closed completed 2026-08-07T11:00Z, so the contention is gone. Last main merge on this path is 82bf47b (#6471, this lane, merged). No open in-lane claim on the file.

    Premise re-verified at origin/main a36db28, not from the card: .github/workflows/ci.yml:220 still reads TURBO_SCM_BASE: ${{ github.event.pull_request.base.sha }}. The frozen-base shape holds.


    Generated by Claude Code

  5. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    ACCEPT — PR #6591 (devx seat review, round 1).

    What shipped: the shard's affected diff now starts at merge-base(origin/$BASE_REF, HEAD) instead of the frozen github.event.pull_request.base.sha — the third and last consumer of the frozen base in this repo's workflows (#6129 family; #6192 fixed the two in pr-automation.yml). Unresolvable base falls back to the full package list with a visible ::warning::, never to the frozen sha — the failure direction deliberately differs from #6192's hard-fail because this step selects tests rather than gating, and the full list is a strict superset.

    Review notes:

    • Diff verified scoped to the one step (+99/-2, single file); the bulk is the workflow-comment record of four measured look-alike non-fixes, matching the file's existing comment density.
    • The dev falsified dispatch assumption 4 (BASE_REF was not in the step's env) and introduced it correctly rather than assuming main — that is the premise-check discipline working.
    • Real fixture measurement both directions (frozen base charges pkg-b to the PR; merge-base does not), plus reverse verification with the correct prediction that reverting makes the set grow.
    • Out-of-scope finding filed as check-shard-attestation.mjs misclassifies a shard job as an aggregate gate on a bare --verify substring anywhere in its run: text (false red, measured) #6589 (check-shard-attestation.mjs substring classifier false-red, measured) — verified it exists, is unassigned, and the PR routes around it in scope (git cat-file -e with the reason written in place).
    • skip-changeset justified: CI-only workflow change, nothing published.

    Ready + auto-merge armed 06:12Z. Tracking to MERGED; flip checkpoint timer armed.


    Generated by Claude Code

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

Metadata

Metadata

Labels

ci/cddomain:devxDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions