feat: add creator workbench release-gate evidence#5846
Draft
rgd451 wants to merge 127 commits into
Draft
Conversation
added 30 commits
June 30, 2026 18:00
- Split TasksView 99-test single file into 5 isolated files (page/creator-content/release/performance/release-schedule, 99 tests total) sharing tasks-view-test-helpers.ts; each file uses jsdom env with afterEach cleanup (cleanup + restore fetch/confirm + restoreAllMocks + useRealTimers) to stop cross-test memory accumulation. - Fix creator content selector multi-match with findAllByText/getAllByText. - packaged: extract platform-agnostic isPackagedDataDirAbsolute(value, platform=process.platform) so tests assert behavior explicitly per platform instead of mocking process.platform (which is bound at load on Windows). - packaged: make desktop-project-root-gate symlink tests capability-aware (skip when directory symlink privilege is unavailable, e.g. Windows without developer mode); non-symlink assertions always run. - docs: add CW-07B acceptance report. Red lines honored: no app src/daemon/contracts/dep/lockfile changes, no real API/.od/assets, no merge/push.
Root cause: TasksView's `refresh` useCallback depended on `entryProjects` by reference identity. When the caller omits the prop, the default `[]` is a fresh array literal every render, so `refresh` was a new function each render and the mount effect `useEffect(() => void refresh(), [refresh])` re-ran on every render, producing an unbounded refresh loop. On the Automations surface this ran in the background, but switching to the heavy Creator workbench dashboard made the continuous re-renders peg CPU and never settle, so the dashboard never appeared (timeout / OOM). Fix (minimal, app-layer only): read the latest `entryProjects` through a ref and key the `refresh` callback on a stable `entryProjectKey` (joined project ids) instead of the array identity. `refresh` now runs once per distinct project set; surface switches trigger no extra fetch, and project-set changes still re-fetch. - TasksView.tsx: `entryProjectsRef` + `entryProjectKey`; `refresh` reads `entryProjectsRef.current` and depends on `[entryProjectKey]`; 5 internal `entryProjects.map` calls use the local `projects` binding. - TasksView.page.test.tsx: add zero-project surface-switch stability regression (default Automations, stable creator-dashboard within 10s, stable switch back, bounded fetch count, no "Maximum update depth"). 99 -> 100 TasksView tests. - docs: CW-07C acceptance report. Red lines honored: no daemon/contracts/dep/lockfile changes, no real API/.od/ assets, no merge/push.
Add strict, versioned DTOs for the Creator local backup/restore feature in packages/contracts (creator-backup.ts) and document the research basis (electron/tauri/AppFlowy/app_backup_restore) in docs/plans/CW-08-creator-backup-recovery-research.md. Contracts cover: CreatorBackupManifest, CreatorBackupFile, CreatorBackupSummary, CreatorBackupValidationResult, CreatorBackupOperationResult, plus the daemon list/create/validate request/response and the packaged main-process restore capability request/response. Restore is intentionally NOT a daemon HTTP route; it is a packaged desktop capability keyed only by backup id (paths are always derived server-side). No runtime filesystem logic is added to the contracts package. Red lines honored: no daemon/packaged/web source changes here, no real .od or asset access, no cloud/third-party APIs.
Implement desktop main-process orchestrated restore for Creator backups,
keyed solely by backupId (never by absolute source/target paths). The
orchestration reads the manifest, validates the snapshot, freezes the
daemon, captures a rollback of the live Creator JSON files, stages the
backup files atomically, restarts the daemon, and auto-rolls-back the
live files on any failure.
Changes:
- apps/packaged/src/restore.ts: injectable restore engine (freeze ->
rollback snapshot -> atomic stage -> restart -> auto-rollback), with a
production daemon control (graceful shutdown + re-spawn).
- apps/packaged/src/sidecars.ts: extract spawnDaemonSidecar and add
restartPackagedDaemon for the restore restart path.
- apps/daemon/package.json: expose ./creator-backup subpath (store reads).
- packages/host: add OpenDesignHostCreatorBridge (restoreBackup), validate
it in isOpenDesignHostBridge, add restoreCreatorBackup helper, keep the
package independent of @open-design/contracts (mirrored local types).
- apps/desktop: creatorBackup option on DesktopRuntimeOptions and
DesktopMainOptions, ipcMain.handle("creator:restore-backup") with
requireMainWindowSender, preload creator bridge (no HTTP restore route).
- apps/packaged/src/index.ts: build the daemon control and supply the
creatorBackup capability to runDesktopMain.
Tests: 7 packaged restore-engine tests (mock daemonControl + injected store
reads, real fs: success / validation fail / missing / auto-rollback /
path-unsafe), 8 host bridge tests (restoreCreatorBackup + creator
validation). Daemon creator-backup suite remains 20/20 green.
- e2e/lib/vitest/release-gates-evidence.ts: SHA-256 hashing, G6-G10
summarizer (honest BLOCKED when failure paths unexercised), orchestrator
merge from spec partial + artifact hashes.
- e2e/scripts/release-smoke.ts: compute artifact SHA-256, write
release-gates-evidence.json (G10 evidence: version/commit/platform/profile).
- e2e/specs/{win,mac}.spec.ts: emit release-gates-partial.json on real
platforms for G6-G9 signal collection.
- release-stable.yml / release-preview.yml: scope Cleanup workflow artifacts
to -release-assets$ so smoke report + evidence survive; upload dedicated
open-design-*-release-gates-evidence artifacts (if: always()).
- e2e/tests/release-gates-evidence.test.ts: 17 focused tests (green in-sandbox).
CW-10 审核整改闭环: - P0: G7 不再接受 dataRootPreserved:null 即 PASS;未测量 → BLOCKED,内容发散 → FAIL, 仅升级前后真实内容指纹一致 → PASS(指纹与遍历序/绝对路径/mtime 无关)。 - P1: Windows full profile 真实执行 G8(checksum-mismatch 回滚)与 G9(metadata 不可达离线启动) 失败路径,断言旧版本仍健康且 dataRoot 指纹不变;core profile 与 macOS 诚实 BLOCKED(不假称 PASS)。 - P2: byteLengthOf 改 statSync 取大小,不再 readFileSync 整读大文件;SHA-256 仍走流式。 - 新增/更新 29 个聚焦单元测覆盖 G7 未测→BLOCKED、一致→PASS、发散→FAIL、G8/G9 未执行→BLOCKED、 真实执行成功→PASS、stat 取大小不整读;e2e 类型检查与发布工作流契约测试全绿。 - 验收文档去除 “G7 健康即 PASS / CI 预期 PASS 无失败场景” 表述,记录真实失败路径证据。 无 Co-Authored-By。未 push/merge/rebase/reset/force;未触碰真实 .od/用户/运行目录;未引入 electron-updater。
CW-10 独立验收复核(2026-07-18)发现的 P0:G8(checksum-mismatch)与 G9 (metadata-unreachable)助手各自以坏 metadata URL 重启桌面后,主流程仅把正常 URL 写回 CLI 的 process.env,却未重启桌面。桌面在启动即冻结 OD_UPDATE_METADATA_URL (独立进程,读取自身 process.env),故运行中的桌面仍持死链/篡改 URL,导致 runPayloadUpdateAcceptance -> waitForDownloadedUpdater 轮询 inspect --update-action download 时 metadata-unreachable 超时、整个 full profile 成功升级路径失败。 修复:恢复 URL 后、成功升级前增加 stop+start,使桌面继承正常 URL;覆盖 payloadFixture 与 updateMetadataUrl 两种来源。同步在验收文档 §10 记录调用链复核 与修复。无 Co-Authored-By。未 push/merge/rebase/reset/force;未触碰真实 .od/用户/ 运行目录;未引入 electron-updater;未改 package.json/pnpm-lock.yaml。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
This draft contains the local Creator Workbench delivery accumulated across CW-01 through CW-10, including CW-10 desktop release smoke evidence. It is intentionally a draft because upstream
mainhas advanced substantially since the local shared base, so this is not a small CW-10-only diff.CW-10 Highlights
Local Validation
e2e/tests/release-gates-evidence.test.ts: 29 passedtools/pack/tests/release-workflows.test.ts: 1 passedCI Limitation
The official Windows
fullsmoke requires the upstream repository's release secrets, signing configuration, and artifact storage. It should be run by an upstream maintainer after reconciling and merging this draft.No production user data or media was used.