Skip to content

ci(test-shard-timings-refresh): the weekly refresh opens its PR with the Actions token, so the PR gets no CI and waits for a human push — #13028 has sat since 10-19 with 585 newly measured files while the shards run 1.3–1.8× unbalanced #25936

Open

Description

@objectstack-fleet

Filing gate: ③ maintainer-directed task (CI performance programme, 2026-10-23). Reader: the domain:ui execution seat — step 1 is a one-time landing of PR objectstack-ai/objectui#13028 the seat drives for its author, step 2 is one os-dev PR. Dedup: search_issues on objectstack-ai/objectui, closed included, "test shard timings refresh PR no CI Actions token push stale timings" → 23 hits, none on the refresh PR's missing CI; the refresh itself is objectstack-ai/objectui#12208's lineage. None open. Session: session_01GVTBi44LAWbPWg4evKfE1T.

One-sentence problem

objectui balances its 16 test shards from a per-file timings dataset that a weekly workflow refreshes by opening a pull request — but that PR is opened with the workflow's own Actions token, GitHub starts no CI for it, and nobody pushes to it, so the dataset in use is from 2026-10-12, 764 of 5,718 test files are missing from it, and the shards run up to 1.8× apart while a correct refresh has been waiting as PR objectstack-ai/objectui#13028 since 2026-10-19.

Evidence (objectui commit 5fef032; PR read 2026-10-23)

  • .github/workflows/test-shard-timings-refresh.yml:41 (the comment: "The pull request is opened with this run's GITHUB_TOKEN, and GitHub starts …"), :128, :145, :164 — GH_TOKEN: secrets.GITHUB_TOKEN; :189 — gh pr create --repo … --base main --head "$BRANCH"; :182 — the workflow writes into its own PR body: "This pull request has no CI of its own yet. It was opened with the Actions token, and GitHub starts no workflow for an event that token raised. Push to its branch once …".
  • objectui#13028: opened 2026-10-19T07:14Z by github-actions[bot], open, mergeable_state: behind, 1 commit, +5229/−4639 in scripts/test-shard-timings.json, no check runs; its body lists 585 files measured for the first time and 17 no longer measured.
  • Dataset in use: measured.at 2026-10-12 (bootstrap from two runs, marked PARTIAL); 764 of 5,718 test files absent and assigned the 4,490 ms median. Measured imbalance on current runs: full battery 8.5–11.2 min per shard (1.3×), PR runs 6.5–12.0 (1.8×); the Test aggregator's headroom notice reads 56–60%.
  • Once the affected fast path runs (sibling card), small PRs carry ≈ 2 min of weight per leg and a stale dataset mis-sorts them harder.

Governing text

  • test-shard-timings-refresh.yml:39-48 documents the token limitation and the manual push as the accepted workaround; objectui#5397 (closed) refused a personal access token for automation — the fix must not reintroduce one.
  • objectui AGENTS.md §9 (merge-queue and changeset discipline) governs how step 1 lands.

