Files
fusion/packages/core/package.json
gsxdsm 3da5358b33 test(U9): add a core unit-gate so dependency gating and FN-5819 block merges (#2569)
**U9, PR10.** Two `package.json` lines. No test or production changes —
this only decides *when* existing tests run.

## The gap

Two U9 safeguards are well covered but sat in **no blocking gate**.
Their proof lives in `packages/core/src/__tests__/task-merge.test.ts`,
and core's only gate job is `test:pg-gate` (two PG tests). A regression
in either surfaced in non-blocking full-suite — after the merge.

## What's now gated, each verified by mutation delta

**`task-merge.test.ts`**

| Invariant | Mutation | NEW failures |
|---|---|---|
| Safeguard 3 — dependency gating | `getTaskCompletionBlocker` drops the
unresolved-dependency reason | **5** |
| FN-5819 — exception bounded to a live group | drop `group.status ===
"open"` | **1** |
| FN-5819 — exception bounded to shared members | widen
`isSharedBranchGroupMemberIntegration` to every task | **4** |

Both FN-5819 directions matter. This is the **only** scoped exception to
`autoMerge:false`, so its *narrowness* is the invariant — not merely its
existence. A test that only proves the exception works would pass while
the exception swallowed every task.

**`legacy-adoption.test.ts`**

| Invariant | Mutation | NEW failures |
|---|---|---|
| FN-8492 — orphaned pending results REWRITTEN to failed, never DELETED
| delete instead of rewrite | **2** |

That one matters because deletion *silently satisfies* the merge gate:
the gate blocks on pending/failed results, not on an enabled step with
no result, so deleting lets a task merge with its review skipped.

## Implementation

Adds `packages/core` → `test:unit-gate`, a curated **non-PG allow-list**
mirroring `engine-core`'s discipline (explicit membership, not a glob),
run as a third parallel job in the root `test:gate` block alongside the
engine and PG jobs.

**Gate fires — verified, not assumed:**
- drop the dependency reason → `pnpm test:gate` **exits 1**
- drop the FN-5819 open-group bound → **exits 1**
- restored → **exits 0**

## Cost: no measurable increase

| | Runs |
|---|---|
| baseline | 13.07s, 14.95s |
| with the job | 12.20s, 12.58s |

It runs in parallel with the existing jobs and finishes well inside
them, so the delta sits inside run-to-run variance. **I am not claiming
a speedup** — the honest reading is "no measurable cost", and the
variance band here is wider than the change.

## Reversible call made rather than asked

A new `test:unit-gate` script rather than widening `test:pg-gate` or
adding a glob. `test:pg-gate` carries PG setup these pure unit tests do
not need, and a glob would admit all of core by default — which
AGENTS.md explicitly forbids ("tests never graduate into the gate by
default"). Membership stays explicit so the next addition has to state
its evidence.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 10:08:29 -07:00

82 lines
2.5 KiB
JSON

{
"name": "@fusion/core",
"version": "0.74.0-beta.5",
"license": "MIT",
"description": "Fusion core: task store, scheduler, settings, and shared domain types backing the Fusion AI coding agent.",
"homepage": "https://github.com/Runfusion/Fusion#readme",
"repository": {
"type": "git",
"url": "https://github.com/Runfusion/Fusion",
"directory": "packages/core"
},
"bugs": {
"url": "https://github.com/Runfusion/Fusion/issues"
},
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"source": "./src/index.ts",
"import": "./dist/index.js"
},
"./gh-cli": {
"types": "./src/gh-cli.ts",
"source": "./src/gh-cli.ts",
"import": "./dist/gh-cli.js"
},
"./task-delete-attribution": {
"types": "./src/task-delete-attribution.ts",
"source": "./src/task-delete-attribution.ts",
"import": "./dist/task-delete-attribution.js"
},
"./detect-content-language": {
"types": "./src/detect-content-language.ts",
"source": "./src/detect-content-language.ts",
"import": "./dist/detect-content-language.js"
},
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public"
},
"files": [
"dist",
"README.md"
],
"scripts": {
"build": "tsc",
"typecheck": "tsc --noEmit",
"test": "vitest run --silent=passed-only --reporter=dot",
"test:embedded-postgres": "vitest run src/__tests__/postgres/embedded-lifecycle.test.ts --silent=passed-only --reporter=dot",
"test:pg-gate": "vitest run --config vitest.pg.config.ts src/__tests__/postgres/handoff-to-review-atomicity.pg.test.ts src/__tests__/postgres/task-lifecycle-e2e.pg.test.ts --silent=passed-only --reporter=dot",
"test:unit-gate": "vitest run src/__tests__/task-merge.test.ts src/__tests__/legacy-adoption.test.ts --silent=passed-only --reporter=dot"
},
"devDependencies": {
"@earendil-works/pi-coding-agent": "0.82.1",
"@types/dockerode": "^3.3.41",
"@types/node": "^25.5.0",
"@vitest/coverage-v8": "^4.1.10",
"typescript": "^5.7.0",
"vitest": "^4.1.10"
},
"engines": {
"node": ">=22.5.0"
},
"private": true,
"dependencies": {
"bonjour-service": "^1.3.0",
"check-disk-space": "^3.4.0",
"cron-parser": "^5.5.0",
"dockerode": "^4.0.2",
"drizzle-orm": "^0.45.2",
"embedded-postgres": "15.18.0-beta.17",
"extract-zip": "^2.0.1",
"postgres": "^3.4.9",
"tar": "^7.5.13",
"yaml": "^2.8.3"
},
"optionalDependencies": {
"keytar": "^7.9.0"
}
}