## What this adds
A **test-free verification command** — `pnpm verify:fast`
(`scripts/verify-fast.mjs`) — that gives deterministic, flake-free
signal without running the test suite. It is fully **additive**: `pnpm
test`, the merge gate (`test:gate`), and CI are untouched.
`docs/testing.md` observes the broad test gate "caught no recalled real
bugs while consuming ~70% of shipping time in flake triage."
`verify:fast` is the opt-in path for non-test verification, suitable as
a project `testCommand`/verification command.
## What verify:fast runs
1. **typecheck — scoped to the changed packages** (each package's
`typecheck` script, or `pnpm --filter <pkg> exec tsc --noEmit -p .` when
none exists).
2. **build — scoped to the changed packages** (`pnpm --filter <pkg>
build`, only for packages that declare a build script).
3. **boot smoke once** (`scripts/boot-smoke.mjs`: CLI `--help` + a real
`fn serve` answering `GET /api/health`), after builds so it runs against
fresh artifacts.
Change-detection **reuses `scripts/test-changed.mjs`** (`getBaseBranch`
/ `detectComparisonBase` / `changedFilesSince` /
`resolveAffectedPackages` / workspace resolution — newly `export`ed)
instead of reinventing git-diff, so it scopes to exactly the packages a
changed-only test run would. With no affected package (root/docs-only
diff) it runs the boot smoke only. Each step is bounded by the existing
`runWithWatchdog` (class `changed`) so a hung tsc/build/serve fails
fast; it streams progress and exits nonzero on the first failing step.
`@fusion/desktop` and `@fusion/mobile` are skipped, mirroring the root
`build`/`typecheck` exclusions.
## Measured wall-time
On this branch's diff (which resolves to the heaviest package,
`@fusion/dashboard`), end-to-end:
```
[verify:fast] plan: typecheck:@fusion/dashboard -> build:@fusion/dashboard -> boot-smoke
[verify:fast] OK typecheck @fusion/dashboard (~44s)
[verify:fast] OK build @fusion/dashboard (26.2s)
[verify:fast] OK boot smoke (CLI --help + real serve /api/health) (19.6s)
[verify:fast] PASS — 3 step(s) green in 90.3s (no tests run).
```
**~90s total**, deterministic and flake-free. By contrast a typical
**scoped test run for the same package** is far heavier and flake-prone:
`docs/testing.md` notes a dashboard task "otherwise re-ran all 822
dashboard test files (~5-8 min)", and `pnpm test` additionally runs the
merge-gate suite first. verify:fast trades that test-suite cost (and its
flake-triage tax) for a typecheck+build+boot signal in ~1.5 min.
## Doc additions
- `AGENTS.md` + `docs/testing.md` testing-commands lists now include
`pnpm verify:fast`, described as the recommended **test-free
verification** (typecheck + build + boot-smoke), suitable as a project
`testCommand`/verification command; the full suite stays available and
runs non-blocking.
## Tests / verification
- New `scripts/__tests__/verify-fast.test.mjs` (11 tests) pins the pure
planning / arg-construction logic — scoped typecheck/build selection,
build-script gating, desktop/mobile exclusion, boot-smoke-only fallback,
and reuse of `resolveAffectedPackages`. It never spawns real
tsc/build/vitest.
- `pnpm verify:fast` runs end-to-end and exits 0 (output above).
- Lint clean on all new/changed files; `agents-md-invariants`,
`check-test-inventory`, `verify-fast`, and `test-changed` script tests
all green (132 tests).
No changeset (scripts + docs + CI-tooling, behavior-additive;
`@runfusion/fusion` runtime unaffected).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- stage-review-badge-begin -->
---
<a href="https://stagereview.app/Runfusion/Fusion/pull/1777">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
</picture>
</a>
<!-- stage-review-badge-end -->
Adds scripts/verify-fast.mjs + root `pnpm verify:fast`, an opt-in, flake-free
verification path that runs typecheck + build scoped to the changed packages
(reusing test-changed.mjs git-diff / changed-package resolution) plus the
existing boot smoke once, with no test suite. Each step is bounded by the
shared runWithWatchdog (class "changed"); exits nonzero on the first failure.
No default changed: pnpm test, the merge gate, and CI are untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Strengthen the fn_run_verification allowFullSuite parameter description, add an
AGENTS.md standing rule, and update docs/testing.md so agents default to a
file-scoped verification command and reserve allowFullSuite for genuinely full
runs with no targetable test set. allowFullSuite is the main way verification
balloons past its budget; the thin merge gate is the cross-cutting safety net.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
Replaces dense, agent-authored technical changeset paragraphs with a
**structured, concise changeset schema** (end-user summary + category +
optional dev detail), enforced by a linter. Adds a **deterministic
distillation step** at version time that transforms a release's
collected changesets into clean, grouped, end-user-facing release notes.
Unifies both release paths (local `release.mjs` and CI `version.yml` /
`release.yml`) behind a single distilled artifact so the root
`CHANGELOG.md` and GitHub Release both carry the same user-facing notes.
## Changes
### Changeset format (`scripts/lib/changeset-schema.mjs`)
- Each changeset body now uses labeled fields: `summary` (required,
user-facing, max 120 chars), `category` (required:
feature/fix/breaking/security/performance/internal), `dev` (optional
developer detail)
- Legacy freeform changesets are detected and flagged for the transition
period
### Linter (`scripts/check-changeset-format.mjs`)
- Validates structured schema, summary length, category enum, and
frontmatter package scope
- Wired into `test:gate`, `pretest`, `pretest:full`, and `pr-checks.yml`
- Legacy changesets warn (exit 0) during transition; `--strict` flag
fails on them
### Distillation (`scripts/lib/distill-release-notes.mjs`)
- `distillDeterministic` builds grouped, end-user-facing release notes
by category (New, Fixed, Breaking, Security, Performance, Internal)
- `buildDistillationPrompt` and `DISTILLATION_SYSTEM_PROMPT` ready for
AI distillation via `createFnAgent` when model credentials are available
- Graceful fallback: deterministic bullet list when no model is
configured
### Release integration
- **Local path** (`scripts/release.mjs`): captures changeset entries
before `changeset version` deletes them, distills notes post-version,
replaces the version's CHANGELOG section with curated notes
- **CI path** (`scripts/ci-distill-release-notes.mjs`,
`scripts/run-ci-distill.mjs`): chained into `release:version` so both
flows get distilled notes
- **GitHub Release** (`release.yml`): uses curated CHANGELOG notes
instead of `generate_release_notes: true`
### Documentation
- `AGENTS.md`, `RELEASING.md`, `docs/contributing.md` updated with the
structured format guide
- `.changeset/README.md` template for `pnpm changeset` consumers
## Testing
- 54 new unit tests across changeset-schema, check-changeset-format,
distill-release-notes, and extract-version-notes
- `pnpm lint` clean
- `pnpm test:gate` green (371 tests)
- `pnpm check:changesets` passes (13 legacy warnings expected during
transition)
## Plan
Full implementation plan:
`docs/plans/2026-06-24-001-feat-better-changelog-plan.md`
<!-- stage-review-badge-begin -->
---
<a href="https://stagereview.app/Runfusion/Fusion/pull/1750">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
</picture>
</a>
<!-- stage-review-badge-end -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added structured release-note guidance and validation for changeset
entries.
* Release notes now use curated, grouped changelog content instead of
auto-generated text.
* Added a fallback process to keep release notes consistent when
automated distillation isn’t available.
* **Bug Fixes**
* Improved handling of legacy changesets and malformed entries.
* Ensured version-specific changelog sections are updated without
affecting older releases.
* **Tests**
* Added coverage for changeset validation, note grouping, and changelog
section replacement.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Update AGENTS.md, RELEASING.md, contributing.md with the structured
changeset format guide. Add .changeset/README.md template. Add changeset
for this change. Update distill-release-notes.mjs with final version.
Code review (8 reviewers) fixes:
- P1: embedded board task-detail now passes onRequestClose so delete/merge/retry dismiss the panel (no ghost task).
- P1: RightDock + TerminalModal drag handlers add pointercancel + unmount teardown (no leaked document listeners / rAF / stuck userSelect); remove dead onOpenChange prop.
- Planning slot DOM-poll interval now caps (self-cancels on mobile); heartbeat slider persist debounced + mounted-guarded.
- Cleanup: remove dead ViewHeader-migration CSS (Skills/Insights), extract shared GithubIcon, move Activity Log embedded CSS to ActivityLogModal.css, FNXC date-format fixes, AGENTS lazy-view note.
- Update stale RightDock roster tests + LeftSidebarNav 'Compound Eng' test to current behavior.
Live UI tweaks:
- Default load lands on board, never the Command Center Dashboard.
- View Board/View Agents moved to the Command Center Overview tab (under the live-activity strip).
- Heartbeat card full-width with spaced, wrapping controls.
- Dev Server panel scrolls in the dock; ChatView right-pane title takes the full line.
- Files pop-out renders deterministic left-right two-pane.
- Mailbox list pane narrower + narrow by default; Add Goal button height matches the Compound stage button; Memory Working-Memory tab no longer overlaps; Skills view fills full width.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Makes the self-healing layer workspace-aware and adds recovery for the states
Phase C introduced. No reconciler may wrongly finalize, skip, or move a workspace
task backward.
Existing reconcilers (the P0/P1 the feasibility check caught):
- recoverInterruptedMergingTasks no longer single-commit-finalizes a workspace
task: a workspace candidate clears the transient "merging" status and re-enqueues
via enqueueMerge (which routes to the idempotent landWorkspaceTask), never
reaching findLandedTaskCommit / moveTask(done) / task:merged — so a partial-landed
task (repo A landedSha, repo B not) is never marked fully merged on one repo's
commit. recoverStaleMergingStatus confirmed single-commit-free.
- recoverMergeableReviewTasks relaxes its Boolean(t.worktree) gate to also admit
isWorkspaceTask(t), so a zero-landed mergeable workspace task (null worktree) is
re-enqueued instead of silently skipped forever.
New reconcilers:
- reconcileWorkspacePartialLands: re-enqueues stuck non-done workspace merges via
enqueueMerge (idempotent skip of landed repos), guarded by allowsAutoMergeProcessing
(FN-5147), user-pause, and a workspace-aware liveness predicate (any sub-repo path
active via pathsForTask+isPathActive — triple-proof isn't workspace-aware). A repo
with its fusion/<id> branch gone AND landedSha unset is parked failed; branch-gone
but landed is skipped. Emits task:reconcile-workspace-partial-land(+-no-action).
- reclaimPhantomWorkspaceLandLeases: enumerates the new activeSessionRegistry
entriesByKind("workspace-repo-land"), age-gated by the FN-6736 floor, and clears a
lease whose owner is terminal/dead (live merging owners untouched). Emits
task:reclaim-phantom-workspace-land-lease.
- reconcileOrphanedWorkspaceWorktrees: removes a done workspace task's recorded
per-repo worktreePaths (isPathActive-guarded) with NO temp-root walk (AGENTS.md).
Emits task:reconcile-orphaned-workspace-worktree.
New activeSessionRegistry.entriesByKind seam; four DatabaseMutationType literals +
the AGENTS.md Run Audit list. Single-repo behavior byte-for-byte unchanged (every
path branches on isWorkspaceTask). 13 new fixture tests; 558 self-healing tests +
test:gate (649+58) green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Recover wedged in-progress tasks by clearing stale executor bindings only after liveness proves the owner is gone.
- Add a guarded executor escape hatch that clears only stale in-memory task bookkeeping while refusing live session surfaces.
- Teach self-healing to identify phantom executor-active bindings using age, checkout, heartbeat, run-audit, and worktree liveness signals before requeueing preserved work.
- Record reclaim events in run audit and cover preserved-worktree recovery with reliability interaction tests.
- Document the recovery path and add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-6736-phantom-executor-binding.md | 5 +
AGENTS.md | 1 +
docs/architecture.md | 1 +
.../reclaim-phantom-executor-binding.test.ts | 244 +++++++++++++++++++++
packages/engine/src/executor.ts | 35 +++
packages/engine/src/run-audit.ts | 2 +
packages/engine/src/runtimes/in-process-runtime.ts | 3 +-
packages/engine/src/self-healing.ts | 112 ++++++++++
8 files changed, 402 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6736
Fusion-Task-Lineage: c76191ba-f4c3-4832-a790-67676e258ba2
Resolves conflicts in the lazy-loaded heavy-views inventory. main independently
grew the curated list to 22 (adding AppModals lazy modals); this branch added the
Command Center view. Combined count is 23 — updated the AGENTS.md prose/inventory
and the lazy-loaded-views-docs test contract (count + length assertions) to 23,
keeping main's richer "App-level and AppModals" wording.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds /api/pull-requests routes (list, detail, merge/approve/retry/close/
automerge — all re-fetch authoritative state before acting), a
PullRequestView rendering every entity state distinctly (creating/failed/
unverified/responding/await-review/conflict) with the action bar, live
auto-merge gate reason, and conflict CTA; TaskCard PR node-state badge +
link; and the R16 column-move-backward guard. User actions route through
the existing releaseHeldTaskByEvent primitives. Maps the new PR node kinds
in the workflow editor's kind resolver. 13 route tests + lazy-view guard
green; component test runs in CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- config: explicit Hans script wins over HK/MO region (zh-Hans-HK -> zh-CN),
with regression tests for script-vs-region precedence
- dashboard i18n: detection.caches [] so the detector's init-time auto-persist
can't masquerade as a user choice and suppress server-settings hydration
- LanguageSelector: role=group (radiogroup conflicted with aria-pressed)
- bin: validate --lang against SUPPORTED_LOCALES (fail loudly, not silent
fallback); help text clarifies the flag is terminal-UI-only
- cli i18n test: assert a real fr catalog lookup (defaultValue could mask a
catalog that never loaded); comment the async changeLanguage re-init seam
- assert-locale-chunks: only dirs containing common.json count as locales
- plan doc: merge duplicate Ink 6.8->7.0 risk bullets
- AGENTS.md/solution doc: frontmatter field list + normalizer excerpt synced
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document the trigger-layer gating bug fixed in this PR under
docs/solutions/logic-errors/, seed CONCEPTS.md with the merge-lifecycle
vocabulary, and surface both knowledge stores in AGENTS.md's reference
docs index.
- docs/solutions/architecture-patterns/: knowledge doc covering the Vite
code-split catalog constraint, zh-CN/zh-TW routing, three-tier language
persistence, CLI inline-resources init, and the CI failure modes hit
- CONCEPTS.md: seed shared domain vocabulary (Surface, Global Settings,
Three-Tier Setting, Supported Locale)
- AGENTS.md: surface docs/solutions/ and CONCEPTS.md in Reference docs
- docs/settings-reference.md: add the missing GlobalSettings.language row
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document and enforce pnpm build-script review decisions to prevent ignored-script install warnings.
- add reviewed ignoredBuiltDependencies entries to the root pnpm config and mirror the effective policy in pnpm-workspace.yaml
- add a regression test that verifies reviewed dependencies are categorized exactly once and stay aligned across both config files
- document the pnpm build-script approval policy in contributing docs and link plugin authoring guidance from AGENTS.md and PLUGIN_AUTHORING.md
Files changed:
AGENTS.md | 5 ++
docs/PLUGIN_AUTHORING.md | 3 +-
docs/contributing.md | 14 ++++
package.json | 9 +++
pnpm-workspace.yaml | 14 ++++
scripts/__tests__/pnpm-build-scripts-config.test.mjs | 74 ++++++++++++++++++++++
6 files changed, 118 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-5927
Fusion-Task-Lineage: 192bbed9-c5ed-45cb-b4bd-fb18514e2783