Skip to content

CI cost 11a (domain:cloud): publish an on-demand public framework build base image from objectstack main for cloud Dockerfiles #31441

Closed

Description

@objectstack-fleet

repo:cloud#2 · os-zhuang · session_0123kRqqdpAJWYMgsgdAJX4G

Filing gate: ③ a task on the maintainer's word. Sam 2026-11-08 asked for two more evaluations, 「评估是否每个测试都必要,哪些定期运行就可以」 (07:19Z) and 「是否还可以评估哪些 ci或者测试可以迁移到 objectstack 开源项目,那个不要钱。」 (07:44Z), and ruled 「ci 相关优化任务都优先派发」 (07:45Z). Target: at most 35,000 billed minutes per month. Reviews run on fable (「相关任务用 fable 审核」); implementation on opus/xhigh. Report https://claude.ai/artifact/87JwyqMfm3pzfxZcVEiYgB, scripts and per-file timings in project files ci-cost-eval/. Siblings: cloud#3774–#3782. Dedup: searched open cloud and objectstack issues for "CI cost", "periodic", "base image", "spec-changes cache"; no hits beyond the siblings.

Queue: objectstack domain:cloud, so this card is seat 3's per the seat split. Blocks cloud card 11b (filed next, it names this card).

卡 11a(objectstack 仓库,domain:cloud 卡)按需构建公开的“框架构建底座”镜像

  • 仓库:objectstack-ai/objectstack(公开仓库,标准 runner 免费)。按座位分工这张进座位 3 的 objectstack domain:cloud 队列。
  • 背景:cloud 的三个 Dockerfile(apps/cloud、apps/objectos、apps/objectos-ee)都在镜像里从源码安装并构建整个框架和 console。pin 一变或 docker 缓存被挤掉就要冷构建:staging 镜像构建均值比中位数多约 4 分钟;EE 镜像验证在 pin 升级 PR 第一次推送时要约 26 分钟,之后约 5 分钟。
  • 要做:新增一个只能在 main 上的可信运行里发布的 workflow(workflow_dispatch,输入框架 SHA;可选 repository_dispatch),构建并推送 ghcr.io/objectstack-ai/<名字待定>:<sha>:框架依赖安装结果 + 框架 dist + console dist,构建参数和 cloud Dockerfile 现在用的一致。输出镜像摘要。不要每个提交都建,只在 cloud 升级 pin 时按需构建(每天几次)。公开镜像只含开源的框架代码。
  • Done when:对一个指定 SHA dispatch 一次,镜像可匿名拉取,PR 里贴出摘要和构建耗时。

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:cloudTouches cloud: the whole card is the cloud PM's (repo:cloud seat); no objectstack lane claims it
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    repo:cloud#3 · os-zhuang · session_01QUs3BuMyARAhKn8scCUz3t

    os-dev-report · 2026-11-08T09:32Z

    {
      "issue": 31441,
      "status": "done",
      "branch": "claude/project-thread-nkr544",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31454 (draft, Part of #31441, head a54e5890, GOVERNED Tier H: .github/workflows/**)",
      "session": "session_01QUs3BuMyARAhKn8scCUz3t",
      "premise_still_valid": "yes, with one premise break on the dispatch half. The build half holds: cloud's three Dockerfiles (apps/cloud, apps/objectos, apps/objectos-ee at cloud ac69aac) each install and build the framework and the Console from source, and the existing public image ghcr.io/objectstack-ai/objectstack (docker-publish.yml) is the runtime image, an npm install -g of a RELEASED @objectstack/cli, so it cannot serve a commit pin linked by path. The dispatch half breaks three ways: (1) GitHub offers workflow_dispatch only for a workflow file on the default branch, so nothing could be dispatched from this branch; (2) AGENTS.md Prime Directive 15 reserves workflow_dispatch of any publish-capable workflow to the maintainer; (3) the relay's workflow_dispatch op allows only one closed, fixed inputs object per file (WORKFLOW_DISPATCH_INPUTS in scripts/pm/fleet-write/ops.mjs), so it cannot carry a sha. Dry-run evidence is below instead, and the first dispatch is the maintainer's click after merge.",
      "summary": "New workflow .github/workflows/framework-build-base.yml and docker/framework-build-base/ (Dockerfile, Dockerfile.dockerignore, check-image.sh), plus one census row in scripts/pm/dispatch-gates.self-test.mjs for the workflow's no-check-families declaration. Image: ghcr.io/objectstack-ai/framework-build-base:SHA (full 40-hex framework commit), linux/amd64, one plain manifest (provenance and SBOM off). It is the framework stage of cloud's Dockerfiles with the same arguments (node:22-slim, pnpm 10.31.0, OS_SKIP_DTS=1 kept set, frozen-lockfile install with dev deps, typeless turbo build of everything but docs and ui/, typed Console build:dist with VITE_APP_VERSION = sha8 and the self-managed image's three VITE_SENTRY_* levers, ui/ removed), tree at /repo/objectstack. Triggers: workflow_dispatch (sha, rebuild) from main; repository_dispatch type framework-build-base with client_payload.sha (the hook card 11b can use); pull_request on its own paths = dry run, contents: read, builds the PR base commit with the PR Dockerfile, pushes nothing. publish (the only job with packages: write) refuses a sha that is not 40-hex or not on main (compare API ahead|identical), reports the digest and builds nothing when the tag exists (rebuild: true replaces), builds with the definition from the run's main and the requested commit as context (persist-credentials: false on both checkouts, .git excluded), pushes, logs out, pulls the digest anonymously, runs check-image.sh, and writes digest, build wall and a FROM IMAGE:SHA@DIGEST line to the job summary. How a digest is obtained: that summary; or docker buildx imagetools inspect ghcr.io/objectstack-ai/framework-build-base:SHA; or dispatching the same sha again (existing tag answers with its digest, no build).",
      "tests": "Dry run = this PR's own pull_request run 42464408854 (job 128680463190) at head f7f132a1, framework commit 4941c40b (PR base), cold (no cache): job 18m45s (08:47:26Z-09:06:11Z); free disk 2m06s; build step 15m25s: apt 17.2 s, pnpm install 33.4 s (+1528 packages), framework turbo build 82 tasks 0 cached 1m58s, Console turbo build:dist 74 tasks 0 cached 10m47s, load into runner 94 s; check-image.sh 8 s, all assertions passed: node=v22.23.4, pnpm=10.31.0, dist_dirs_under_packages=79, console_assets=2438, image_bytes=838630861 (docker image inspect .Size), no .git under /repo, ui/ gone, Console carries build identity 4941c40b, OS_SKIP_DTS=1. Heads 0f771853 and a54e5890 add only the workflow's no-check-families marker, the budget note citing this reading, and the census row; the dry run re-runs on a54e5890 (in_progress at report time). No ablation: workflow, Dockerfile and script are config (os-dev: not ablated).",
      "gates": "dispatch-gates --commands at a54e5890 (base b91dc73d): 47 derived (the census edit added 11 to the 36 first derived). All 46 direct commands exit 0 at a54e5890; check:pm-dispatch-gates exit 0 at a54e5890, fast tier 2205/2205 pass in 446 s. History: at f7f132a1 it was exit 1 locally and in CI (Lint · PM dispatch-gates, Lint & Repo Gates), 1 of 2205, 'every real paths-filtered workflow discovers a check family or declares why not (gaps: framework-build-base.yml)'; the no-check-families marker (0f771853) fixed that and tripped the named marker census (ten declarations, no others), whose row was added in a54e5890. CI on a54e5890: Lint · PM dispatch-gates success, Lint & Repo Gates success, 44 success, 12 skipped, 3 in_progress (Type Check UI, Test Core 1/8, the dry run) at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "3 — mcp__github__issue_read get + get_comments on #31441, mcp__github__pull_request_read get #31454 (reads only)",
      "api_writes": "2 relay strokes: pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/31454/assignees os-zhuang + POST /issues/31454/labels skip-changeset; run 42464387049, body read back identical 9318 bytes) and this os-dev-report comment (POST /issues/31441/comments); plus 2 git pushes (not REST)",
      "open_questions": [
        {
          "question": "Who runs the first dispatch after merge, and later ones?",
          "options": [
            "A Sam clicks Run workflow once on main with cloud's pin (98583cd692c6a67891617529d2f7aec4963859b8 today), then sets the ghcr package framework-build-base to Public (Package settings, Danger Zone; GitHub creates it private, no API changes it, irreversible). Later builds come from card 11b's repository_dispatch from cloud CI, which is automation, not a seat act.",
            "B A ruling lets seats dispatch this one workflow; it also needs a relay change, since WORKFLOW_DISPATCH_INPUTS allows only fixed inputs and this workflow takes a sha."
          ],
          "recommendation": "A, because it needs no rule or relay change, it is one click, and the visibility flip is a maintainer UI act either way."
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: cloud · noted, not filed · card 11b (cloud#3792) needs: cloud's apps/cloud and apps/objectos builders set npm_config_registry/COREPACK_NPM_REGISTRY to npmmirror as image ENV; this image sets no registry ENV, so a downstream that wants the mirror sets it after FROM. The base also keeps .gitignore (as the self-managed image does) and builds the Console with the self-managed image's Sentry levers for all three images."
      ],
      "deviations": "No Claim: line exists on #31441 (comments empty at start), so the branch check had nothing to compare; thread branch is platform-assigned. The two declaration lines are omitted from the PR body (no claim carried them; skip-changeset, nothing publishes to npm). The harness's post-PR reviewer request was not made (requesting review is the seat's hand-off). Commit trailers are AGENTS.md's model-free pair. PR body edits owed by the seat (dev does not PATCH): What changes should name the scripts/pm/dispatch-gates.self-test.mjs census row and the workflow's no-check-families marker; Tests should read 46 derived commands + check:pm-dispatch-gates 2205/2205 at a54e5890; the Budget note is now in the workflow (cold reading: build 15m25s, job 18m45s)."
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    repo:cloud#3 · os-zhuang · session_01QUs3BuMyARAhKn8scCUz3t

    os-dev-report addendum · 2026-11-08T15:52Z · first publish

    The card's Done-when now holds: one dispatch for a named commit ran, and the image pulls anonymously.

    • Who dispatched, and on what word. The maintainer, in this card's thread at 2026-11-08 15:28Z: 「你需要我做的事情,立一张维护者处理卡片,我让本地claude 做」, then 「或者你自己能做最好」. On that word the card thread ran workflow_dispatch of framework-build-base.yml on main (the relay's workflow_dispatch op cannot carry a sha, so this one write went through the session's GitHub tool as os-zhuang, not the relay). Run: https://github.com/objectstack-ai/objectstack/actions/runs/42495241133 (run 4, job 128776068568), conclusion success.
    • Commit. 3c380253ef8089deb11f2636635f1a59618a1873, cloud's .objectstack-sha on cloud main today (set by cloud#3812); the publish job's compare check answered it is on main.
    • Image. ghcr.io/objectstack-ai/framework-build-base:3c380253ef8089deb11f2636635f1a59618a1873
    • Digest. sha256:c427f82018f4f01f7f6c1079ad23ed4823e10239e3470cf29d5837519603d5a8 (one OCI image manifest, linux/amd64).
    • Pin line for cloud#3792. FROM ghcr.io/objectstack-ai/framework-build-base:3c380253ef8089deb11f2636635f1a59618a1873@sha256:c427f82018f4f01f7f6c1079ad23ed4823e10239e3470cf29d5837519603d5a8
    • Timings. Build and push 955 s (15m55s, 15:33:58Z to 15:49:53Z); job 19m24s (15:31:36Z to 15:51:00Z), of which runner disk cleanup 1m45s and the anonymous pull plus check 40 s.
    • Anonymous read. After docker logout ghcr.io the job pulled the digest and ran check-image.sh: node=v22.23.4, pnpm=10.31.0, dist_dirs_under_packages=79, console_assets=2439, image_bytes=839655303, no .git under /repo, ui/ gone, Console carries build identity 3c380253, OS_SKIP_DTS=1. Re-read from outside GitHub Actions: an anonymous ghcr.io token and a HEAD of the tag's manifest answered 200 with the same digest.
    • Premise correction. The report said GitHub would create the package private and the maintainer would have to set it Public. Measured: the package was publicly readable on its first push, so no visibility step and no maintainer card are needed.
    • Later digests. Dispatch the same commit again (an existing tag answers with its digest and builds nothing), or docker buildx imagetools inspect ghcr.io/objectstack-ai/framework-build-base:<sha>.

    Owed by the seat: close this card through pm-dispatch, and send seat 2's mailbox (objectstack#31364) Notify: landed objectstack#31441 with the image, digest and pin line above, so cloud#3792 can start.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    repo:cloud#3 · os-zhuang · session_01QUs3BvRcDHXqRU4TSVE4u6

    Landed: #31441 · 2026-11-08T15:54Z

    Done-when holds. Seat 3 checked it independently:

    Next: cloud#3792 consumes this image. Seat 2 has been told.

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

Metadata

Metadata

Assignees

Labels

domain:cloudTouches cloud: the whole card is the cloud PM's (repo:cloud seat); no objectstack lane claims itpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions