# @systemfsoftware/effect-gherkin-spec

## 7.0.1

### Patch Changes

- Updated dependencies:
  - @systemfsoftware/vitest@2.0.0

## 7.0.0

### Major Changes

- Require `effect` `^4` (stable 4.0.0). Release candidates are no longer supported: imports follow 4.0.0's module layout (`effect/http`, `effect/rpc`, `effect/http-api`, `effect/cluster`, `effect/process`, `effect/socket`, `effect/persistence`, `effect/reactivity`, `effect/encoding`, `effect/Arbitrary`), which does not exist in any 4.0.0 RC.

### Patch Changes

- Updated dependencies:
  - @systemfsoftware/effect-spec-runtime@1.0.0
  - @systemfsoftware/vitest@1.0.0

## 6.0.1

### Patch Changes

- Updated dependencies:
  - @systemfsoftware/vitest@0.3.0

## 6.0.0

### Major Changes

- The lawful test runner is now a peer dependency under its own name, `@systemfsoftware/vitest`, instead of the `@effect/vitest` alias that pointed at it. Install `@systemfsoftware/vitest` and import `it`, `layer`, `expect`, and the rest from `@systemfsoftware/vitest`. `@systemfsoftware/effect-gherkin-spec` re-exports `it` and `layer` from `@systemfsoftware/vitest`.

- Live cases now declare a required reason, and every other scenario runs on the simulation kernel under the profile's seeded schedules.

  - `Feature('...').liveClock()` → `Feature('...').live('the reason it waits on real I/O')`, at every builder stage.
  - `FeatureLayerOptions` is gone: `withLayer(shared, opts)` → `withLayer(shared)`.
  - `makeFeature` takes bindings with only `it`: `makeFeature({ it, layer })` → `makeFeature({ it })`.
  - One scenario or outline stays live through its own options: `scenario('...', { live: 'why it needs the real clock' }, pipeline)`, where `live` is a reason string, not a boolean.

  The package re-exports only `it` and `layer` from `@effect/vitest`; import anything else from `@effect/vitest` directly.

### Minor Changes

- `StepError` now has a message naming the keyword, the resolved step text and a summary of the cause, for example `Given "a user logs in" failed: Unauthorized {"user":"bob"}`, and its stack leads with the spec line that wrote the step. Steps are recorded as spans, so a failing scenario reports which steps passed and which failed.

- `Then`, `And` and `But` bodies take `(state, expect)` and return exactly one check (or an Effect of one); `expect` is no longer imported from `@effect/vitest`. Only `Given` and `When` open a new observed state, so a `Then` followed by an `And` or `But` on the same state is refused: merge the facts into one `Then` over a record. `Then.soft`, `Then.poll` and `When.poll`, with their `And`/`But` forms, are removed, as are `checkSoftFailures`, `owned` and `recordAssertion`. A background pipeline may carry the check service.

### Patch Changes

- Update peer and runtime dependency on `effect` and companion packages to `4.0.0-rc.117`.

- Updated dependencies:
  - @systemfsoftware/vitest@0.2.0

## 5.0.0

### Minor Changes

- `Then`, `And` and `But` bodies take `(state, expect)` and return exactly one check (or an Effect of one); `expect` is no longer imported from `@effect/vitest`. Only `Given` and `When` open a new observed state, so a `Then` followed by an `And` or `But` on the same state is refused: merge the facts into one `Then` over a record. `Then.soft`, `Then.poll` and `When.poll`, with their `And`/`But` forms, are removed, as are `checkSoftFailures`, `owned` and `recordAssertion`. A background pipeline may carry the check service.

### Patch Changes

- Updated dependencies:
  - @systemfsoftware/vitest@0.1.0

## 4.4.0

### Minor Changes

- Requires `@systemfsoftware/vitest` installed under the `@effect/vitest` name (`"@effect/vitest": "npm:@systemfsoftware/vitest"`) in place of the upstream package. A scenario whose steps all pass counts as asserted, a failing `expect` inside a step fails that step, and a feature's layer is built once and shared by its scenarios.

### Patch Changes

- Updated dependencies:
  - @systemfsoftware/effect-spec-runtime@0.2.0

## 4.3.1

### Patch Changes

- Update peer and runtime dependency on `effect` and companion packages to `4.0.0-rc.117`.

## 4.3.0

### Minor Changes

- Feature runtime, outline expansion, do-notation, case-layer and pairwise helpers that took their subject first can now also be called data-last. Existing calls keep working.

### Patch Changes

- Updated dependencies:
  - @systemfsoftware/effect-spec-runtime@0.1.0

## 4.2.3

### Patch Changes

- `VitestTaskRef` is now the task reference owned by `@systemfsoftware/effect-spec-runtime`, so its context key changed from `@systemfsoftware/effect-gherkin-spec/VitestTask` to `@systemfsoftware/effect-spec-runtime/VitestTask`. Code that imports `VitestTaskRef` from this package is unaffected; code that re-declared a reference under the old key no longer receives the running test's task. Every exported type, the stage vocabulary, and every other runtime behaviour are unchanged.

## 4.2.2

### Patch Changes

- Unconstrained type holes are defaulted type parameters (`<A = unknown>`) instead of a type argument `unknown`. Calls that omit those arguments are unchanged.

## 4.2.1

### Patch Changes

- Bump the stryker catalog to pull in the latest patch releases of the stryker-js ecosystem.

## 4.2.0

### Minor Changes

- Add compile-time BDD stage validation, Then.soft composite assertions, polling step combinators, Effect equality tester integration, and Vitest task reporting

## 4.1.0

### Minor Changes

- These packages now peer-depend on Vitest 5. Install `vitest` ^5; Vitest 4 is unsupported.

## 4.0.2

### Patch Changes

- Releases the workspace so its published versions track the shared dependency graph this change moves.

- The `@systemfsoftware/source` export condition is gone. It resolved to a package's TypeScript sources for editors and in-repo typechecks; each package now exports only its built entry. If your tsconfig sets `customConditions: ["@systemfsoftware/source"]`, or a bundler config names that condition, remove it — resolution falls back to the built entry, which is what every consumer already got.

## 4.0.1

### Patch Changes

- Peer Effect requirement advances to 4.0.0-rc.112. No API changes.

## 4.0.0

### Major Changes

- AtomRuntime.fn now infers precise success and error types from the function you pass, in both direct and curried forms. Values that are not functions are rejected at compile time; previously they failed when the resulting atom was first read.

  withScope now requires scope bindings to be effects with no service requirements. Bindings that require services no longer compile — provide those services with withLayer and read them inside steps instead.

  onToolResult now fails with PlatformError instead of an untyped error.

### Patch Changes

- Re-published against the oxc-based instrumenter: workspace dependency ranges move to the new instrumenter major; no package's own behavior changes in this release.

## 3.0.0

### Major Changes

- Scenario titles are now enforced as prose at the type level: `scenario` and `scenarioOutline` reject any title that either starts with "Should" (the `Should_[Behavior]_When_[Condition]` unit-test naming convention) or lacks an ASCII space between words (every concatenated-token shape — PascalCase, snake_case, CamelCase — that reads as a unit-test name rather than prose). A rejected title fails to type-check with the rule in the diagnostic. Titles that are not string literals are unaffected.

## 2.0.2

### Patch Changes

- Peer Effect requirement advances to 4.0.0-rc.112. No API changes.

## 2.0.1

### Patch Changes

- The peer requirements for `effect` and for the Effect test-runner integration now accept any compatible `4.0.0-rc` release, instead of demanding one exact release candidate.

  Installing alongside a newer release candidate no longer reports an unmet peer dependency or resolves a second copy of `effect` into the dependency tree.

## 2.0.0

### Major Changes

- Collapse projection tags into the ports they projected

  A `*ExecutorDeps` tag whose service type was indexed off other ports recorded which members
  one operation happened to reach for. Exporting it turned internal composition into a surface
  commitment: a consumer had to discover and provide an aggregator for each operation, where the
  port it came from already served. The tags rode the `R` channel of exported signatures, so a
  consumer met them only at their own call site.

  Each was removed the way its evidence directed — no tag was renamed, and none was replaced:

  - `AttwCliExecutorDeps`, `CheckPackageExecutorDeps` — deleted. Zero consumers, no Live layer;
    callers already required the real capabilities directly.
  - `HookDispatcherExecutorDeps` — was a 1:1 alias of `Scope.Scope`. Requiring `Scope` names the
    same service.
  - `InjectInstructionsExecutorDeps` — packed `FileSystem`, `Path` and `TomlLoader` with no logic.
    Consumers require the three ports.
  - `EffectVitestDeps` → `EffectVitestBindings`. Never a `Context.Tag`: a plain type alias already
    passed as an ordinary parameter, so only the name misdescribed it. A stale api report that no
    `api-extractor` regenerates was deleted with it.

  A consumer providing a port instead of an aggregator provides no more than before, since a
  service `{ a, b }` is assignable to a requirement `{ a }`.

