feat(release): unify Desktop and CLI product releases - #3222
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
Included review availability: Your plan provides up to 3 included reviews per hour; 0 remain after this review. 📝 WalkthroughWhat this PR solvesThis PR creates one release path for Desktop and standalone macOS arm64 CLI/TUI products. It uses the root npm remains an optional staged channel. It does not create another tag or GitHub Release. Source of truth and solution scopeThe PR extends the existing product release source of truth. It does not create a parallel product release path. The root product version, product tag, source commit, release identity utility, manifest-based packaging policies, and single Draft GitHub Release now control Desktop, CLI/TUI, source, and npm artifacts. The separate Desktop workflow and CLI-specific tag and release behavior were removed. The solution is the smallest coherent path shown by the current diff. The added workflow, packaging, validation, signing, notarization, recovery, and test logic supports immutable source selection, workspace dependency closure, native artifact filtering, npm staging, and Draft Release safety. Simplification opportunitiesNo safe deletion is evident from the supplied change summary. The PR removes duplicated behavior by deleting the Desktop-only workflow, CLI-specific release metadata, the The packaging and verification scripts are large. The current evidence does not show that further deletion or simplification would preserve behavior and regression coverage. Concrete risks and validationKey risks include:
Reported validation covered release checks, formatting, workflow linting, CLI packaging, CLI smoke tests, workspace tests, the Desktop build, and a packaged macOS arm64 CLI/TUI ZIP. Developer ID signing, notarization, protected-environment approval, npm staging, and browser-download acceptance were not run locally because they require release credentials or human operators. Required-check status remains unverified without direct check results. Complexity deltaAdded
Removed
The PR adds implementation and test-maintenance complexity. It removes duplicated release authorities and parallel release states. Total maintenance complexity decreases at the release-model level. The added complexity is justified by the standalone artifact, security, provenance, and recovery requirements. Optional follow-up simplifications are non-blocking. Review-relevant risksThe diff affects protected areas:
Material changes in these areas require independent human review under repository policy. The person performing the merge must review the final diff. A maintainer makes the final determination. WalkthroughThe release system now uses one product identity and source commit for desktop, CLI/TUI, npm, and source artifacts. It adds macOS arm64 packaging and verification, unified draft-release creation, product-tagged npm staging, and updated CLI distribution contracts. ChangesProduct release pipeline
Estimated code review effort: 5 (Critical) | ~120 minutes Merge Risk: 🟡 Moderate · up to The unified release changes the publication and acceptance contract, but the current checklist still omits verification of the required Windows Desktop ZIP. Merge should wait for that checklist correction or explicit owner acceptance because a required download artifact could otherwise go unverified. Sequence Diagram(s)sequenceDiagram
participant ReleaseDispatcher
participant ReleaseIdentity
participant ArtifactJobs
participant ArtifactVerifier
participant GitHubDraftRelease
ReleaseDispatcher->>ReleaseIdentity: resolve product version and source commit
ReleaseIdentity->>ArtifactJobs: provide tag, commit, and toolchain metadata
ArtifactJobs->>ArtifactVerifier: provide desktop, CLI/TUI, and source artifacts
ArtifactVerifier->>GitHubDraftRelease: upload verified assets and checksums
GitHubDraftRelease-->>ReleaseDispatcher: create or update draft release
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
5789994 to
55e7055
Compare
PR Summary by QodoUnify Desktop, standalone CLI, and npm release identity
AI Description
Diagram
High-Level Assessment
Files changed (35)
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (6)
scripts/verify-macos-arm64-cli.mjs (1)
207-225: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueImport
realpathat the top of the file and delete the inline dynamic imports.Lines 216-219 and Lines 342-347 call
import('node:fs/promises')four times only to obtainrealpath. The file already imports named members fromnode:fs/promisesat Line 4-14. Addingrealpaththere removes four dynamic imports with no behavior change.Disposition: optional.
♻️ Proposed simplification
readFile, readdir, + realpath, rm,- const [resolvedLink, resolvedPackage] = await Promise.all([ - import('node:fs/promises').then(({ realpath }) => realpath(linkPath)), - import('node:fs/promises').then(({ realpath }) => realpath(packagePath)), - ]); + const [resolvedLink, resolvedPackage] = await Promise.all([ + realpath(linkPath), + realpath(packagePath), + ]);As per path instructions: "Flag concrete cases where code can be deleted or simplified."
Source: Path instructions
scripts/product-release.test.mjs (2)
206-225: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThis assertion is a change detector for the Eval manifest.
workspaceReleaseFilesreads the declaration frompackages/eval/package.json. The test then compares it against a hand-copied duplicate of that same list. Any harbor asset added or renamed breaks this test even though no behavior changed, and the fix is always to re-copy the manifest.The stated contract is "the Eval workspace owns the complete runtime asset declaration". Assert that property instead:
distis present, every entry is a real path under the workspace, and no development directory leaks in. That still fails when the declaration is wrong and stops failing when the declaration merely grows.As per path instructions: "Flag tests that duplicate existing coverage, assert implementation details, or do not protect observable behavior."
Source: Path instructions
200-203: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLine 201 pins shell syntax, not the relocatability contract.
/while \[ -L "\$launcher" \]/ufails if the wrapper resolves symlinks with any other correct construct. The two following assertions are different: they pin the embedded runtime path and the CLI entry, which are contract. The symlink behavior itself is already covered by the acceptance step in.github/RELEASE_CHECKLIST.mdline 72 and byverify-macos-arm64-cli.mjs.Consider dropping Line 201 or replacing it with an assertion that the wrapper never references an absolute build-time path.
As per path instructions: "Flag tests that duplicate existing coverage, assert implementation details, or do not protect observable behavior."
Source: Path instructions
.github/workflows/release-cli-stage.yml (1)
40-54: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe commit assertion at Line 52 cannot fail.
git rev-list -n 1 FETCH_HEADandgit rev-parse "FETCH_HEAD^{commit}"both peel to the same commit. The comparison is always true, so it adds no protection against an annotated tag or a non-commit target.Delete the redundant line, or replace it with a check that actually constrains the target.
As per path instructions: "Flag concrete cases where code can be deleted or simplified."
♻️ Proposed simplification
git fetch --no-tags origin "refs/tags/$PRODUCT_TAG" source_commit="$(git rev-list -n 1 FETCH_HEAD)" - test "$(git rev-parse "FETCH_HEAD^{commit}")" = "$source_commit" echo "source_commit=$source_commit" >> "$GITHUB_OUTPUT"Source: Path instructions
scripts/release-cli-publication.test.mjs (1)
82-94: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd negative coverage for the new
productTagguard.
prepareStageReleasenow rejects aproductTagthat does not equalv<version>. The tests only exercise the matching value. The drift tests cover version confirmation and checksum drift, but not tag drift.Add one assertion that a mismatched
productTagthrows.scripts/release-cli-workflow-policy.test.mjs (1)
62-63: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLine 63 duplicates the invariant already covered by Line 62.
Line 62 asserts the workflow delegates version validation to
scripts/release-version.mjs. Line 63 additionally asserts that no inline bash regex comparesEXPECTED_VERSION. That second assertion matches on incidental text shape and breaks if the step is reformatted, without protecting extra observable behavior.Consider removing Line 63.
As per path instructions: "Flag tests that duplicate existing coverage, assert implementation details, or do not protect observable behavior."
Source: Path instructions
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 53dae729-1ce9-4711-9e7c-6a49a45fa7e9
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (35)
.github/RELEASE_CHECKLIST.md.github/workflows/ci.yml.github/workflows/cli-package-validation.yml.github/workflows/release-cli-finalize.yml.github/workflows/release-cli-stage.yml.github/workflows/release-desktop.yml.github/workflows/release.ymldocs/README.mddocs/cli-distribution.mddocs/cli-npm-release.mddocs/cli-npm-release.zh-CN.mddocs/runtime-host-remote-access.mddocs/runtime-host-remote-access.zh-CN.mdpackage.jsonpackages/cli/README.mdpackages/cli/README.zh-CN.mdpackages/cli/package.jsonpackages/cli/src/__tests__/cli.test.tspackages/cli/src/cli-core.tspackages/eval/package.jsonscripts/ci-test-plan.mjsscripts/package-macos-arm64-cli.mjsscripts/product-release-identity.mjsscripts/product-release-tag.mjsscripts/product-release.test.mjsscripts/release-cli-file-policy.mjsscripts/release-cli-file-policy.test.mjsscripts/release-cli-package.mjsscripts/release-cli-publication.mjsscripts/release-cli-publication.test.mjsscripts/release-cli-workflow-policy.test.mjsscripts/release-eval-smoke-sitecustomize.pyscripts/release-version.mjsscripts/smoke-release-cli-package.mjsscripts/verify-macos-arm64-cli.mjs
💤 Files with no reviewable changes (3)
- scripts/smoke-release-cli-package.mjs
- packages/cli/src/cli-core.ts
- .github/workflows/release-desktop.yml
Included review availability: Your plan provides up to 3 included reviews per hour; 2 remain after this review.
f7e8ac9 to
caa339a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 28261e16-0e19-4033-9efb-a3ccd733d89c
📒 Files selected for processing (18)
.github/RELEASE_CHECKLIST.md.github/workflows/release-cli-finalize.yml.github/workflows/release-cli-stage.yml.github/workflows/release.ymldocs/cli-distribution.mddocs/cli-npm-release.mddocs/cli-npm-release.zh-CN.mdscripts/package-macos-arm64-cli.mjsscripts/product-release-identity.mjsscripts/product-release.test.mjsscripts/release-checksum.mjsscripts/release-cli-file-policy.mjsscripts/release-cli-file-policy.test.mjsscripts/release-cli-package.mjsscripts/release-cli-publication.mjsscripts/release-cli-publication.test.mjsscripts/release-cli-workflow-policy.test.mjsscripts/verify-macos-arm64-cli.mjs
Included review availability: Your plan provides up to 3 included reviews per hour; 0 remain after this review.
3ff0afb to
a395694
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
package.json (1)
55-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse
test:product-releaseincheck:release.Line 55 and Line 58 both define the
scripts/product-release.test.mjsinvocation. Usenpm run test:product-releaseincheck:releaseso the test command has one source of truth.Disposition: optional.
As per path instructions, consolidate duplicated authority and prefer the closest existing seam.
Source: Path instructions
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 3468f886-510c-49cc-b6e1-d05de8143930
📒 Files selected for processing (5)
.github/RELEASE_CHECKLIST.mddocs/cli-npm-release.mddocs/cli-npm-release.zh-CN.mdpackage.jsonscripts/smoke-release-cli-package.mjs
Included review availability: Your plan provides up to 3 included reviews per hour; 1 remains after this review.
ba1f50d to
0275809
Compare
22bc643 to
0c0e939
Compare
|
@coderabbitai review |
|
/agentic_review |
Make the root product version, one main commit, one tag, and one draft GitHub Release authoritative for Desktop, the standalone macOS arm64 CLI/TUI, and bundled source. Keep the staged OIDC npm workflow as a verified install channel without a competing tag or release. Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
0c0e939 to
929f2a1
Compare
M4n5ter
left a comment
There was a problem hiding this comment.
English
Requesting changes. The overall one-version/one-tag/one-Draft design is coherent, but the current implementation is not release-ready:
- formal CLI re-signing drops the pinned Node runtime's entitlements;
- npm staging is guaranteed to reject the repository's current
apache/makaidentity, and the Trusted Publisher instructions are also stale; - the product release source is not bound to the IPMC-approved ASF source identity;
- release-authority changes do not actually select the release-contract CI gate;
- Apple signing verifies consistency, but not Maka's expected publisher Team ID.
The Windows package failure on this head is unrelated to this diff: it failed in the unchanged CDP readiness harness, the same symptom occurred on unrelated PRs today, and #3327 is already addressing that harness.
The simplify audit converged on the same two root reductions: remove the independent arbitrary-main product-source authority in favor of the approved ASF source identity, and remove the ineffective parallel CI routing concept by giving release-contract paths one real owner.
Reviewed at 929f2a134a58c5ff873b97f79e3c325e9ad93597. Focused publication/workflow-policy tests, file-policy tests, planner tests, and git diff --check passed. Developer ID signing, notarization, npm OIDC staging, and cross-machine artifact acceptance were not executed in this environment.
简体中文
请求修改。整体的单版本、单 tag、单 Draft 设计是连贯的,但当前实现还不能用于发布:
- 正式 CLI 重签名会丢失固定 Node runtime 的 entitlements;
- npm staging 必然拒绝当前仓库的
apache/makaidentity,Trusted Publisher 指南也仍是旧仓库; - product release source 没有绑定到获 IPMC 批准的 ASF source identity;
- release authority 变更实际上不会选择 release-contract CI gate;
- Apple 签名只验证内部一致性,没有验证 Maka 预期的 publisher Team ID。
当前 head 的 Windows package 失败与本 PR diff 无关:失败发生在未修改的 CDP readiness harness,同一天多个无关 PR 出现了相同症状,且已有 #3327 专门处理。
Simplify audit 收敛到相同的两个根因简化:删除独立的 arbitrary-main product-source authority,统一使用已批准的 ASF source identity;删除无效的并行 CI 路由概念,让所有 release-contract 路径只有一个真实 owner。
审查基于 929f2a134a58c5ff873b97f79e3c325e9ad93597。定向 publication/workflow-policy、file-policy、planner 测试以及 git diff --check 均通过。本环境未执行 Developer ID signing、notarization、npm OIDC staging 和跨机器 artifact acceptance。
| await run( | ||
| 'codesign', | ||
| [ | ||
| '--force', |
There was a problem hiding this comment.
English
[Blocking] Preserve Node's required entitlements when re-signing it
This loop force-replaces every Mach-O signature with hardened runtime, but passes neither --entitlements nor --preserve-metadata=entitlements. The pinned official Node v24.18.1 signs bin/node with tools/osx-entitlements.plist, including com.apple.security.cs.allow-jit; its official signing script applies that plist explicitly. Apple's re-signing guidance likewise requires entitlements to be preserved or reapplied.
The release-signing path therefore removes metadata that the official runtime deliberately carries, after the earlier validation has accepted it. The final verifier checks only signature validity, Team ID consistency, and hardened-runtime flags, so it cannot detect the loss. A development ZIP may work while the formally signed artifact contains a Node runtime without its required JIT authority.
Please handle the embedded Node executable separately: preserve or explicitly reapply its verified entitlements, then assert the post-signing entitlements in the final archive verifier. Node-specific entitlements should not be applied indiscriminately to every native dependency.
简体中文
[Blocking] 重签嵌入式 Node 时必须保留其必要 entitlements
这里用 hardened runtime 强制替换每个 Mach-O 的签名,却既没有传入 --entitlements,也没有使用 --preserve-metadata=entitlements。当前固定的官方 Node v24.18.1 会使用 tools/osx-entitlements.plist 签署 bin/node,其中包括 com.apple.security.cs.allow-jit;Node 的官方签名脚本也会显式应用该 plist。Apple 对重签名的指导同样要求显式保留或重新应用 entitlements。
因此,正式发布路径会在前面验证并接受官方 Node 后,移除其刻意携带的签名元数据。最终 verifier 只检查签名有效性、Team ID 一致性和 hardened-runtime flag,无法发现 entitlements 已丢失。开发 ZIP 可能正常,而正式签名的产物却包含缺少必要 JIT 权限的 Node runtime。
请单独处理嵌入式 Node:保留或显式重新应用已经验证的 entitlements,并在最终 archive verifier 中检查重签后的 entitlement。不要把 Node 专属 entitlement 无差别应用到所有 native dependency。
| if (productTag !== `v${identity.version}`) { | ||
| throw new Error(`Product tag ${productTag} does not match ${identity.version}`); | ||
| } | ||
| validateSourceIdentity({ |
There was a problem hiding this comment.
English
[Blocking] Bind npm publication to the current canonical repository
The live repository and Actions identity are now apache/maka, but this release boundary still requires maka-agent/maka-agent. Stage passes ${{ github.repository }} into prepareStageRelease, so every run in the current repository reaches validateSourceIdentity and fails with Release repository must be maka-agent/maka-agent before release.json is created or npm staging begins.
Fixing only the constant is insufficient: both npm runbooks still instruct operators to configure the Trusted Publisher as organization/repository maka-agent / maka-agent, while the OIDC claim will identify apache/maka. Please update the canonical identity, fixtures and provenance expectations, both runbooks, and the actual npm Trusted Publisher configuration to apache/maka. There is no need for an old-owner compatibility path.
简体中文
[Blocking] 将 npm 发布身份绑定到当前 canonical repository
当前实际仓库和 Actions identity 已经是 apache/maka,但这个发布边界仍强制要求 maka-agent/maka-agent。Stage 会把 ${{ github.repository }} 传给 prepareStageRelease,因此当前仓库中的每次运行都会在创建 release.json 或进入 npm staging 之前,由 validateSourceIdentity 抛出 Release repository must be maka-agent/maka-agent。
仅修改常量仍不完整:中英文 npm runbook 仍要求把 Trusted Publisher 配置成 organization/repository maka-agent / maka-agent,而实际 OIDC claim 会是 apache/maka。请将 canonical identity、测试 fixture、provenance expectation、中英文 runbook,以及 npm 控制面上的 Trusted Publisher 一并更新为 apache/maka。无需保留旧 owner 的兼容路径。
| - name: Check out the dispatched commit | ||
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| ref: ${{ inputs.source_commit || github.sha }} |
There was a problem hiding this comment.
English
[Blocking] Derive product releases from the approved ASF source identity
Current main now defines the ASF release authority in .github/ASF_SOURCE_RELEASE.md: Desktop and npm convenience artifacts must be built from the exact IPMC-approved source release. This workflow instead treats the dispatch-time main SHA as an independent product source and accepts an explicit historical SHA only after a product tag already exists for Draft recovery.
That creates two release authorities and also makes the supported flow impossible when main advances during the required ASF vote: the approved RC commit can no longer be selected for an initial product release. More importantly, neither this workflow nor the publication checklist prevents publishing convenience artifacts from a different, unapproved commit.
Please make the approved ASF RC commit/tag the sole product source authority. The product v<version> tag may remain as a convenience alias, but it must resolve to that same commit. The checklist should require the completed ASF votes before publication, and workflow contracts should reject an arbitrary main commit. This also removes the implicit requirement to keep two independently selected source identities synchronized by hand.
简体中文
[Blocking] 产品发布必须派生自已批准的 ASF source identity
当前 main 已在 .github/ASF_SOURCE_RELEASE.md 中定义 ASF 发布权威:Desktop 和 npm convenience artifacts 必须来自获 IPMC 批准的同一个精确 source release。这个 workflow 却把 dispatch 时的 main SHA 当作独立的产品 source;历史 SHA 只有在 product tag 已存在、用于 Draft recovery 时才允许传入。
这形成了两套 release authority,并且当 ASF 投票期间 main 前进后,受支持的流程无法再从已批准的 RC commit 创建首次 product release。更关键的是,当前 workflow 和 publication checklist 都不能阻止从另一个未经批准的 commit 发布 convenience artifacts。
请把已批准 ASF RC 的 commit/tag 作为唯一 product source authority。产品 v<version> tag 可以继续作为 convenience alias,但必须指向同一 commit。Checklist 应在 publication 前要求 ASF 投票已经完成,workflow contract 应拒绝任意 main commit。这样也能删除依靠人工保持两套 source identity 同步的隐式要求。
| code = true; | ||
| continue; | ||
| } | ||
| if (RELEASE_CONTRACT_FILES.has(path)) { |
There was a problem hiding this comment.
English
[Important] Make release-authority files actually select the release-contract gate
RELEASE_CONTRACT_FILES only sets code = true, while CI runs npm run check:release exclusively when cli_package == true. A directed planner probe returns cliPackage: false for release.yml, all three CLI release workflows, the new product identity/tag scripts, the standalone packager/verifier, checksum helpers, and even product-release.test.mjs.
Consequently, future changes can break these release workflows or their own contract tests while CI remains green. The existing test named “product workflow changes select the release contracts in CI” only asserts code === true, so it preserves the gap.
Please consolidate these paths into the classifier that actually owns the release gate—or introduce a dedicated release_contract output—and test that every release authority, implementation, and contract-test path really triggers npm run check:release. The separate RELEASE_CONTRACT_FILES branch can then be deleted.
简体中文
[Important] Release authority 文件必须真正选择 release-contract gate
RELEASE_CONTRACT_FILES 只会设置 code = true,而 CI 仅在 cli_package == true 时运行 npm run check:release。定向执行 planner 后,release.yml、另外三个 CLI release workflow、新增的 product identity/tag 脚本、standalone packager/verifier、checksum helper,甚至 product-release.test.mjs 本身得到的都是 cliPackage: false。
因此,后续修改可以破坏这些发布 workflow 或它们自己的 contract test,而 CI 仍保持绿色。现有名为 “product workflow changes select the release contracts in CI” 的测试只断言 code === true,恰好掩盖了这个缺口。
请将这些路径合并到真正拥有 release gate 的 classifier,或者增加独立的 release_contract output,并测试每个 release authority、实现和 contract-test 路径确实会触发 npm run check:release。随后可以删除单独但无效的 RELEASE_CONTRACT_FILES 分支。
| export function parseDeveloperIdApplicationIdentity(output) { | ||
| const identities = [...output.matchAll(/^\s*\d+\)\s+([0-9A-Fa-f]{40})\s+"([^"]+)"\s*$/gmu)] | ||
| .map((match) => ({ hash: match[1].toUpperCase(), name: match[2] })) | ||
| .filter(({ name }) => name.startsWith('Developer ID Application:')); |
There was a problem hiding this comment.
English
[Important] Verify Maka's expected Apple publisher identity
This accepts any valid Developer ID Application certificate. The final verifier then derives the expected TeamIdentifier from the first binary and only checks that every other binary uses the same team. A coherent but incorrect credential bundle—for example, a certificate and notarization credentials belonging to another Apple Developer team—would therefore pass signing, notarization, codesign, spctl, and final verification while publishing Maka under the wrong publisher identity.
Please pin the expected TeamIdentifier in reviewable product-release configuration, verify it immediately after importing the certificate and again from every binary in the final extracted ZIP, and record/report it in RELEASE.json or the acceptance evidence. The expected authority should not be derived from the artifact being verified.
简体中文
[Important] 验证 Maka 预期的 Apple publisher identity
这里会接受任意有效的 Developer ID Application certificate。最终 verifier 又从第一个 binary 自举 expected TeamIdentifier,只检查其他 binary 是否来自同一个 team。因此,一整套有效但错误的凭据——例如属于另一个 Apple Developer team 的证书和配套 notarization credentials——仍能通过 signing、notarization、codesign、spctl 和最终验证,却会把 Maka 发布成错误的 publisher identity。
请在可 review 的 product-release 配置中固定预期 TeamIdentifier,在导入证书后立即验证,并从最终 ZIP 解压出的每个 binary 再次验证;同时将其记录或输出到 RELEASE.json 或 acceptance evidence。预期 authority 不应从待验证 artifact 自身推导。
Summary
main: rootpackage.jsonis the sole version authority, and one main commit,v<version>tag, release gate, and Draft GitHub Release cover Desktop, the standalone macOS arm64 CLI/TUI, and bundled source.gh release create --verify-tag; interrupted Draft uploads keep byte-identical assets, add only missing assets, and fail on conflicts or extras. npm staging is dispatched from the existing product tag, so its workflow ref, source, run record, and npm provenance identify one commit; Finalize rechecks the live tag, Release, andmainancestry.releaseFiles, development-file pruning, notices, current Eval assets, dependency patches, and caller-independent npm configuration. npm retains its OIDC staged-publishing and 2FA boundaries as an optional installation channel, without another tag or Release.makacommand, Developer ID/notarization hooks,DISCLAIMER-WIP, checksums, and end-to-end verification. This supersedes feat(release): add synchronized macOS arm64 CLI artifact #3002 and incorporates or explicitly adjudicates every unresolved review thread there.Fixes #1510
Verification
npm run check:release— stale-dist and notice checks plus 53 focused release/publication contractsnpm run format:checkactionlint .github/workflows/release.yml .github/workflows/release-cli-stage.yml .github/workflows/release-cli-finalize.yml .github/workflows/cli-package-validation.ymlnpm run release:cli:pack— clean committed-source archive pathnpm run release:cli:smokenpm --workspace maka-agent test— 286 passed after rebasing the managed Runtime Host setup from currentmainnpm --workspace @maka/desktop run buildMaka-0.1.11-cli-mac-arm64.zipon macOS arm64 with pinned Node 24.18.1/npm 11.19.0. Verification covered relocation, embedded runtime/native closure, shared file policy,DISCLAIMER-WIP, notices, CLI and Eval smoke, and PTY TUI startup. SHA-256:81ba9f3259411f09f2bf520e715683c1979d56dc1336fbb7861caa62ca5b356c.Release review required
v0.1.11already exists. A future release preparation must bump root, Desktop, and CLI manifests together to one unused product version.AI use
Select exactly one:
Tool(s) and scope: Codex reconstructed the release architecture from current
mainand public decisions, implemented code/workflows/tests/docs, ran local verification, and prepared this PR. Claude provided an adversarial review; Codex independently adjudicated its findings. Material commits carryGenerated-by: Codextrailers.Checklist
Does this PR entail a change in behavior?