Change

  1. One-time: the lane seat drives chore(test): refresh the per-file test timings (objectui#12208) objectui#13028 for its author — merge main into ci/test-shard-timings-refresh (that push starts its CI; the dataset is in the root vitest config import closure, so the full suite runs on the new split), then land it through the queue under the repo's own conventions.
  2. Structural, dev picks one and cites [finding] The changeset release PR runs no CI at all — every ci.yml run on changeset-release/main is action_required, so the release commit reaches main unvalidated objectui#5397: (a) have the refresh raise its PR through an identity whose events start workflows — the fleet App token via the objectstack fleet-write relay (pr_create op; scripts/pm/** has a single writer on the objectstack side, so if the op or a cross-repo route is missing, the dev files the upstream card and links it here with Blocked-by:); or (b) keep GITHUB_TOKEN for the PR and immediately workflow_dispatch ci.yml on the new branch (ci.yml:4-65 already declares workflow_dispatch), accepting that the dispatched run is not a pull_request event and checking that the required contexts still attach to the PR head.
  3. Remove or rewrite the "no CI of its own yet" paragraph at :182 once it is no longer true.

Acceptance

Work estimate

Lane domain:ui · 1 PR (.github/workflows/test-shard-timings-refresh.yml) + the one-time objectstack-ai/objectui#13028 landing · precedent: the refresh workflow itself (lineage objectui#12208; its PR beyond this depth-50 clone). Clause-②: no · Metadata-protocol: none · Tier H (governed surface — the PR waits for a GOVERNED_APPROVERS approval before ready).

Prior rulings read: shard, partition → objectstack docs/adr 3 hits, AGENTS.md 0; objectui thread: objectstack-ai/objectui#5397 (closed, PAT refused), objectstack-ai/objectui#12208; ADR none.

Related: objectui#13028 (open PR), objectui#12208, objectui#5397 (closed), the affected-fast-path and Repo Gates cards filed alongside this one.

Maintainer directive (verbatim, untranslated)

同意,立卡

— the maintainer, 2026-10-23, in reply to the director seat's offer 「(a) 我按 PM 流程把 A1–A5、B1–B3 立成卡进队列(英文卡面、带 Governing text: 与工作量列),由 os-dev 派发」. The CI performance analysis those letters index is the seat's 2026-10-23 five-line audit (objectstack ci.yml + lint.yml; the other 39 workflows; the repo-side turbo/vitest/gate configuration; objectui's 28 workflows; GitHub Actions run data for the preceding 5–55 hours). The maintainer's stated goal, verbatim: 「我希望优化的是性能和效率速度」.

Activity

  1. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: instrument — CI time-to-green for every lane (area:devpath, the road's dev/verify step) | none — no platform-checklist item asserts CI speed | priority:p2 (North Star rule 3: an instrument card inherits along the chain; the queue position is set by the maintainer directive below) | none

    Triage: lands in domain:ui (objectui) — .github/workflows/test-shard-timings-refresh.yml plus the one-time landing of objectui#13028; labels tooling · area:devpath · priority:p2 · pm:queue; type Task (the create door carries no type flag — triage sets it on first touch); rationale: the weekly refresh PR is opened with the Actions token so it gets no CI and waits for a human push; objectstack-ai/objectui#13028 has waited since 10-19 with 585 newly measured files while shards run 1.3–1.8× apart.

    Direct-dispatch channel (pm-dispatch cross-repo-coordination: 「维护者直派通道:当面指挥的 PM 会话直接路由,只对明示指挥的卡成立。直派的审计评论逐字引用授权指令。」). The authorising words, verbatim and untranslated — the maintainer, 2026-10-23, replying to the director seat's offer:

    seat: (a) 我按 PM 流程把 A1–A5、B1–B3 立成卡进队列(英文卡面、带 Governing text: 与工作量列),由 os-dev 派发;(b) 先只要这份报告,总监席决裁批照原计划开。
    maintainer: 同意,立卡

    The word covers filing and dispatch; the lane seat dispatches this card under it even while a p1 sits in the lane queue (优先序:维护者裁决 > 北极星). Labels and domain were set by the filing seat under this channel, not by triage — triage may spot-check (SKILL.md 域车道 例外二).

    Filed by the director seat, session session_01GVTBi44LAWbPWg4evKfE1T, from the 2026-10-23 CI performance audit (five read-only lines: objectstack ci.yml + lint.yml; the other 39 workflows; repo-side turbo/vitest/gate configuration; objectui's 28 workflows; GitHub Actions run data).

    Written 2026-10-23T04:45Z by the director seat.

  2. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-23T11:40Z
    Session: session_01Cr2pnminvpXPZAG6sKgzgN (a card session of the Sales account's project, dispatched by its coordinator; 由Sales账户的项目负责)
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/issue-13349-refresh-pr-ci
    Worktree: objectui-issue-13349
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: .github/workflows/test-shard-timings-refresh.yml, the tests that pin it under scripts/__tests__/, its section in content/docs/guide/ci-cd-pipeline.md; plus the one-time landing of PR objectstack-ai/objectui#13028 by a relay pr_update_branch stroke (no file of mine) (stop on breach; explain in the report)
    Container & model: M, mode:thread (base origin/main 2c4e5f5), model: opus (default; dispatch-gates --tier --repo objectstack-ai/objectui answered "no path-derived mandate"), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6357595286
    Serial constraints cleared: none (no open claim of this lane names test-shard-timings-refresh.yml)

    Order of work: step 1 first (sync objectstack-ai/objectui#13028 with main as the fleet so its CI starts; the dataset is in the root vitest config import closure, so that run is the full suite on the new split), then step 2.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR objectstack-ai/objectui#13028 comment 6364330747 (终局四件套: 9868 lines > 3000; needs-user-decision on the PR; waits for an authorized approval, then the seat queues it) · domain:ui seat 1 · 2026-10-23T11:58Z

  4. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling recorded · card session session_01Cr2pnminvpXPZAG6sKgzgN · 2026-10-23T12:07Z

    Step 2 of this card offered two routes; both were measured unworkable as written (2026-10-23, objectui main 2c4e5f5):

    • the workflow_dispatch route rests on a premise that does not hold: ci.yml's on: is push / pull_request / merge_group / schedule only, and six of the queue's seven required contexts (Lint aside) come from workflows that take no workflow_dispatch (ci.yml's Type Check, Build & E2E, Build Docs, Test; changeset-presence.yml's Changeset Declaration; governed-surface-guard.yml's Governed Surface Queue Guard);
    • the relay route has no caller: the objectstack fleet-write relay starts only on a repository_dispatch to objectstack, which this repository's GITHUB_TOKEN cannot send, and no workflow here holds an App credential.

    Step 1 is done: the relay's pr_update_branch synced objectstack-ai/objectui#13028 as the fleet (head 17b3796), every required context went green, and the seat's record is on objectstack-ai/objectui#13028.

    Ruled: the refresh mints a narrowed, short-lived fleet App token on its runner (actions/create-github-app-token, the organization's OS_FLEET_APP_ID variable and OS_FLEET_PRIVATE_KEY secret, scoped to this one repository) and pushes its branch and opens or updates its pull request with it, so the pull request's own events start CI.

    Provenance (who / verbatim / where): Sales (os-sales), the project owner directing this lane, in the project chat on 2026-10-23, replying to the coordinator's two-option summary (the App-token route vs. an objectstack-side upstream route with this card parked). Verbatim reply, untranslated:

    A

    Two things this ruling cannot settle, asked of the maintainers (GOVERNED_APPROVERS) here; the implementing pull request stays a draft and waits for them:

    1. Secret visibility. Is the organization secret OS_FLEET_PRIVATE_KEY (and variable OS_FLEET_APP_ID) visible to objectstack-ai/objectui? A session cannot read an organization secret's repository access. If it is restricted to selected repositories, adding objectui is the one settings action this needs.
    2. Narrowing objectui#5397. That ruling (2026-08-22) rejected "a PAT / GitHub App token" for the release pull request because a zero-trust-surface alternative existed there (validate the post-version tree in-workflow). This card has no such alternative: the refresh pull request exists so the new split runs the full suite before it lands. Confirm that [finding] The changeset release PR runs no CI at all — every ci.yml run on changeset-release/main is action_required, so the release commit reaches main unvalidated objectui#5397's rejection is read as scoped to the release pull request, so this workflow may mint the fleet token. A personal access token stays out either way.

    Approving the implementing pull request answers both.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Hold · domain:ui seat 1 · session_01WJozybDmRH8z2c5SD7vJkj · 2026-10-24T13:17Z

    pm:dispatched → pm:on-hold.

    Why. The project owner has decided to merge objectui into the objectstack repository. This card changes objectui's own CI: the weekly shard-timings refresh workflow and its PR, objectstack-ai/objectui#13028. So the card stops here rather than finish a route that the move will replace.

    Provenance. The instruction is Sales's (the project owner, account os-sales). Their words were 「按建议」 ("as proposed"), given in this project's chat at 2026-10-24T13:15Z. It approves the coordinator's plan for the ui lane during the repo move, and that plan names this card as stopped.

    State left behind:

    Restart-when: the objectui → objectstack repository move is done. The card is then re-read against the merged CI, where the shard-timings refresh may be rebuilt or dropped. Until then, nobody works this card.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session_01Cr2pnminvpXPZAG6sKgzgN (the card session named in the claim 6364048769) and the domain:ui seat 1 (session_01WJozybDmRH8z2c5SD7vJkj) · cause: the domain:ui seat 1 of the Sales account's project clocks out · destination: stays pm:on-hold, assignee cleared · 2026-10-24T15:50Z

    Provenance. The instruction is Sales's (the project owner, account os-sales): 「ui 车道下班」 ("the ui lane clocks out"), given in this project's chat at 2026-10-24T15:48Z.

    Hand-over note.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Pause lifted · domain:ui seat 4 (vacant; written by its signed-off session session_01XWGTsmqrtrt1Zqh1ioWqsT) · 2026-10-25T14:09Z

    pm:on-hold → pm:queue. The maintainer lifted the os-sales pause (hold 6384686873) in this project on 2026-10-25T14:08Z: 「你放回队列就写」. Nothing dispatches it now, because the domain:ui lane is off duty.

    For whoever dispatches it next: the hold's own reason still applies. This card changes objectui's own CI (the weekly shard-timings refresh and its PR objectstack-ai/objectui#13028), and the repo move in objectstack#25677 is still open. That move will replace this route if it lands first. Re-read the card against the epic's state before claiming it. objectstack-ai/objectui#13362 (step 2) is merged; objectstack-ai/objectui#13028 (step 1) still waits on maintainer approval.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Transferred 2026-10-26T04:49Z from objectstack-ai/objectui#13349, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the ui/ workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.

    Paths. Read every repository path in the body with a ui/ prefix: .github/workflows/test-shard-timings-refresh.yml is now ui/.github/workflows/test-shard-timings-refresh.yml; scripts/test-shard-timings.json is now ui/scripts/test-shard-timings.json; docs/adr is now ui/docs/adr.

    scripts/pm was already objectstack's own path and stays as written.

    References. The bare issue numbers in the body were written in objectui and now resolve against this repository by mistake; read them as objectstack-ai/objectui#5397, objectstack-ai/objectui#12208, objectstack-ai/objectui#13028.

    No stale pm:dispatched or assignee to strip.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: lane corrected — domain:ui → domain:devx · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T06:12Z

    ⛔ Not a claim, ⛔ not a dispatch. Re-grade after the transfer from objectui (#25854). The objectui-only labels (types, sdui, scripts and others) do not exist here, and GitHub dropped them on the move.


    Generated by Claude Code

  10. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop · 2026-10-26T08:12Z
    Session: session_014GRKsjPHqpppQDE1LMetJX (card thread, dispatched by seat session session_01LKHDniRQSWjRJyDtacwpEd)
    Account: os-elon-musk
    Branch: claude/project-thread-czb0vs (the harness-pinned branch for the card thread; it names no issue, so this claim is the identity record)
    Worktree: objectstack-issue-25936
    Domain: domain:devx
    Seat: domain:devx#1 (seat post #6023)
    File surface: .github/workflows/shard-timings-refresh.yml (Tier H), scripts/ci/select-shard-timings-run.mjs, scripts/measure-test-shard-timings.mjs, ui/ test-timings dataset only via its generator; may close on a reading (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier, effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — CI tooling
    Thread-read: none
    Serial constraints cleared: #25870 (PR #25968) edits partition-test-shards.mjs + the Test Core dataset: merge origin/main before each push

    Dispatched under the maintainer's 「同意」 to the director's ruling batch 1, item 5A (devx dispatches p1–p3). Dispatch order: /mnt/project-files/pm-devx-seat/dispatch-25936.md.

  11. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25936,
      "status": "done",
      "branch": "claude/project-thread-czb0vs",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26017",
      "session": "session_014GRKsjPHqpppQDE1LMetJX",
      "premise_still_valid": true,
      "summary": "Premise re-read per triage 6409504632. (1) The root shard-timings-refresh.yml has the card's defect: #25960 is authored by github-actions[bot] and carries the USED_PAT-false 'No checks will start' section, so RELEASE_PUSH_TOKEN is unset; CI only started after a relay pr_update_branch. PR #26017 (Tier H, one file, +78/-24) mints a fleet App token on the runner (actions/create-github-app-token@v3, OS_FLEET_APP_ID + OS_FLEET_PRIVATE_KEY, narrowed to this repo, contents + pull-requests write, no workflows grant) and pushes, opens and labels with it; job token drops to contents/actions read; checkout persists no credential; a missing credential is a named red; pull_request runs stay a dry run that mints nothing; the PR-body no-CI paragraph is replaced (card step 3). (2) The ui/ per-file dataset has NO producer: ui/.github/workflows/test-shard-timings-refresh.yml is nested and never runs, root ci.yml Test UI uploads no test-file-timings-N artifact, and its own comment hands the port to the governance-workflow audit = #25712 item 5 (os-tesla epic, in flight), which names test-shard-timings-refresh for folding into this lane. Not built here (duplicate of in-flight work); numbers in the PR body. PR says Part of #25936: the card waits for the first live refresh PR's CI reading and for #25712's ui half.",
      "tests": "Write step lifted from the YAML and run under bash -e in a scratch repo at 50d4fffd: dry leg (DRY_RUN=true, pull_request) exit 0, every outward act printed DRY RUN incl. gh auth setup-git, commit authored objectstack-fleet[bot]; live leg with empty GH_TOKEN exit 1 at the GH_TOKEN guard. Credential-check step: both set exit 0 + repository=objectstack; app id missing exit 1; key missing exit 1. No ablation: workflow change.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 42 derived, all 42 run locally exit 0 (captured before any pipe), incl. select-shard-timings-run --self-test, measure-test-shard-timings --self-test, partition-test-shards --self-test, check:pm-dispatch-gates fast tier 1917 cases; --ran: 42 run, 0 NOT MEASURED, exit 0. check-governed-merges --branch HEAD: GOVERNED .github/workflows/**, Tier H, 102 lines. Gates ran at 50d4fffd; head cadda147 adds only a conflict-free merge of origin/main a3e5bfa6 (diff vs main unchanged, one file). CI check-runs on #26017: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "13 — read-only: issue_read x5 (#25936 get + comments, #25712 get + comments, #25677 sub-issues), pull_request_read x2 (#25960, #26017 read-back), search_issues x1, plus ToolSearch loads; 0 write tools",
      "api_writes": "2 relay writes — fleet-write pr_create (PR #26017, label skip-changeset, assignee os-elon-musk) and this comment + pr_request_reviewers os-elon-musk in the same stroke; plus 1 git push",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: #25712 item 5 · ui/ per-file dataset has no producer since the cutover: ui/scripts/test-shard-timings.json measured 2026-10-19T06:37Z (6 runs, 5547 keys); of 5805 tracked ui test files 290 have no key (weighed at the median) and 32 keys are stale; root Test UI uploads no timing artifact. Serial note: folding it into shard-timings-refresh.yml touches the file #26017 edits.",
        "carrier: none · noted, not filed: cut-rc.yml makes the same PAT-if-present-else-Actions-token choice for the RC PR"
      ]
    }

    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions