edit | blame | history | raw

MEXP14 QA-EDC-02 外部分发候选验证

日期:2026-07-06
项目:Mindraw
角色:QA

用户目标

PMO 补派 QA-EDC-02,要求在两个 Review Gate 已回写代码复核层面 PASS 后,按 QA-EDC-01 计划尽可能执行 MEXP14 外部分发候选验证。

限制:

  • 不改源码、需求、设计、App/plugin 产物或发布资料。
  • 不替代码审核员、PMO Gate、运营或用户验收下结论。
  • 真实 fresh machine 优先;没有真实 fresh machine 时,只能把 clean profile 结果标成 fallback,不能冒充跨机器验证。

已完成事项

  • 读取并遵守项目入口和 QA 规则:AGENTS.mdINDEX.md02-P/plan-progress.markdown MEXP14 计划项、QA-EDC-01 计划/阻塞 JSON、App 候选证据、plugin 候选证据、两个 Review Gate PASS 行。
  • 复核 App candidate 1.2.3 / Build202607061556
  • SHA256 与记录一致。
  • release-manifest.json 显示 mexp14-external-distribution-candidate-not-formal-release-not-notarized-installer
  • hdiutil verify 通过。
  • DMG 只读挂载后包含 Mindraw.appApplications link。
  • Info.plist 中 bundleId=com.mindraw.desktop、version 1.2.3、build Build202607061556mindraw:// scheme、.mindraw / .excalidraw document types 均可见。
  • codesign --verify --deep --strict 通过,但签名为 ad-hoc、无 TeamIdentifier。
  • spctl 对 DMG 和 mounted App 都返回 rejected,符合未签名 / 未 notarized 边界,但会阻塞普通外部安装。
  • 复核 plugin candidate:
  • SHA256SUMS.txt 全部 OK。
  • tarball SHA256 为 ee06e91a866049b6a8062367f77fc659aa3c3c9f5638f7b0c2b61ad8e14aa2f1
  • marketplace 名称为 mindraw-mexp14-edc-20260706154843
  • 解包后 validator、npm run check、lifecycle / HTTP / MCP smoke 均通过。
  • SkillSpector skill directory 为 SAFE;plugin root 仍为 CAUTION,命中 scripts/mindraw-canvas-service.mjs:4,按 crg-ce3b411d6cca=PASS 只视为代码复核层面已接受风险。
  • 执行 clean Codex CLI profile fallback:
  • 临时 profile 初始无 marketplace/plugin。
  • 从 candidate root 和 tarball extract 两条路径都能 codex plugin marketplace add + codex plugin add
  • codex plugin list 可见 mindraw@mindraw-mexp14-edc-20260706154843
  • installed cache 的 validator 与 npm run check 通过。
  • clean CLI profile 中 remove plugin / remove marketplace 成功,回到无 marketplace/plugin。
  • 当前 warmed-up profile 未留下 MEXP14 candidate 安装,只保留 mindraw@personal

关键决策

  • QA-EDC-02 结果写为 PARTIAL,不写 QA PASS。
  • Clean Codex CLI profile 只能证明候选安装源可被隔离 CLI profile 识别、安装、校验和移除;不能证明 Codex Desktop plugin 可见、sidebar GUI、App foreground、真实保存刷新或跨机器可用。
  • 未执行 /Applications 安装、App first launch 和 App rollback,以避免覆盖当前机器状态;这些必须在 fresh machine 或 clean macOS user 上执行。
  • spctl rejected 不是本轮 QA 误差,而是候选本身 ad-hoc / unsigned / not-notarized 的外部分发风险,需要 PMO/OPS 明确是否允许进入外部用户复验。

文件变更

  • 新增:02-P/MEXP14-ExternalDistributionCandidate/qa/qa-edc-02-external-distribution-check-20260706.md
  • 新增:02-P/MEXP14-ExternalDistributionCandidate/qa/qa-edc-02-external-distribution-check-20260706.json
  • 更新:02-P/plan-progress.markdown
  • MEXP14 状态更新为 Active / QA-EDC-02 reported PARTIAL / not formal release
  • QA-EDC-02 任务卡标记为已执行,结果 PARTIAL
  • Progress Log 追加 QA-EDC-02 证据和剩余缺口。
  • 更新:INDEX.md
  • 登记 QA-EDC-02 报告和 JSON 证据路径。

核心事实 / 变更快照

  • 变更对象:MEXP14 P-20260706-external-distribution-candidate 的 QA-EDC-02 状态。
  • 事实来源:
  • 02-P/plan-progress.markdown
  • 02-P/MEXP14-ExternalDistributionCandidate/qa/qa-edc-02-external-distribution-check-20260706.md
  • 02-P/MEXP14-ExternalDistributionCandidate/qa/qa-edc-02-external-distribution-check-20260706.json
  • 变更前:
  • QA-EDC-02 已派发,状态为 in progress。
  • QA-EDC-01 只产出计划和阻塞记录。
  • 变更后:
  • QA-EDC-02 已执行可运行范围验证。
  • 结果为 PARTIAL
  • PM_NOTIFY_READY=yes 表示 partial evidence 可供 PMO 收敛,不代表 QA PASS、PMO Gate、正式发布或用户验收。
  • 已覆盖:
  • App SHA、manifest、DMG verify、只读挂载、metadata、URL scheme、document types、codesign、doctor metadata check、Gatekeeper 表达。
  • Plugin SHA、tarball、marketplace、validator、npm run check、lifecycle / HTTP / MCP smoke、SkillSpector、clean Codex CLI profile install/list/remove。
  • 未覆盖:
  • 真实 fresh machine。
  • clean macOS user。
  • clean Codex Desktop GUI profile。
  • 新机器 /Applications 安装和首次启动。
  • 真实 App 编辑保存后 sidebar 刷新。
  • App rollback。
  • 外部机器 plugin rollback baseline。

可复用命令 / Runbook

用途:复跑 MEXP14 QA-EDC-02 的 App artifact、plugin package 和 clean Codex CLI profile fallback 验证。

前置条件:

  • /Users/ar/Projects/Mindraw 项目根运行。
  • App candidate 已存在于 03-O/C2.builds/releases/Build202607061556/
  • Plugin candidate 已存在于 P2.mindrawforcodex/03-O/C2.builds/MEXP14-ExternalDistributionCandidate/mindraw-plugin-0.1.0+codex.20260704090518-EDC20260706154843/

App candidate artifact / Gatekeeper 表达:

DMG=/Users/ar/Projects/Mindraw/03-O/C2.builds/releases/Build202607061556/Mindraw_1.2.3_aarch64-Build202607061556.dmg
MANIFEST=/Users/ar/Projects/Mindraw/03-O/C2.builds/releases/Build202607061556/release-manifest.json
BUILD_INFO=/Users/ar/Projects/Mindraw/03-O/C2.builds/releases/Build202607061556/build-info.txt
shasum -a 256 "$DMG" "$MANIFEST" "$BUILD_INFO"
jq '{version,buildLabel,releaseClass,packageType,source,artifacts,signing,notarization,validation}' "$MANIFEST"
hdiutil verify "$DMG"
MP=/tmp/mindraw-qa-edc-02-mount-$$
mkdir -p "$MP"
hdiutil attach -nobrowse -readonly -mountpoint "$MP" "$DMG"
/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$MP/Mindraw.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$MP/Mindraw.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$MP/Mindraw.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c 'Print :CFBundleURLTypes' "$MP/Mindraw.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c 'Print :CFBundleDocumentTypes' "$MP/Mindraw.app/Contents/Info.plist"
codesign --verify --deep --strict --verbose=2 "$MP/Mindraw.app"
codesign -dv --verbose=4 "$MP/Mindraw.app"
spctl --assess --type open --verbose=4 "$DMG"
spctl --assess --type execute --verbose=4 "$MP/Mindraw.app"
npm run doctor:mindraw -- --app "$MP/Mindraw.app" --pretty
hdiutil detach "$MP"

Plugin candidate package validation:

CANDIDATE_ROOT=/Users/ar/Projects/Mindraw/P2.mindrawforcodex/03-O/C2.builds/MEXP14-ExternalDistributionCandidate/mindraw-plugin-0.1.0+codex.20260704090518-EDC20260706154843
cd "$CANDIDATE_ROOT" && shasum -a 256 -c SHA256SUMS.txt
TARBALL="$CANDIDATE_ROOT/plugin/mindraw-plugin-0.1.0+codex.20260704090518-EDC20260706154843.tar.gz"
shasum -a 256 "$TARBALL"
TMPDIR=$(mktemp -d /tmp/mindraw-qa-edc-02-plugin.XXXXXX)
tar -xzf "$TARBALL" -C "$TMPDIR"
jq -r '.name' "$TMPDIR/install-source/.agents/plugins/marketplace.json"
PYTHONPATH=/tmp/mindraw-pyyaml python3 /Users/ar/.codex/skills/.system/plugin-creator/scripts/validate_plugin.py "$TMPDIR/install-source/plugins/mindraw"
npm run --prefix "$TMPDIR/install-source/plugins/mindraw" check
node "$TMPDIR/install-source/plugins/mindraw/scripts/mindraw-canvas-service.mjs" smoke-lifecycle
node "$TMPDIR/install-source/plugins/mindraw/scripts/mindraw-canvas-service.mjs" smoke-http
node "$TMPDIR/install-source/plugins/mindraw/scripts/mindraw-canvas-service.mjs" smoke-mcp
skillspector scan "$TMPDIR/install-source/plugins/mindraw/skills/mindraw-open-canvas" --no-llm
skillspector scan "$TMPDIR/install-source/plugins/mindraw" --no-llm

Clean Codex CLI profile install / remove fallback:

CANDIDATE_ROOT=/Users/ar/Projects/Mindraw/P2.mindrawforcodex/03-O/C2.builds/MEXP14-ExternalDistributionCandidate/mindraw-plugin-0.1.0+codex.20260704090518-EDC20260706154843
CLEAN_ROOT=$(mktemp -d /tmp/mindraw-qa-edc-02-clean-profile.XXXXXX)
export HOME="$CLEAN_ROOT/home"
export CODEX_HOME="$CLEAN_ROOT/codex-home"
export AGENTS_HOME="$CLEAN_ROOT/agents-home"
export XDG_CACHE_HOME="$CLEAN_ROOT/xdg-cache"
export XDG_CONFIG_HOME="$CLEAN_ROOT/xdg-config"
mkdir -p "$HOME" "$CODEX_HOME" "$AGENTS_HOME" "$XDG_CACHE_HOME" "$XDG_CONFIG_HOME"
codex plugin marketplace list
codex plugin list
codex plugin marketplace add "$CANDIDATE_ROOT/plugin/install-source"
codex plugin add mindraw@mindraw-mexp14-edc-20260706154843
codex plugin list
codex plugin remove mindraw@mindraw-mexp14-edc-20260706154843
codex plugin marketplace remove mindraw-mexp14-edc-20260706154843
codex plugin marketplace list
codex plugin list

验证结果判定:

  • App SHA / manifest / hdiutil verify / mounted metadata / codesign --verify 应通过。
  • spctl rejected 是当前候选的已知 Gatekeeper 风险,不应写成通过。
  • Plugin validator / npm run check / smoke 应通过。
  • Skill directory SkillSpector 应为 SAFE;plugin root 仍会是 CAUTION,需保留 review risk note。
  • Clean CLI profile install/remove 通过仍不能替代 Codex Desktop clean profile。

搜索关键词:QA-EDC-02Build202607061556mindraw-mexp14-edc-20260706154843spctl rejectedclean Codex CLI profilePARTIAL

未决问题

  • PMO 需要判断下一状态是 BLOCKED_PENDING_FRESH_MACHINE,还是带明确 Gatekeeper / rollback 风险的外部用户复验。
  • OPS 需要把实际 App/plugin 候选值补进 distribution kit,并补外部机器可用的 plugin rollback baseline 或 remove-only 策略。
  • QA / PMO 仍需真实 fresh Mac 或 clean macOS user 验证:App 安装启动、Codex Desktop plugin 可见、sidebar preview、编辑/双击进入 App、真实保存后 sidebar 刷新或 fail-closed、重启恢复、rollback。

后续建议

  • 不要把 clean CLI profile fallback 写成 fresh machine pass。
  • 如果允许外部用户继续试未 notarized 包,必须在测试说明里明确 Gatekeeper 风险、预期阻断和停止/回报路径。
  • 如果目标是正式外部分发而非受邀候选,应补 Developer ID signing / notarization,再重新跑 QA。