Commit Graph

157 Commits

Author SHA1 Message Date
Phil Larson
0643a64f0d fix(desktop): pin complete Pi runtime closure (#2439)
## Summary
- pin `pi-agent-core`, `pi-ai`, `pi-coding-agent`, and `pi-tui` to one
exact 0.82.0 workspace override set
- extend the Pi version policy guard to reject missing, ranged, or
mismatched desktop runtime closure overrides
- add a patch changeset for the legacy desktop packaging fix

## Test plan
- `node --test scripts/__tests__/check-pi-versions-pinned.test.mjs` (5
passed)
- `node scripts/check-pi-versions-pinned.mjs`
- `corepack pnpm check:changesets --strict`
- focused engine fixtures: 4 files / 47 tests passed
- GitHub: Desktop packaging, Lint, Typecheck, Build, Gate, and Greptile
Review passed
2026-07-26 07:34:50 -07:00
gsxdsm
084dd76d64 feat(release): write release copy with opus and draft tweets for betas too
- distillation runs on opus (env-overridable) with a 4-minute budget
- highlights must name the surface and outcome; vague filler is banned
- tweets target 200-280 chars with concrete changes and varied structure
- betas get their own tester-facing draft carrying `fn update --channel beta`
- prerelease openers read as "Fusion 0.74 beta:" instead of "Fusion 0.74-beta.0"
2026-07-24 23:15:36 -07:00
gsxdsm
330e4970f0 refactor(release): move the version-anchor package.json rewrite into the shared lib
Makes the re-anchor file mutation unit-testable alongside the anchor decision.
2026-07-24 23:01:11 -07:00
gsxdsm
dba9746287 fix(release): base the next beta on the shipped stable version
After a stable release, main stayed inside the old pre-mode cycle, so the next
beta numbered below the published stable (v0.73.0-beta.7 after v0.73.0) and the
dev checkout kept reporting the last beta.

- beta releases re-anchor a stale pre-mode cycle on the newest stable tag
- both channels refuse a version at or below the newest published stable
- stable promotion now back-merges release into main automatically (fail-soft
  on conflict) so the local dev version is the stable version
2026-07-24 22:59:19 -07:00
gsxdsm
e3dba364d1 FN-8564: update bundled Pi runtime to 0.82.0
Update Fusion's matched Pi dependencies and compatibility coverage for version 0.82.0.

- Pin Pi AI and coding-agent packages to the exact 0.82.0 release pair.
- Refresh provider catalog, supplemental model, auth storage, and Droid thinking coverage.
- Add the published CLI patch changeset.

Files changed:
 .changeset/fn-8564-pi-082.md                       |   7 +
 packages/cli/package.json                          |   4 +-
 packages/cli/src/__tests__/package-config.test.ts  |   2 +-
 packages/core/package.json                         |   2 +-
 packages/dashboard/package.json                    |   2 +-
 ...ister-model-routes-kimi-k3-supplemental.test.ts |   6 +-
 packages/engine/package.json                       |   4 +-
 .../src/__tests__/provider-registration.test.ts    |   4 +-
 packages/engine/src/auth-storage.ts                |  11 +-
 packages/engine/src/pi.ts                          |   6 +
 packages/pi-claude-cli/package.json                |   8 +-
 .../src/thinking-config.ts                         |  10 +-
 pnpm-lock.yaml                                     | 176 +++++++++++----------
 pnpm-workspace.yaml                                |   6 +-
 .../__tests__/check-pi-versions-pinned.test.mjs    |   8 +-
 15 files changed, 142 insertions(+), 114 deletions(-)

Fusion-Task-Id: FN-8564

Fusion-Task-Lineage: 543c5e17-4cb2-446f-9a1c-ec7ec8b8117a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 19:06:14 -07:00
gsxdsm
6166b496e4 FN-8559: refresh test timing snapshots
Refresh timing data and keep velocity reports aligned with the current snapshot.

- Attribute CI timing reports from absolute checkout paths
- Render report-only slowest tests from the latest timing snapshot
- Update timing snapshot data and regression coverage

Files changed:
 scripts/__tests__/ci-test-shard-timings.test.mjs  |    9 +
 scripts/__tests__/test-velocity-baseline.test.mjs |   38 +
 scripts/ci-test-shard.mjs                         |   13 +
 scripts/test-timings.json                         | 2522 +++++++++++++--------
 scripts/test-velocity-baseline.mjs                |   33 +-
 5 files changed, 1616 insertions(+), 999 deletions(-)

Fusion-Task-Id: FN-8559

Fusion-Task-Lineage: 09ed6b78-f82f-4732-a5e3-1066efe385b3

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 06:21:53 -07:00
gsxdsm
c5a8421533 FN-8560: forward desktop test telemetry flags
Desktop test execution now preserves CI reporter and JSON output flags.

- Forward caller-selected Vitest reporters and output files through the desktop test wrapper.
- Add coverage for reporter syntax and shard timing command forwarding.
- Document desktop timing artifact requirements.

Files changed:
 docs/testing.md                                    |  7 ++++-
 packages/desktop/scripts/__tests__/test-args.test.ts | 36 ++++++++++++++++++++++
 packages/desktop/scripts/test-args.ts              | 13 ++++++++
 packages/desktop/scripts/test.ts                   |  3 +-
 scripts/__tests__/ci-test-shard.test.mjs           |  9 ++++++
 5 files changed, 66 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-8560

Fusion-Task-Lineage: 2a89b28d-39f6-4949-aec2-1123c36126cf

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-24 05:30:45 -07:00
gsxdsm
c5e9a7956a fix(ci): stop watchdog false-kills of the grown core slice; actually upload timing artifacts
- Shard watchdog floor 25min (was 15): the July PG-cutover test growth pushed
  @fusion/core past 900s on contended CI runners; run 30075604930 killed a
  healthy core run at exactly the floor because the 27-day-old (still "fresh")
  undercounting timings snapshot tightened the budget to it — the same
  false-kill class as the 5->15min raise. Floor pin + in-band example updated.
- full-suite.yml timing upload: include-hidden-files — the .timings/ dot-dirs
  were silently excluded by upload-artifact@v4, so the step has uploaded
  nothing since it was added and the snapshot could never be refreshed from CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 00:55:38 -07:00
gsxdsm
ff165ecb5a fix: scope beta release notes to that beta's changesets; stable keeps full-cycle rollup
Pre-mode preserves consumed changeset .md files, so every beta's distilled notes and GitHub prerelease body aggregated the entire cycle since the last stable (v0.73.0-beta.4 shipped the full 0.72.0→0.73.0 aggregate). Betas now distill only changesets not yet recorded in pre.json's consumed ledger, and fail loudly when a beta would ship nothing new. Stable promotion still feeds the full preserved set, keeping its notes an explicit rollup of every beta in the cycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 12:18:24 -07:00
gsxdsm
28e8c0abc9 FN-8524: cover workspace manifests in Docker builds
Ensure the builder install layer includes every selected workspace manifest.

- Copy the five omitted plugin manifests before frozen installation.
- Validate pre-install Dockerfile coverage against pnpm workspace entries.
- Document the manifest coverage requirement and focused test command.

Files changed:
 Dockerfile                                         |   8 +-
 docs/docker.md                                     |   3 +-
 .../dockerfile-workspace-manifests.test.mjs        | 111 +++++++++++++--------
 3 files changed, 78 insertions(+), 44 deletions(-)

Fusion-Task-Id: FN-8524

Fusion-Task-Lineage: 16a4d9df-ff08-4051-9e53-0da414ef6a85

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 22:04:32 -07:00
gsxdsm
f120e6c879 FN-8506: run static checks in verify:fast
Run canonical pretest validators before test-free verification work.

- Derive read-only static check steps from the root pretest script.
- Test fail-fast static-check planning and execution.
- Document the expanded verify:fast gate and correct changeset metadata.

Files changed:
 .changeset/mobile-board-pointercancel-settle.md |   2 +-
 docs/testing.md                                 |   5 +-
 scripts/__tests__/verify-fast.test.mjs          | 105 ++++++++++++++++++++++--
 scripts/verify-fast.mjs                         |  86 ++++++++++++++++---
 4 files changed, 174 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-8506

Fusion-Task-Lineage: 87f74fda-1fd0-4e08-9bfe-51e0c4c9a31d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 18:26:33 -07:00
gsxdsm
9002fca9de FN-8497: reduce merge gate wall time
Keep merge-gate coverage focused while running its independent test lanes concurrently.

- Limit PostgreSQL gate coverage to lifecycle and transactional-handoff canaries.
- Run engine and PostgreSQL gate lanes concurrently while preserving failure propagation.
- Enforce canary coverage policy and refresh velocity documentation and history.

Files changed:
 docs/test-velocity-baseline.md                     |  16 +--
 docs/testing.md                                    |   5 +-
 package.json                                       |   2 +-
 packages/core/package.json                         |   2 +-
 .../__tests__/engine-vitest-gate-policy.test.mjs   |  79 +++++++++++++-
 scripts/test-velocity-history.json                 | 115 +++++++++++++++++++++
 6 files changed, 204 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-8497
Fusion-Task-Lineage: 8777959c-6d8c-4686-a975-d91af2c169ea
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 15:47:24 -07:00
gsxdsm
241a5c94ea chore: bump @earendil-works/pi to 0.81.1 (#2399)
## Summary
- Bump `@earendil-works/pi-ai` and `@earendil-works/pi-coding-agent`
from **0.80.10 → 0.81.1** (exact matched pins).
- Update `pnpm-workspace.yaml` overrides so floating `*` consumers
(`droid-cli`, `pi-llama-cpp`, runtime plugins) stay on the same
ModelRuntime surface.
- Refresh pin-guard tests, package-config assertions, and FNXC notes for
the new pin.

## What's new in pi 0.81.x
- Qwen Token Plan providers
- Expanded usage accounting (tools/compaction/branch summaries)
- Resilient compaction retries + retry lifecycle events
- Full provider-extension registration API
- Built-in llama.cpp router management
- Provider/catalog fixes (Bedrock env credentials, OpenAI Responses
early-stream retry, Codex 272K defaults, extension stream-fallback
restore)

## Test plan
- [x] `scripts/check-pi-versions-pinned` (4/4)
- [x] Typecheck: core, engine, dashboard, cli, pi-claude-cli
- [x] `package-config.test.ts` (35)
- [x] `provider-registration.test.ts` (14)
- [x] `auth-storage-concurrency` + `model-registry-refresh` (15)
- [x] `register-model-routes-kimi-k3-supplemental` (1)
- [ ] CI gate green
- [ ] Spot-check Anthropic OAuth + API key session
- [ ] Spot-check openai-codex model picker / supplemental models

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Updates**
  * Updated the bundled Pi runtime to version 0.81.1.
* Added support for newer models and providers, including Qwen Token
Plan.
  * Improved usage accounting and session reliability.
* Strengthened compaction retry handling and provider catalog accuracy.
  * Added support for the expanded maximum thinking level.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-22 01:32:14 -07:00
gsxdsm
7911fdb9b1 fix(release): preserve distilled changelog summaries across releases
syncRootChangelog rewrote every prior release from raw package notes, so only
the latest distilled Highlights view survived. Re-emit already-distilled bodies
on sync, keep the archive pointer outside version sections, and restore wiped
summaries from release history.
2026-07-21 20:29:46 -07:00
Phil Larson
fe9269b57b fix(i18n): restore Chinese roadmap duplicate labels (#2358)
## Summary
- restores the missing Simplified Chinese duplicate-roadmap report label
- restores the missing Traditional Chinese duplicate-roadmap report
label
- adds a patch changeset for the catalog correction

## Test plan
- `pnpm --filter @fusion/i18n test` (5 files, 29 tests)
- `pnpm build`


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Restored Simplified and Traditional Chinese translations for duplicate
roadmap report titles.
* Updated the roadmap reporting UI text to clarify when a report is
already in the roadmap and ask whether to add the user’s data point.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 00:18:53 -07:00
gsxdsm
e0e395a715 FN-8365: enforce dashboard route registrar mount order
Keep dashboard API registration modular while preserving Express route precedence.

- Route all top-level dashboard registrars through a runtime-checked canonical mount sequence
- Add mount-order and inline-route-ratchet coverage with CI enforcement
- Document registrar ownership and mount-order conventions

Files changed:
.github/workflows/pr-checks.yml                    |   3 +
AGENTS.md                                          |   2 +
package.json                                       |   5 +-
packages/dashboard/src/routes.ts                   | 136 +++++-----
packages/dashboard/src/routes/README.md            | 276 ++++++++++-----------
packages/dashboard/src/routes/__tests__/create-api-routes-mount-order.test.ts |  66 +++++
packages/dashboard/src/routes/create-api-routes-mount-sequence.ts |  54 ++++
scripts/__tests__/check-routes-modular.test.mjs    |  28 +++
scripts/check-routes-modular.mjs                   |  65 +++++
scripts/lib/routes-modular-baseline.json           |   3 +
10 files changed, 433 insertions(+), 205 deletions(-)

Fusion-Task-Id: FN-8365

Fusion-Task-Lineage: 9c36a263-ed5e-4524-8ea5-71ed3f3e34d9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-19 15:53:07 -07:00
gsxdsm
965f15f5ca FN-8368: enforce browser-safe dashboard core imports
Prevent dashboard code from bypassing Vite's browser-safe core boundary.

- Add an allowlist-backed scanner for dashboard core value imports, including dynamic template imports.
- Run the scanner in test and merge-gate prechecks, with regression coverage and import guidance.
- Document reviewed browser-safe core leaves and Vite alias requirements.

Files changed:
 docs/dashboard-guide.md                            |   6 +
 package.json                                       |   6 +-
 packages/dashboard/vite.config.ts                  |   5 +
 ...no-node-only-core-imports-in-dashboard.test.mjs |  80 ++++++++++
 ...heck-no-node-only-core-imports-in-dashboard.mjs | 167 +++++++++++++++++++++
 .../lib/dashboard-browser-safe-core-modules.json   |  59 ++++++++
 6 files changed, 320 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-8368

Fusion-Task-Lineage: 13e70672-d1da-430c-a360-0a714ad33d9f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-19 14:08:51 -07:00
gsxdsm
ecffdbb14b fix: isolate test-mode database access
Prevent automated tests from inheriting production PostgreSQL URLs and route global test-mode startups to a dedicated external or embedded test database.
2026-07-19 00:10:02 -07:00
gsxdsm
e445b3e367 FN-8201: pin pi dependency versions
Pin the pi runtime packages to a single exact version so global npm installs resolve a compatible set.

- Pin pi-ai and pi-coding-agent declarations across workspace manifests
- Add a guard and tests that reject ranged or mismatched pi versions
- Document the source-install fallback and add a patch changeset

Files changed:
 .changeset/fn-8201-pin-pi-versions.md              |   7 ++
 docs/getting-started.md                            |   3 +
 package.json                                       |   6 +-
 packages/cli/package.json                          |   4 +-
 packages/cli/src/__tests__/package-config.test.ts  |  18 +++-
 packages/core/package.json                         |   2 +-
 packages/dashboard/package.json                    |   2 +-
 packages/engine/package.json                       |   4 +-
 packages/pi-claude-cli/package.json                |   8 +-
 .../__tests__/check-pi-versions-pinned.test.mjs    |  45 ++++++++
 scripts/check-pi-versions-pinned.mjs               | 120 +++++++++++++++++++++
 11 files changed, 205 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-8201

Fusion-Task-Lineage: bf0ac363-df5f-4445-835b-cfd2d4909659

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-17 09:12:01 -07:00
gsxdsm
06d03d4e1f FN-8103: enforce PostgreSQL-only production data access
Require production paths to use PostgreSQL-aware stores and prevent new unrestricted database access.

- Add a checked allowlist that bans production getDatabase() calls by default.
- Route Quality plugin persistence through an async PostgreSQL-aware store and add Drizzle ORM.
- Document backend-safe plugin storage patterns and cover guarded access behavior.

Files changed:
 docs/PLUGIN_AUTHORING.md                           |  20 +++
 package.json                                       |   6 +-
 .../src/__tests__/agent-logs-backend-mode.test.ts  |   7 +
 packages/core/src/store.ts                         |   7 +-
 packages/core/src/task-store/remaining-ops-5.ts    |   8 +-
 plugins/fusion-plugin-quality/package.json         |   1 +
 .../src/__tests__/async-quality-store.pg.test.ts   |  36 +++++
 .../src/__tests__/cancel-and-plans.test.ts         |   8 +-
 .../src/__tests__/experimental-gate.test.ts        |   1 +
 .../src/routes/create-routes.ts                    |  50 +++----
 .../src/runner/command-runner.ts                   |  17 ++-
 .../src/store/async-quality-store.ts               |  34 +++++
 pnpm-lock.yaml                                     |   3 +
 scripts/__tests__/check-no-getdatabase.test.mjs    |  90 ++++++++++++
 scripts/check-no-getdatabase.mjs                   | 159 +++++++++++++++++++++
 scripts/lib/getdatabase-allowlist.json             |  18 +++
 16 files changed, 422 insertions(+), 43 deletions(-)

Fusion-Task-Id: FN-8103
Fusion-Task-Lineage: ff17bcb2-5341-4c6c-a5c4-993580539676
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-16 10:13:49 -07:00
gsxdsm
e9f14bf024 perf: speed up local pnpm build and cap stacked verifications (#2134)
## Summary

- Extend the workspace content-hash skip cache to **all** packages (not
just plugins), with `--force` / `--full` flags
- Default local CLI packaging to a **fast mode** (bin/extension +
migrations only); full desktop/plugin/DTS staging runs on CI or `pnpm
build:full`
- Enable TypeScript `incremental` builds for warm recompiles
- Add `maxConcurrentVerifications` (default **1**) so concurrent tasks
cannot stack monorepo typecheck/build and peg CPU

Warm `pnpm build` measured ~**126s → ~0.8s** when nothing changed.

## Test plan

- [x] `node --test scripts/__tests__/build-workspace.test.mjs` (12 pass)
- [x] `pnpm --filter @fusion/engine exec vitest run
src/__tests__/verification-concurrency.test.ts`
- [x] `pnpm --filter @fusion/core exec vitest run
src/__tests__/settings-parity.test.ts`
- [x] Local: first `pnpm build` rebuilds as needed; second warm `pnpm
build` skips all packages (~0.8s)
- [x] Fast CLI packaging logs skip of desktop/plugin staging without
`FUSION_CLI_FULL_PACKAGE`
- [ ] CI: `pnpm build` still full-packages under `CI=true` (plugin
staging / release surfaces)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a Scheduling setting to limit concurrent verification tasks from
1–8, with a default of 1.
* Verification tasks now support cancellation while waiting or running.
  * Added options for forced and full workspace builds.

* **Performance**
* Local builds can skip unchanged packages and use incremental
compilation for faster rebuilds.
* Local CLI packaging is faster by default, while full packaging remains
available when needed.

* **Documentation**
* Updated the settings reference with the new verification concurrency
option.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 08:44:11 -07:00
gsxdsm
97172fdcf2 fix(FN-7952): require PostgreSQL in CLI and desktop (#2110)
## Summary

CLI commands, daemon/dashboard startup, packaged desktop startup, and
live-data maintenance scripts now share the mandatory PostgreSQL
lifecycle. Operators no longer risk a command silently reading or
writing a disconnected SQLite shadow when PostgreSQL setup fails.

## Design decisions

- Every startup owner retains and awaits its PostgreSQL shutdown
callback, including partial-startup failure paths.
- CLI project context and lock-retry flows resolve through asynchronous
project stores.
- Maintenance scripts use the shared backend helper; explicit database
migration/inspection remains the only CLI surface allowed to read legacy
SQLite sources.

## Validation

- CLI and Desktop typechecks pass on the stacked branch.
- `pnpm test:gate` passes all 478 gate tests.
- This PR changes 54 files.

## Stack

- Depends on #2109, which depends on #2108.
- Bundled plugins and docs/release follow in later PRs.

Related: #2105


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* PostgreSQL is now the authoritative store for structured project and
task metadata.
* Projects can be recognized and initialized using
`.fusion/project.json`, without creating a legacy SQLite database.
  * CLI commands now retry transient PostgreSQL contention errors.

* **Bug Fixes**
* Improved cleanup when commands complete, fail, or run in the
background, preventing lingering resources.
  * Improved desktop, server, and session shutdown reliability.

* **Documentation**
* Updated storage and standalone binary guidance to reflect PostgreSQL
and legacy SQLite compatibility.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-14 23:18:55 -07:00
gsxdsm
c25f8b796d Harden PostgreSQL migration foundation (#2088)
## Summary

- make SQLite-to-PostgreSQL cutover retryable, fail-closed, versioned,
and transactionally serialized
- isolate migration sessions from runtime traffic and apply schema
upgrades through `0002`
- enforce tenant ownership across automations, analytics, activity,
usage, agent runs, evals, and todos
- replace expired SQLite-only coverage with PostgreSQL parity and
concurrency coverage

This is PR 1 of 2. The stacked follow-up restores PostgreSQL parity for
CLI, engine, dashboard, and bundled integrations.

## Verification

- `pnpm check:changesets --strict`
- `pnpm --filter @fusion/core typecheck`
- migration schema, connection, and SQLite cutover suite: 57 tests
passed
- `pnpm test:gate`: 463 tests passed

## Post-Deploy Monitoring & Validation

- take a restorable PostgreSQL backup before deploy
- confirm `fusion_schema_migrations` contains `0002`
- confirm each expected project has a complete
`fusion_sqlite_migrations` row
- verify no null or empty tenant ownership in automations, activity
logs, agent runs, and usage events
- monitor for ownership inference failures, cutover verification
failures, and migration session errors
- restore the backup for data rollback; do not downgrade the
tenant-isolation schema in place

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* PostgreSQL-backed analytics and live dashboard metrics are now
project-scoped (activity, tools, monitor, signals, and live snapshots).
* Evaluation runs and scheduled eval batches received lifecycle
improvements (ordering, updates, and execution flow).
* Todo list changes now emit events; WhatsApp persistence and
project-scoped roadmap data are supported.

* **Bug Fixes**
* SQLite-to-PostgreSQL cutovers now fail safely with stronger
verification, serialized cutover handling, and safer project ownership.
* PostgreSQL backend writes and reads are now strictly project-isolated
and fail closed when project context is missing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-14 08:16:42 -07:00
gsxdsm
f7d29dd1da chore: archive pre-0.60 changelog notes and distill corrupted 0.47–0.59 entries
Raise the durable archive cutoff to 0.60.0, keep only the current release in CHANGELOG.md, and rewrite labeled summary/category/dev package aggregates for 0.47–0.59 into operator-facing Highlights/New/Fixed notes.
2026-07-13 23:00:25 -07:00
gsxdsm
c15c78feeb feat: migrate storage from SQLite to PostgreSQL (#1793)
# Migrate storage from SQLite to PostgreSQL — full dashboard cutover

Migrates Fusion's storage layer to the embedded PostgreSQL
`AsyncDataLayer` (the default backend) and **completes the
satellite-store + feature cutover** so every dashboard and Command
Center surface works in PG mode.

## Status — every surface works in embedded-PG mode

Verified live against a running embedded-Postgres dashboard (all
**200**, zero 5xx) and gate-tested (**23 files / 99 tests** on embedded
PG, plus engine-core 294 and ci-shape 63 in the blocking merge gate;
core/engine/cli/dashboard typecheck clean).

| Area | Surfaces | State |
|---|---|---|
| Satellite stores | workflows, todos, insights, research, missions,
goals, mailbox | ✅ |
| Views | artifacts, documents, evals | ✅ |
| Command Center | activity, productivity, team, tokens, tools,
**workflows**, **github**, **signals**, **plugin-activations**, **live**
(all 10) | ✅ |
| Run execution | insight generation, research run execution | ✅
(store-path; AI step needs a provider) |
| Live updates | SSE push for mission/research/insight events | ✅ |
| Workflow editing | create / update / delete / select (+ id counter) |
✅ |
| Engine | mission autopilot, incident-signal ingestion, regression
storm-guard, agent wake-on-message | ✅ |
| Core | tasks, agents, secrets, automations, memory, chat, usage, PRs,
git | ✅ |

## Approach

Each satellite store gets an `Async<Store>` wrapper exposing the sync
store's method names over the existing `async-*-store.ts` helpers;
`get<Store>Store()` returns a `Sync | Async` union; consumers `await`
(harmless on sync), and engine/CLI paths that can't convert use
`instanceof Sync` graceful fallback. Analytics aggregators branch on
`"ping" in dbOrLayer` to run schema-qualified raw SQL over `project.*`
(snake_case) in PG. Executors/orchestrators/autopilot are
await-converted to drive the union store; the async store wrappers
extend `EventEmitter` so SSE live-push fires in both backends.

Not-yet-ported capabilities degrade gracefully (never 500) and are
individually called out in commits.

## Sync with main

The branch is kept continuously merged with `main` (currently through
FN-7845, 2026-07-12); the earlier "final rebase deferred" note no longer
applies. Use **Create a merge commit** (or squash) to land it — GitHub's
rebase-merge cannot replay a merge-maintained branch.

## Residual Review Findings

Multi-agent code review of the PostgreSQL satellite-store ports (U1–U5)
applied 3 safe fixes (see `fix(review): apply autofix feedback`). The
following are **real but gated** — recorded here as follow-up work
rather than auto-applied. All are SQLite→PostgreSQL
**concurrency/atomicity regressions**: the sync stores were immune only
by SQLite's single-writer, single-threaded-handler execution; the async
ports open multi-await read-modify-write windows. **Reachability is low
today** because the execution engines that generate concurrent same-run
mutations (insight run executor, research orchestrator/dispatcher) are
`instanceof`-gated to sync mode in PG. No process-crash class survived
(all engine fallbacks correctly guard the sync store).

- **[P1] Research `appendResearchEvent` dual-write is non-atomic**
(`packages/core/src/async-research-store.ts`, corroborated: adversarial
+ reliability). The `research_run_events` insert (own transaction) and
the `run.events` jsonb update are separate writes — a crash between
them, or two concurrent appends, splits the table count from the jsonb
array. **Fix:** perform the seq-insert and the jsonb update in one
`layer.transactionImmediate`.
- **[P1] Research run terminal-reversion via stale full-row persist**
(`async-research-store.ts` `persistResearchRun`/`updateResearchStatus`).
Concurrent `PATCH /runs/:id/status` + `POST /runs/:id/events` can revert
a terminal run to `running` by overwriting the whole row, bypassing the
transition guard. **Fix:** scoped column `UPDATE`s with a `WHERE status
…` guard, or optimistic version column.
- **[P2] `updateResearchRun`/`updateInsightRun` read-then-write TOCTOU**
— concurrent PATCHes last-writer-wins on the lifecycle merge. **Fix:**
`SELECT … FOR UPDATE` / enclosing transaction.
- **[P2] `upsertRun`/`createRunOrThrowConflict` check-then-create race**
(`async-insight-store.ts`) — two callers can each create an "active"
run. **Fix:** partial unique index on `(projectId, trigger) WHERE status
IN ('pending','running')`.
- **[P3] `createResearchRetryRun` return-value divergence** — sync
returns the pre-update `queued` snapshot; async returns the reloaded
`retry_waiting` run (persisted state is identical). Pick one side for
cross-backend parity.
- **[P2/perf] Mission `getMissionWithHierarchy`/`getMissionHealth` N+1
fan-out** — O(milestones×slices) sequential round-trips hold one pool
slot per request; can starve the pool for large hierarchies. **Fix:**
batched/joined reads.
- **Testing gaps:** no PG-mode concurrency tests (interleaved
status/event mutations), no sync↔async parity assertion for the
lifecycle-error codes, and no mission status/health rollup parity test
vs the sync `MissionStore`.

~~Out of scope (deferred): AI run *execution* (insight/research) +
mission autopilot + live SSE mission events remain sync-gated/degraded
in PG mode.~~ **Since ported** — insight/research run execution, mission
autopilot, and SSE live push all run on the async layer now, which also
makes the concurrency findings above genuinely reachable; they remain
open follow-ups.







---

## Update — 2026-07-12: production-readiness hardening & live acceptance

Everything below landed on this branch since the description above was
written:

**Production blockers from review — fixed**
- `recoverStaleTransitionPending` ported to the async layer (backend
moves write + clear the crash-safe marker; startup/maintenance sweeps no
longer throw).
- Lost-update class fixed: `atomicWriteTaskJson`/`WithAudit` write
changed columns only (full-row upserts silently resurrected stale fields
across concurrent store instances — the "task stuck unplanned forever"
bug).
- First-boot **auto-migration**: booting the PG backend over a project
with a legacy `fusion.db` migrates it automatically (loud failure,
SQLite kept as backup), and the dashboard shows a one-time **"your data
was migrated" banner** with the backup paths and a Need-help Discord
link.
- `pg_dump`/`pg_restore` discovered from common install locations for
embedded-mode backups.
- The PG suite is part of the blocking merge gate (`test:pg-gate`).

**Multi-project isolation (PR #2007, merged into this branch)**
- `project_id` partition key on tasks / archived tasks / config,
`taskProjectScope` threaded through every scan/claim/count, per-project
config rows, layer bound to the project at startup.
- Review P1 follow-up: the shared cold-storage `archive.archived_tasks`
table is also partitioned and all archived-board reads/counts/searches
are scoped.
- Schema drift self-heal generalized to schema-qualified columns so
existing databases upgrade in place.

**Other changes**
- Node settings sync **removed** in PG mode (409
`settings-sync-disabled-postgres`) — nodes share state by connecting to
the same database; auth sync kept (per-machine file).
- Perf (review findings): `listTasks` pushes column filter + ORDER BY +
LIMIT/OFFSET into SQL; `getConversation` capped to the most recent 200
messages.
- Fixed a false "operator action required" pause-abort log fired on
every successfully auto-merged task.

**Live acceptance — PASSED (2026-07-12)**
A sandboxed instance (isolated HOME, embedded PG, real Opus executor)
ran a task through the complete cycle: create → triage (AI spec) →
execute → in-review → AI squash-merge landed on the project's `main` →
done. A write+read sweep of every data surface (settings, comments,
documents, attachments + artifact bridge + artifact edit, chat with real
generation, goals, missions, agent mail, secrets, workflows, memory, CC
analytics) was green on embedded PG.

**Known remaining work**
- The per-project `config` PK re-key has no upgrade path for
pre-isolation embedded-PG databases (needs a real `DROP
CONSTRAINT`/re-key migration; fresh databases are fine).
- `pg_dump`/`pg_restore` binaries are not yet bundled in release
artifacts (PATH/common-location discovery only).
- The satellite-store concurrency findings listed above.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Phil Larson <hello@phillarson.xyz>
Co-authored-by: fusion-merge <fusion-merge@local>
2026-07-13 19:07:58 -07:00
gsxdsm
edfe57c8e0 feat: AI Highlights and engagement X draft on release
Claude-author Highlights plus an engagement-oriented tweet (≤280) during changelog distillation, with scheme-free links, Fusion version openers that drop .0 patch, and a soft deterministic fallback when Claude is offline.
2026-07-13 01:21:33 -07:00
gsxdsm
b85a6b8663 FN-7912: add quarantine-ledger deadline visibility check
Add a report-only script that surfaces flaky-test quarantine entries approaching their 14-day deletion clock, so maintainers can make deliberate rescue-or-expire decisions before entries silently expire.

- Add scripts/check-quarantine-ledger.mjs: reads scripts/lib/test-quarantine.json, computes days-remaining against the existing 14-day deletion clock (shared DELETION_CLOCK_DAYS from scripts/test-velocity-baseline.mjs), and buckets each entry as expired/near/healthy/unknown
- Support --warn-within=<days> (default 5) to tune the near-deadline window, --json for machine-readable output, and --strict as an opt-in local/CI gate (exits 1 on expired/near entries) while default mode stays exit-0 and non-blocking
- Wire pnpm check:quarantine-ledger script in package.json
- Add scripts/__tests__/check-quarantine-ledger.test.mjs covering deadline bucketing/sorting, empty/missing ledger handling, --strict behavior, and --json output shape
- Document the new command and its flags in docs/testing.md under the quarantine ledger/deletion ratchet section

Files changed:
 docs/testing.md                                    |  10 +
 package.json                                       |   1 +
 scripts/__tests__/check-quarantine-ledger.test.mjs | 159 ++++++++++++++++
 scripts/check-quarantine-ledger.mjs                | 202 +++++++++++++++++++++
 4 files changed, 372 insertions(+)

Fusion-Task-Id: FN-7912

Fusion-Task-Lineage: c08e2e09-473a-4ad0-8c27-43cbc3355168

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 21:21:10 -07:00
gsxdsm
2c7df1bd78 FN-7875: split archived pre-0.50 release notes out of root CHANGELOG.md
Adds a deterministic changelog-archive split so scripts/release.mjs stops regenerating one ever-growing root CHANGELOG.md and instead keeps only current release notes at the root while durably archiving pre-0.50.0 history.

- Add scripts/lib/changelog-archive.mjs with partitionVersionsByCutoff (splits a version-ordered list at the 0.50.0 cutoff, preserving order and treating non-parseable keys as archived) and archivePointerLine (renders the "older releases" pointer appended to the current changelog).
- Rework scripts/release.mjs's syncRootChangelog to build CHANGELOG.md (current versions + archive pointer) and a new CHANGELOG-archive.md (versions before 0.50.0) via a shared buildRootChangelogLines/normalizeChangelogLines helper instead of one monolithic file.
- Add scripts/__tests__/changelog-archive.test.mjs covering cutoff partitioning, boundary/patch handling, non-parseable keys, custom cutoffs, and the archive pointer text.
- Regenerate CHANGELOG.md (now only 0.50.0+) and add CHANGELOG-archive.md containing the pre-0.50.0 history moved out of the root file.

Files changed:
 CHANGELOG-archive.md                         | 10882 +++++++++++++++++++++++
 CHANGELOG.md                                 | 11717 ++-----------------------
 scripts/__tests__/changelog-archive.test.mjs |    58 +
 scripts/lib/changelog-archive.mjs            |    56 +
 scripts/release.mjs                          |    49 +-
 5 files changed, 11710 insertions(+), 11052 deletions(-)

Fusion-Task-Id: FN-7875
Fusion-Task-Lineage: 220e6aa1-54fb-4800-a86e-6d8d21f6bf18
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-12 13:10:52 -07:00
gsxdsm
8f7089ecc9 fix(FN-7779): rebuild changed plugins on pnpm dev + warn on stale plugin dist
The Grok stale-dist bug was possible because the dev/build path never
refreshed plugin dist:

- The `client` prebuild (default `pnpm dev dashboard`) rebuilt only
  @fusion/core + @fusion/engine + @fusion/dashboard, never plugins.
- The FN-6638 stale-dist startup warning only scanned packages/, never
  plugins/, so a source-ahead plugin dist ran phantom-old with no warning.

Changes:
- build-workspace.mjs: add `--plugins-only` to plan/build just the plugins
  that changed, reusing the existing content-hash skip cache (cheap no-op when
  unchanged).
- scripts/dev-prebuild-client.mjs: new orchestrator — fast core/engine/
  dashboard build, then incremental changed-plugin rebuild. The `client`
  prebuild now runs this single cross-platform command.
- dist-freshness.mjs: scan plugin roots (plugins/, plugins/examples/) so a
  stale plugin dist is warned like a stale package dist; the warning names the
  plugin dir.

Verified: --plugins-only plans only plugins, skips unchanged on the second
run, and re-plans exactly the one plugin whose source changed. All script and
CLI lib tests pass.

Fusion-Task-Id: FN-7779
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:26:23 -07:00
gsxdsm
01be51bf35 fix: require typed operator authorization for real releases
Remove the self-grantable FUSION_RELEASE_AUTHORIZED env signal and replace
it with an interactive prompt: a real release now requires a live human to
type "authorized" at a TTY. Releases can no longer run non-interactively
(no TTY is blocked outright), and --yes does not bypass the typed phrase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 09:00:47 -07:00
gsxdsm
aae6a6eca2 FN-7662: harden boot-smoke temp dir cleanup against macOS ENOTEMPTY races
Boot-smoke's post-verdict temp-dir cleanup could throw ENOTEMPTY on macOS when async writers (fsevents/Spotlight, the just-killed child) still touched the throwaway HOME/project dirs, turning an already-decided PASS into a pnpm verify:fast failure.

- Add removeTempDir() helper in scripts/boot-smoke.mjs: wraps rmSync with maxRetries/retryDelay and swallows any residual error (never throws) since cleanup always runs after the smoke verdict is decided/printed
- Replace both isolatedHome/isolatedProject rmSync call sites (exit handler and EADDRINUSE retry-port branch) with removeTempDir()
- Guard main() behind an import.meta.url === pathToFileURL(process.argv[1]) check so requiring boot-smoke.mjs from tests doesn't spawn a real server
- Add scripts/__tests__/boot-smoke.test.mjs covering ENOTEMPTY tolerance, always-failing rm, retry/backoff params, and the no-boot-on-import guard

Files changed:
 scripts/__tests__/boot-smoke.test.mjs | 77 +++++++++++++++++++++++++++++++++++
 scripts/boot-smoke.mjs                | 44 +++++++++++++++++---
 2 files changed, 115 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7662

Fusion-Task-Lineage: 3288d055-4f70-4487-8462-933563214ce5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 00:37:07 -07:00
gsxdsm
20184acdfd FN-7486: fix no-diff merge recovery ownership checks
Fix no-op task branch recovery by recognizing canonical branches with no unique diff before rejecting inherited foreign trailers.

- Add no-diff ownership classification for already-merged detection when canonical task branches inherit another task's landed commit.
- Teach self-healing and branch-misbound recovery to ignore foreign branch-tip trailers only for branches proven to have no unique task diff.
- Skip synthetic verify:fast typechecks for JavaScript alias packages without tsconfig files and cover the behavior with tests.
- Add regression coverage and a patch changeset for the recovery fix.

Files changed:
 .changeset/fn-7486-merge-recovery-noop-ownership.md       |  7 ++
 .../already-merged-detector.real-git.test.ts       | 68 +++++++++++++++++
 .../self-healing-already-merged.real-git.test.ts   | 89 ++++++++++++++++++++--
 packages/engine/src/already-merged-detector.ts     | 88 +++++++++++++++------
 packages/engine/src/self-healing.ts                | 61 +++++++++++++--
 scripts/__tests__/verify-fast.test.mjs             | 16 +++-
 scripts/verify-fast.mjs                            | 15 +++-
 7 files changed, 303 insertions(+), 41 deletions(-)

Fusion-Task-Id: FN-7486

Fusion-Task-Lineage: 4185c6ed-9731-4ffc-b033-34bf0c3a83ad

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-03 22:04:45 -07:00
gsxdsm
4be9275747 FN-7463: refresh test feedback baseline docs
Refresh the weekly test feedback-loop baseline and carry operator notes through the reporting helper.

- Add the 2026-W27 baseline snapshot with updated gate, pnpm test, quarantine, and slowest-test data.
- Refresh the published Markdown summary and trend table for #leads.
- Preserve operator notes in Markdown and printed leads summaries, with regression coverage for notes and empty live quarantine ledgers.

Files changed:
 docs/test-feedback-loop-baseline.md               |  52 +++++-----
 docs/test-feedback-loop-baselines.json            | 113 ++++++++++++++++++++++
 scripts/__tests__/test-feedback-baseline.test.mjs |  72 +++++++++++++-
 scripts/test-feedback-baseline.mjs                |  10 +-
 4 files changed, 219 insertions(+), 28 deletions(-)

Fusion-Task-Id: FN-7463

Fusion-Task-Lineage: 2279c412-5371-41dd-81d1-7fc397bb349a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-03 07:47:03 -07:00
gsxdsm
9d89cb8d32 FN-7420: fix test velocity quarantine reporting
Refresh the test velocity baseline and coverage so quarantine counts come from the live ledger.\n\n- Update the weekly baseline report to show zero active quarantines and a neutral delta.\n- Strengthen the report-only regression test to cover stale report and history quarantine values.\n- Document the FN-7420 requirement near the regression scenario.\n\nFiles changed:\n docs/test-velocity-baseline.md                    | 10 +++++-----\n scripts/__tests__/test-velocity-baseline.test.mjs | 10 +++++++---\n 2 files changed, 12 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7420

Fusion-Task-Lineage: 9144ddb5-3a72-4a37-a1d1-471871f3cbc4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:32 -07:00
gsxdsm
4178e7d325 FN-7415: Delete stale executor pause quarantine
Delete the expired executor pause quarantine and its stale direct-dispatch coverage.

- Remove the obsolete executor-pause test suite after the graph runtime cutover.
- Clear the matching Vitest exclude and quarantine-ledger entry.
- Refresh test audit, timing, line-count, and planning references for the deleted suite.

Files changed:
 ...7-001-refactor-workflow-runtime-cutover-plan.md |    2 +-
 docs/test-value-audit.json                         |  102 -
 .../engine/src/__tests__/executor-pause.test.ts    | 3061 --------------------
 packages/engine/vitest.config.ts                   |    5 -
 scripts/__tests__/test-velocity-baseline.test.mjs  |    2 +-
 scripts/lib/test-quarantine.json                   |    8 +-
 scripts/line-count-baseline.json                   |    1 -
 scripts/test-timings.json                          |    1 -
 8 files changed, 3 insertions(+), 3179 deletions(-)

Fusion-Task-Id: FN-7415
Fusion-Task-Lineage: 3d1551c8-1353-47cb-a70f-d88e733a6652
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:31 -07:00
gsxdsm
00ce5d6a27 FN-7414: refresh test velocity quarantine baseline
Refresh the velocity baseline artifacts so live quarantine counts are reflected consistently.

- Add regression coverage for live quarantine ledger counts overriding stale report and history values.
- Update the weekly velocity baseline report to show the current quarantine count and deltas.
- Append the latest measured velocity history row with quarantine count one.

Files changed:
 docs/test-velocity-baseline.md                    |  22 ++---
 scripts/__tests__/test-velocity-baseline.test.mjs |  75 +++++++++++++++
 scripts/test-velocity-history.json                | 112 ++++++++++++++++++++++
 3 files changed, 198 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7414

Fusion-Task-Lineage: 7c6cd47c-482d-426c-a714-79da33d4591d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 11:38:31 -07:00
gsxdsm
627c5fb0bd FN-7371: clarify CI mode regression guard
Clarifies the test-infrastructure regression guard for CI mode selection.\n\n- Update the FNXC rationale for the CI=true --print-mode subprocess test.\n- Document that full-suite mode remains an explicit opt-in via --full or FUSION_TEST_FULL.\n\nFiles changed:\n scripts/__tests__/test-changed.test.mjs | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7371

Fusion-Task-Lineage: b7482ef1-4db7-4003-85f7-3466470d3dff

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 10:04:55 -07:00
gsxdsm
70d7dcaa6c FN-7290: skip unchanged plugin builds
Add a git-backed plugin build cache to make root workspace builds skip safe unchanged plugin packages.

- Route root pnpm build through a workspace build planner that always builds non-plugin packages and selectively skips cached plugin packages.
- Hash plugin inputs with declared local workspace dependencies plus root build tooling/config and require dist outputs before skipping.
- Cover cache planning and invalidation behavior with script tests and document the operator-facing build behavior.

Files changed:
 .changeset/fn-7290-plugin-build-cache.md   |   7 +
 docs/testing.md                            |   5 +-
 package.json                               |   2 +-
 scripts/__tests__/build-workspace.test.mjs | 253 +++++++++++++++++
 scripts/build-workspace.mjs                | 427 +++++++++++++++++++++++++++++
 5 files changed, 692 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7290

Fusion-Task-Lineage: a91861c7-385d-4e9c-bc43-11ed0ff188c8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 11:08:55 -07:00
gsxdsm
94ddfe1064 FN-7274: document workflow tools in Fusion skill
Document the workflow-authoring tool surface in the packaged Fusion skill references.

- Add workflow tools to the generated Fusion skill category and capability tables.
- Teach the skill sync script to read workflow tool specs from extension and engine agent tool sources.
- Cover workflow tool documentation and cache inputs with sync tests.
- Add a changeset for the published CLI skill update.

Files changed:
 .changeset/fn-7274-workflow-skill-tools.md         |   7 +
 packages/cli/skill/fusion/SKILL.md                 |   1 +
 .../cli/skill/fusion/references/engine-tools.md    |   4 +-
 .../cli/skill/fusion/references/extension-tools.md |  83 +++++++++-
 .../skill/fusion/references/fusion-capabilities.md |   8 +
 packages/cli/src/__tests__/skill-sync.test.ts      |  60 ++++++-
 scripts/__tests__/skill-sync-cache.test.mjs        |   5 +
 scripts/sync-fusion-skill-tools.mjs                | 172 ++++++++++++++++++---
 8 files changed, 312 insertions(+), 28 deletions(-)

Fusion-Task-Id: FN-7274

Fusion-Task-Lineage: e1cd6bd8-aecc-49ca-96ed-a937a15a18a4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 08:04:12 -07:00
gsxdsm
f42b49ab2d FN-7105: add CI print-mode regression guard
Add regression coverage ensuring CI=true no longer forces test-changed into full-suite mode.

- Add a reusable --print-mode subprocess helper for synthetic test-changed repositories.
- Seed the synthetic repo with changeset config so mode decisions match workspace expectations.
- Assert CI=true stays in gate or changed mode while --full and FUSION_TEST_FULL still select full mode.

Files changed:
 scripts/__tests__/test-changed.test.mjs | 54 +++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

Fusion-Task-Id: FN-7105

Fusion-Task-Lineage: f4a26d96-3992-4f25-a456-04f2b9b8a4dc

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-27 09:28:30 -07:00
gsxdsm
af8cc7b29c FN-7079: Correct quarantine baseline reporting
Correct the velocity baseline to reflect an empty quarantine ledger and cover that report-only path.

- Update the published test velocity baseline quarantine totals, buckets, trend row, and #leads summary to zero.
- Add a regression test that regenerates the report from an empty live quarantine ledger without measuring lanes.
- Assert deletion-due and bucket rows stay zero and stale nonzero quarantine text is removed.

Files changed:
 docs/test-velocity-baseline.md                    | 10 ++--
 scripts/__tests__/test-velocity-baseline.test.mjs | 72 ++++++++++++++++++++++-
 2 files changed, 76 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7079

Fusion-Task-Lineage: d641adc3-f991-4d95-bcb2-7b20bbfeb0bb
2026-06-26 15:50:40 -07:00
gsxdsm
29aee2196a FN-7051: restore verify:fast prerequisite builds
Restore verify:fast so fresh worktrees prepare required artifacts before boot smoke.\n\n- Bootstrap missing or stale workspace dist artifacts before scoped verification.\n- Always build @runfusion/fusion for source-checkout boot smoke, even when no package diff maps to the CLI.\n- Update verify:fast tests and docs to capture the prerequisite build flow.\n\nFiles changed:\n AGENTS.md                              |  4 +-\n docs/testing.md                        |  5 +-\n scripts/__tests__/verify-fast.test.mjs | 29 +++++++++--\n scripts/verify-fast.mjs                | 92 ++++++++++++++++++++++++++--------\n 4 files changed, 101 insertions(+), 29 deletions(-)

Fusion-Task-Id: FN-7051

Fusion-Task-Lineage: b8980f15-0103-4f40-9f8d-83907461988a
2026-06-26 01:10:00 -07:00
gsxdsm
1699c60033 fix: anchor rootDir at the git toplevel so subdir runs don't skip tests (#1785)
greptile: my earlier existence-check anchor was necessary but insufficient.
`rootDir` (= process.cwd() when FUSION_PROJECT_DIR is unset) drives ALL workspace
discovery (readWorkspacePatterns / listWorkspacePackageInfos /
packageHasVitestConfig). Launched from a package subdir, cwd-based discovery
found no packages, so decideExecutionPlan saw "no affected package", ran only the
gate, and exited successfully WITHOUT running the live changed package tests.

Fix the root cause: resolveRepoRoot() resolves the git toplevel as the fallback
(FUSION_PROJECT_DIR still the explicit override; cwd only when git can't report a
toplevel). This is correct from any cwd inside the repo, including a git worktree
(how the engine runs per-task verification). repoRootForExistence is now
redundant and removed; the existence check defaults back to rootDir.

Demonstrated: resolveRepoRoot() from packages/core (no FUSION_PROJECT_DIR) now
resolves the repo root and finds the workspace. +1 regression test. 121/121.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:56:10 -07:00
gsxdsm
e29954e50d Merge remote-tracking branch 'origin/main' into feature/tasks-take-too-long
# Conflicts:
#	scripts/__tests__/test-changed.test.mjs
2026-06-25 22:41:18 -07:00
gsxdsm
c36f234da2 Address PR review feedback (#1785)
- P2 (greptile): anchor the changed-test existence check at the git repo root
  (repoRootForExistence via `git rev-parse --show-toplevel`) instead of rootDir,
  so a script run from a package subdir without FUSION_PROJECT_DIR no longer
  forms a doubled path and silently drops live tests into the delegate path.
  +1 regression test (default root resolves to repo root).
- coderabbit: fix stale "1-worker lane" wording in the delegation log (now
  "heavy memory-envelope lane") and the "single-worker envelope" test title,
  both stale after the 1->4 worker change.

test-changed 118/118, eslint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:30:57 -07:00
gsxdsm
2cff1864c9 fix: bound @fusion/core affected lane + tighten changed watchdog under engine kill
Three changes to make `pnpm test` reliably minimal and fail gracefully:

- @fusion/core is now a memory-envelope/wide-fan-out package (was unguarded).
  It's the hub nearly everything imports (~354 test files), so a core source
  edit made `vitest --changed` expand to ~the whole core suite and blow past the
  engine's 15-min verification kill -> SIGKILL + task restart. Adding it to
  SCOPED_AFFECTED_MEMORY_ENVELOPES applies the wide-fan-out guard (run only
  directly-changed core tests, else delegate) and the bounded env. core is NOT
  gate-covered, so delegation warns loudly rather than false-greens.

- Lower CLASS_BUDGET_BANDS.changed ceiling 20min -> 13min so the script watchdog
  fails a runaway local lane itself (exit 124, no restart) BEFORE the engine's
  15-min kill restarts the whole task. A tightening, not a timeout-widening.
  Guard test pins ceiling < 900_000ms.

- Raise scoped-affected worker fan-out 1 -> 4 (operator decision). Was 1 only
  for OOM safety (FN-6854/FN-6874); the fan-out guard now bounds the set so the
  hundreds-of-files OOM driver no longer reaches these workers. Heap stays
  6144MB/worker (~4x6GB on the lane) — revisit if a RAM-constrained CI runner
  OOMs. Trades FN-5048 worker-knob guidance for throughput, scoped to the
  bounded affected lanes only.

Tests: test-changed 117/117, watchdog 15/15, eslint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 21:42:22 -07:00
gsxdsm
8297762eeb Address PR review feedback (#1780)
- P2: filter directly-changed test files to paths that still exist on disk
  (existingChangedTestFilesInPackage) so deleted/renamed .test paths from
  `git diff` never reach `vitest run` positionally; all-deletions diff falls
  into the delegate-to-gate path.
- P1: make heavy-package delegation gate-coverage-aware
  (GATE_COVERED_MEMORY_ENVELOPE_PACKAGES). Engine delegation keeps the accurate
  "curated engine-core subset ran above" note; dashboard delegation now warns
  that the gate runs no dashboard tests and names the CI full-suite backstop,
  so the coverage gap is loud instead of a silent false-green.
- +4 regression tests (115/115).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:17:56 -07:00
gsxdsm
8754e28868 FN-7026: cap scoped affected test watchdogs
Keep changed-only affected test lanes from outliving the workspace verification timeout.

- Add a scoped affected watchdog ceiling below the default executor timeout.
- Use the ceiling for scoped dashboard and engine affected Vitest lanes while leaving full fallback budget unchanged.
- Cover the timeout derivation and dashboard-only package selection in script tests.
- Document the changed-only watchdog behavior for future test infrastructure changes.

Files changed:
 docs/testing.md                         |  6 +++--
 scripts/__tests__/test-changed.test.mjs | 48 +++++++++++++++++++++++++++++++++
 scripts/test-changed.mjs                | 18 ++++++++++---
 3 files changed, 66 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7026

Fusion-Task-Lineage: 774519e0-505b-4e40-8309-5d2250da1eba
2026-06-25 19:35:46 -07:00
gsxdsm
c5fbe08c00 fix: bound changed-affected test lane to avoid vitest --changed graph blowup
`pnpm test`'s changed-affected lane ran `vitest run --changed <base>` for the
heavy packages (@fusion/engine, @fusion/dashboard). `vitest --changed` does
unbounded transitive module-graph expansion: one changed hub source file
selects ~8,393 test entries (79s just to list), which at the OOM-pinned
workers=1 exceeds the engine's 15-min VERIFICATION_TIMEOUT_WORKSPACE_MS. The
engine SIGKILLs and restarts the task, producing the observed loop of nine
15-min verification timeouts (~2.8h) on a single task.

Guard the lane with a git-only predictor: when a heavy package has changed
non-test source in its graph, run only the directly-changed test files;
when no test files changed, delegate cross-cutting coverage to the merge gate
(already run in changed mode). Test-only diffs keep normal --changed.
Mirrors the existing reverse-dependent blast cap one level down. No widened
timeouts, retries, or worker bumps. test:full remains the explicit full sweep.

Bounded engine run: 2.79s vs 79s. Regression suite 111/111.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:28:15 -07:00
gsxdsm
65a2b3bc72 feat: add test-free verify:fast (typecheck + build + boot-smoke) (#1777)
## 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 -->
2026-06-25 17:24:25 -07:00