### Minor Changes

- cut over to effect v4 (4.0.0-rc.108): public surface derives from effect types; peers flip effect ^3→^4

### Patch Changes

- Array types are spelled one way. `Array<T>` and `ReadonlyArray<T>` in emitted
  declarations become `T[]` and `readonly T[]`, which the type checker cannot tell
  apart: no exported type changes, only how it is written.

- New version is published through npm trusted publishing, so it carries a provenance attestation you can verify.

- Fix two `test:types` scripts that could not pass.

  `tstyche` exits 1 with "No test files were selected using current configuration" when nothing matches
  `testFileMatch`, so a watcher pointed at files that do not exist is a script guaranteed to fail the
  moment anyone runs it. Measured directly: `effect-gherkin-spec`'s `tstyche.json` matched
  `src/**/*.tst.ts` and the package holds no such file, so its `test:types` script is removed rather than
  left as a gate attached to nothing. `stryker-plugins` now pins `TSTYCHE_TYPESCRIPT_MODULE` so its own
  `test:types` resolves the TypeScript module it needs.

  Both packages publish, and both scripts ship in the published `package.json`, so a consumer inspecting
  or running them sees the change — a real patch rather than an empty intent.

## 1.0.0

### Major Changes

- Collapse projection tags into the ports they projected

  A `*ExecutorDeps` tag whose service type was indexed off other ports recorded which members
  one operation happened to reach for. Exporting it turned internal composition into a surface
  commitment: a consumer had to discover and provide an aggregator for each operation, where the
  port it came from already served. The tags rode the `R` channel of exported signatures, so a
  consumer met them only at their own call site.

  Each was removed the way its evidence directed — no tag was renamed, and none was replaced:

  - `AttwCliExecutorDeps`, `CheckPackageExecutorDeps` — deleted. Zero consumers, no Live layer;
    callers already required the real capabilities directly.
  - `HookDispatcherExecutorDeps` — was a 1:1 alias of `Scope.Scope`. Requiring `Scope` names the
    same service.
  - `InjectInstructionsExecutorDeps` — packed `FileSystem`, `Path` and `TomlLoader` with no logic.
    Consumers require the three ports.
  - `EffectVitestDeps` → `EffectVitestBindings`. Never a `Context.Tag`: a plain type alias already
    passed as an ordinary parameter, so only the name misdescribed it. A stale api report that no
    `api-extractor` regenerates was deleted with it.

  A consumer providing a port instead of an aggregator provides no more than before, since a
  service `{ a, b }` is assignable to a requirement `{ a }`.

### Minor Changes

- cut over to effect v4 (4.0.0-rc.108): public surface derives from effect types; peers flip effect ^3→^4

### Patch Changes

- Array types are spelled one way. `Array<T>` and `ReadonlyArray<T>` in emitted
  declarations become `T[]` and `readonly T[]`, which the type checker cannot tell
  apart: no exported type changes, only how it is written.

- New version is published through npm trusted publishing, so it carries a provenance attestation you can verify.

- Fix two `test:types` scripts that could not pass.

  `tstyche` exits 1 with "No test files were selected using current configuration" when nothing matches
  `testFileMatch`, so a watcher pointed at files that do not exist is a script guaranteed to fail the
  moment anyone runs it. Measured directly: `effect-gherkin-spec`'s `tstyche.json` matched
  `src/**/*.tst.ts` and the package holds no such file, so its `test:types` script is removed rather than
  left as a gate attached to nothing. `stryker-plugins` now pins `TSTYCHE_TYPESCRIPT_MODULE` so its own
  `test:types` resolves the TypeScript module it needs.

  Both packages publish, and both scripts ship in the published `package.json`, so a consumer inspecting
  or running them sees the change — a real patch rather than an empty intent.
