### Prescriptive Structural Syntax

I am sorry but I actually prefer the other style of specification! The main reason is that I think that encourages me 
to think about writing some text about what I am testing, and why I am testing it this way 
(that doesn't mean that I necessarily do it :-)).

### Enforced Matcher Uniformity

I hear you and I indeed simplified all `must` expressions to be `a must b`, and then `a must not(b)`.

### Better Matcher Construction

I have added a bunch of `Matcher.apply` functions but also simplified the `Matcher` data type which does not longer 
return a `MatchResult[T]` but simply a `Result`. The reason for having the intermediate `MatchResult[T]` data type 
was to keep the actual value around and to have both a success and a failure message which could be switched when 
calling `not(matcher)`.

It turns out that it is really hard to compose failure messages when trying to create matchers from other 
matchers so I gave up on that. I eventually think that it is easier to reuse the success/failure logic of 
other matchers but draft your own message for a custom matcher.

### First-Class Support for Async Tests

specs2 now supports `Future[T]` as the body of a test, as long as `T` has a `AsResult[T]` instance. 
But more generally there is an `AsExecution` typeclass which can be used to transform the body of any async example 
using cats `IO` or `ZIO` to a specs2 `Execution`. The cats `IO` integration itself has now be put in a separate 
[specs2-cats project](https://github.com/etorreborre/specs2-cats).

### Async ScalaCheck

The support for ScalaCheck in specs2 is a bit convoluted and while I think it should be possible to do something 
for async properties I haven't tried yet.

### Better Support for things like Discipline

I would need a concrete test project showing one of the issues. It seems to me that Discipline
is doing to the right thing by creating one example per property. Then everything else should behave like a normal
specification with sequential execution if `sequential` is set etc...

The seed issue could be a bug due to the way I am capturing the actual seed being used to report it. That's something I can
definitely investigate if you have a way to reliably reproduce the problem.

### Better Support for Test Abstraction

You can add / remove fragments even with a mutable specification. To do this you can override the inherited
`map` or `flatMap` functions:

```
  /** modify the whole list of fragments */
  def map(fs: =>Fragments): Fragments = fs

  /** modify each fragment to expand it into a list of fragments */
  def flatMap(f: Fragment): Fragments = Fragments(f)
```

Would that help for what you'd like to do?

### Slightly Saner pendingUntilFixed/etc Combinators

This one might be a naming thing. `pending` and `skipped` are `Results` while `pendingUntilFixed` is a way to modify the execution of a `Result`.
If that helps I have added the possibility to use the `pendingUntilFixed` method as a prefix method 
(also available in the next specs2-4.x version):
```
"example 1" >> pendingUntilFixed {
  1 === 2
}

"example 1" >> pendingUntilFixed("ISSUE-123") {
  1 === 2
}
```

Maybe this is "slightly saner" :-)?

### Integrated Lifecycle Management

Indeed `before/after` methods are very "side-effecty". In this new version of `specs2` there is a `Resource[T]` trait 
which can be used to declare a resource available to all the examples a specification.

For example you can mix the following trait to your specification:
```
trait DbConnection(using ec: ExecutionContext) extends Resource[Connection]:
  def acquire: Future[Connection] =
    ??? // create a new connection

  def release(connection: Connection): Execution = Execution.future {
    connection.close.map {
      case Right(_) => success
      case Left(e) => anError(e)
    }
  }  

class MySpec(using ec: ExecutionContext) extends mutable.Specification, DbConnection:
  "use a database connection" >> { (c: Connection) =>
     c.executeSql("SELECT COUNT(*) FROM TABLE").map { n => n must be_>=(10) }
  }
```

You can even share that resource across several specifications by giving it a resource key:
```
trait DbConnection(using ec: ExecutionContext) extends Resource[Connection]:
  override def resourceKey: Option[String] =
    Some("DB connection")

  def acquire: Future[Connection] =
    ...

  def release(connection: Connection): Execution =
    ...
```

Then the `release` method will only be called at the end of a run.