Release logs showed two warning classes after the packaging fixes: Linux builds warned about macOS-only menu imports, and tauri-action reported an unknown releaseAssetNamePattern input. Gate the native menu imports to macOS and use the action's supported assetNamePattern input so release logs stay clean and asset naming is actually applied.
Constraint: Linux release builds compile the shared Tauri lib without macOS-only menu usage
Constraint: tauri-action v0 accepts assetNamePattern, not releaseAssetNamePattern
Rejected: Ignore warning-only output | release candidates should not hide real signal behind avoidable warnings
Confidence: high
Scope-risk: narrow
Directive: Keep workflow input names aligned with tauri-action's published action schema
Tested: cargo fmt --check
Tested: cargo check --target aarch64-apple-darwin
Tested: git diff --check
Not-tested: Full GitHub release workflow after retag before pushing
The release workflow shells out through tauri-action but did not pass Tauri's --ci flag, while the desktop development workflow already uses it for the same app,dmg packaging path. Align release builds with the non-interactive CI mode so macOS DMG packaging does not depend on interactive defaults during tag builds.
Constraint: Release assets are produced remotely by .github/workflows/release-desktop.yml on tag push
Constraint: The dev desktop workflow already validates macOS app,dmg packaging through tauri build --ci
Rejected: Drop macOS DMG from release assets | would reduce the expected user-facing installer surface for 0.2.1
Confidence: medium
Scope-risk: narrow
Directive: Keep release and dev desktop Tauri build flags aligned when changing bundle behavior
Tested: bunx tauri build --target aarch64-apple-darwin --bundles app,dmg --ci --config /tmp/tauri-no-updater.json
Tested: git diff --check
Not-tested: Full GitHub release workflow after retag before pushing
The PR triage workflow mentioned Dosu inside inline-code formatting and before the final footer, which did not reliably wake the bot. Move the handoff so the last non-empty comment line is a plain-text @dosubot request, matching the working PR template pattern.
Constraint: GitHub bot mentions can be sensitive to markdown formatting and comment placement.
Rejected: Leave the mention as a copy-paste hint | it does not satisfy the maintainer need for automatic bot triggering.
Confidence: high
Scope-risk: narrow
Directive: Keep the generated triage comment's final non-empty line as a plain-text @dosubot request.
Tested: bun run check:policy
Tested: git diff --check
Tested: bun run check:pr
Pull requests need a deterministic way to show changed areas, required checks, missing-test signals, and CLI-core risk before review. This adds a path-based policy gate, local impact reporting, PR triage labels/comments, and reusable check scripts so reviewers can evaluate blast radius without trusting contributor claims.
Constraint: CLI core should remain effectively frozen unless a maintainer explicitly overrides it.
Constraint: Default PR checks must be safe for external forks and avoid live model/provider calls.
Rejected: Run live provider tests on every PR | secrets, cost, network, and vendor instability would make the gate noisy and unsafe.
Rejected: Use Dosu as the merge gate | AI review is useful for risk explanation, but deterministic Actions must own blocking checks.
Confidence: high
Scope-risk: moderate
Directive: Keep real model/provider smoke tests in maintainer-controlled workflows; do not make them required for untrusted PRs.
Tested: bun run check:impact
Tested: bun run check:policy
Tested: ruby YAML parse for PR workflows
Tested: git diff --check
Tested: bun run check:native
Tested: npm run docs:build
Tested: bun run scripts/pr/run-server-tests.ts
Tested: bun run check:adapters
Tested: bun run check:desktop
Not-tested: GitHub-hosted pull_request_target label/comment execution before opening this PR
Windows releases were shipping both NSIS exe and MSI bundles, which made the
release page harder to understand and increased the chance that users would
pick the wrong asset. Restricting Windows output to MSI narrows the installer
surface while the release asset naming now spells out platform, architecture,
and bundle type directly in every published filename.
Constraint: Remote desktop packaging is triggered by GitHub Actions releases, not local uploads
Constraint: Updater metadata must keep latest.json stable for existing clients
Rejected: Keep publishing both NSIS and MSI with better docs | still leaves the higher-risk installer on the release page
Rejected: Rename assets manually after upload | easy to drift from workflow output and updater metadata
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If Windows exe bundles are reintroduced later, reassess SmartScreen and AV impact before publishing them again
Tested: YAML parse for both desktop workflows; git diff --check on modified files; manual review of PowerShell changes
Not-tested: End-to-end GitHub Actions release run; PowerShell parser validation on a Windows host
The main branch push introduced a new root dependency for WebFetch fixes, but
package-lock.json was not refreshed, so the docs workflow's npm ci step failed
before it could even build VitePress. This syncs the lockfile, upgrades the
docs workflow to Node 22 for the current parser dependency requirements, and
includes package-lock.json in the workflow trigger set.
Constraint: The docs pipeline uses npm ci, which requires package.json and package-lock.json to stay exactly in sync
Rejected: Leave the workflow on Node 20 | continues to emit avoidable engine warnings for current docs parser dependencies
Rejected: Switch docs workflow from npm ci to npm install | weakens reproducibility instead of fixing the lockfile contract
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Whenever root dependencies change, keep package-lock.json in the same commit so docs and other npm-based workflows remain green
Tested: npm ci
Not-tested: Remote GitHub Actions rerun after pushing this fix
The release workflow was still publishing a hard-coded GitHub Release body,
which forced manual copy-paste of each version's markdown after the build
finished. This change makes tagged releases load release-notes/vX.Y.Z.md
from the tagged commit and fail fast when the file or version/tag alignment
is missing. The local release script now enforces the same contract and
stages the matching markdown file into the release commit automatically.
Constraint: GitHub Releases must be generated from the tagged commit so the workflow can only read files already present at that revision
Rejected: Keep a hard-coded releaseBody in workflow | still requires manual release-page editing every version
Rejected: Store release notes only outside git state | workflow cannot read local-only markdown during tag-triggered builds
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep release-notes/vX.Y.Z.md as the canonical source for GitHub Release bodies and preserve the tag/version validation gate
Tested: ruby -e 'require "yaml"; YAML.load_file(".github/workflows/release-desktop.yml"); puts "YAML OK"'
Tested: bun run scripts/release.ts 0.1.5 --dry
Tested: git diff --check
Not-tested: End-to-end GitHub Actions release run against a pushed tag
The desktop app already had Tauri updater plumbing, but the
release pipeline was not emitting signed updater artifacts and
the UI exposed only a thin auto-check path. This change restores
a working updater release path, rotates to a new updater public
key, and adds a shared update flow with manual check/install
controls for testing.
Constraint: Original updater private key is unavailable, so a new public key had to be embedded and old installs cannot trust new signatures
Constraint: Must not add new dependencies or require main-branch rollout before validation
Rejected: Keep the old pubkey and skip signing | would leave release builds unable to publish valid updater artifacts
Rejected: Add a manual download fallback flow | user explicitly deferred that work
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Preserve the new updater private key and password outside the repo; losing them again will break future in-app updates for installed builds
Tested: desktop unit test for updater store; desktop TypeScript no-emit; desktop production build
Not-tested: end-to-end updater install against a real GitHub Release on this branch
The current release lane is aimed at manual downloads and command-line usage, not notarized distribution or in-app auto-updates. This change removes Apple certificate import and updater signing from GitHub Actions, and forces release builds to disable updater artifacts so unsigned release bundles can still be produced consistently.
Constraint: Repository does not have working Apple signing certs or updater signing keys
Rejected: Keep signing requirements and document the secrets problem | blocks every release on infra the project does not plan to maintain
Rejected: Remove the GitHub release workflow entirely | still need a repeatable packaging path for downloadable artifacts
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If signed distribution or in-app updates are added later, restore signing in workflow together with validated secrets and release metadata
Tested: git diff --check; YAML parse of release-desktop workflow; manual inspection that updater artifacts are disabled via tauri.release-ci.json and signing env/steps are removed
Not-tested: Live GitHub Actions run after workflow update
GitHub Actions showed that Linux compilation and .deb packaging succeed on both x64 and ARM64, but AppImage consistently fails inside linuxdeploy. The workflows now ship Linux as .deb only so CI and releases stay reliable while the AppImage path is investigated separately.
Constraint: Current GitHub-hosted Linux packaging fails specifically in linuxdeploy after successful .deb output
Rejected: Keep AppImage enabled and accept red workflows | blocks release confidence for an optional format
Rejected: Drop Linux builds entirely | would remove a working .deb delivery path
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Re-enable AppImage only after capturing linuxdeploy stderr and validating both Linux architectures on GitHub Actions
Tested: git diff --check; YAML parse of both workflow files; inspection of failed GitHub Actions logs showing .deb success before AppImage linuxdeploy failure
Not-tested: Re-run of updated workflows on GitHub Actions
The local desktop build path already proved that AppImage packaging needs libfuse2 and that macOS artifacts may be directories rather than plain files. This commit aligns the GitHub workflows with those realities so remote validation matches the local release path more closely.
Constraint: GitHub-hosted Linux runners do not guarantee AppImage runtime deps unless we install them explicitly
Rejected: Leave release workflow unchanged and trust local macOS build only | would not validate Linux packaging path at all
Rejected: Upload only DMG/installer files in dev workflow | hides the macOS .app artifact users expect for local testing
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep dev and release desktop dependency lists in sync when packaging requirements change
Tested: git diff --check; YAML parse of both workflow files; manual inspection of artifact collection and Linux dependency steps
Not-tested: Live GitHub Actions execution on repository runners
This folds together the desktop-side fixes needed before broader rollout.
Session resume no longer deadlocks waiting on init, Mermaid and inline image
output render inside chat, task and sub-agent state stay visible during
execution, local build/release paths are safer, and Feishu/Telegram now expose
lightweight mobile commands (/help, /status, /clear) without adding a new
adapter-specific protocol.
Constraint: Desktop releases must publish updater artifacts from non-draft GitHub releases
Constraint: IM commands need short, phone-friendly responses and low operational complexity
Rejected: Add a dedicated IM command API surface | re-used existing slash commands and session/task REST endpoints to keep adapters thin
Rejected: Wait for task_update push events in WebUI | added low-risk polling because the current frontend ignores that event path
Confidence: medium
Scope-risk: broad
Reversibility: clean
Directive: Keep IM command replies terse and mobile-first, and merge local fallback slash commands when server-provided lists are partial
Tested: cd desktop && bun x vitest run src/components/chat/MermaidRenderer.test.tsx src/components/markdown/MarkdownRenderer.test.tsx
Tested: cd desktop && bun x vitest run src/components/chat/composerUtils.test.ts src/pages/ActiveSession.test.tsx src/stores/chatStore.test.ts
Tested: cd desktop && bun run lint
Tested: bun test src/server/__tests__/conversations.test.ts --test-name-pattern "SDK init arrives only after the first user turn" --timeout 60000
Tested: cd adapters && bun test common/ feishu/ telegram/
Tested: cd adapters && bunx tsc --noEmit
Not-tested: Full GitHub Actions release run on all three desktop platforms
Not-tested: Local DMG packaging end-to-end on Apple Silicon
Not-tested: Real Feishu/Telegram device sessions against a live adapter process