Repository navigation
WolverineFx.Bobcat takes the Critter Stack vocabulary, Bobcat's samples and the spec writer (#5082) - #5083
Merged
Conversation
GH-5082) Bobcat 1.0.0-rc.2 (JasperFx/bobcat#755) drops every JasperFx, JasperFx.Events and Wolverine dependency from core, so the store-agnostic vocabulary moves here, keeping its namespaces: - src/Bobcat/Wolverine.Bobcat/CritterStack: CritterStackScenario, CritterStackSpec, CritterStackActOutcome, EventStores, DocumentStores, StoreRouting, EventStoreAuthoring, CritterStackHostExtensions, ProjectionsBehind and the two timeout exceptions (Bobcat.CritterStack). RecordBuilding stays in core. - EventModel/GeneratedEventModel and SpecIdentityAudit (Bobcat). - Preflight.AddContainerChecks, now an extension method over Bobcat's Preflight (JasperFx's EnvironmentChecker), so a call site reads as before. - [EventModelTrigger(TriggerKind.Http, ...)] is [EventModelTrigger(ActTrigger.Http, ...)]. One core internal is reached by reflection until Bobcat exposes it: RecordedStep.Failure has an internal setter, and recordTimedOutAct (bobcat#673) sets it on the open When step. Tests: Bobcat.CritterStackScenario.Tests moves beside Wolverine.Bobcat.Tests (Marten on this repo's Postgres through Servers, Fisher on temp SQLite, [PostgresFact] never skipping with CI=true), now on net9.0 and net10.0 and in CIBobcat. The SpecIdentityAudit tests and CritterStackSpecRoleTests move into Wolverine.Bobcat.Tests, the role specs compiled as this assembly's own projected specs. Running them on net9.0 exposed an order-dependent bug the net10.0-only Bobcat run never hit: a tenant's first read in a fresh schema threw Marten's immediate "No event activity was detected" (the #497 empty-store case, fixed then for the untenanted wait only). The tenant wait now returns at once when the tenant's own view holds no events on a single-database store. Bobcat comes from a local preview feed (NuGet.config, 1.0.0-rc.2.local.1) until rc.2 publishes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk
…em (GH-5082) All 13 samples from the Bobcat repository (JasperFx/bobcat#755) land in src/Samples/Bobcat with their README, sample-projects.md, docker-compose.yml, init scripts and LICENSE. They are written against the Critter Stack vocabulary that now ships in WolverineFx.Bobcat. - They reference this repository's Wolverine projects (and WolverineFx.Bobcat) by ProjectReference, the way src/Samples consumes Wolverine, and Bobcat, Bobcat.Xunit and Bobcat.Generators as packages, so the packages' buildTransitive props apply as for any consumer. Directory.Build.props adds those four to every Tests project. - Directory.Packages.props imports the repository's own, so the samples run on exactly its Marten, Fisher, JasperFx.Events, xUnit and Alba. Only the Aspire packages and Wolverine.CritterWatch are pinned there; CritterWatch moves from a local-feed 1.0.2-vehicle.1 to the published 1.1.0-rc.1, whose WolverineFx 6.51.0 dependency the ProjectReference satisfies, and BankAccountES's NuGet.config goes. - build/BobcatSamples.cs carries Bobcat's Samples targets as CompileBobcatSamples, TestBobcatSamples (one Postgres database per sample, on this repo's docker-compose Postgres, 5433) and TestBobcatSamplesOnFisher (BankAccountES on a SQLite file). bobcat-samples.yml runs BobcatSamples. - BankAccountES's TriggerKind becomes ActTrigger. Its EventModel specs pinned wolverine#4975's Query-vs-View disagreement so that the fix would turn them red, and against this repository's Wolverine it did: the GET slices now assert a Query reading its response type, with no disagreement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk
…l --specs (GH-5082) Bobcat keeps importing an eventmodelers.ai board as stubs and EventModelDefinitions; writing WolverineFx.Bobcat specifications for the board's examples moved here with the vocabulary they are written against (JasperFx/bobcat#755). New package WolverineFx.Bobcat.EventModel (src/Bobcat/Wolverine.Bobcat.EventModel): - EmlangSpecWriter and SpecProjectWriter from Bobcat.EventModel, the specification arm of its additive merge (SpecMerge: MergeSpecs, MergeGlobalUsings) and of ImportFileWriter (SpecFileWriter.WriteSpecs), with the same callout codes. - The write-specs JasperFx command, next to scaffold: an application referencing the package runs `dotnet run -- write-specs board.json`. It keeps the flags --specs-out, --specs-namespace, --app-project, --store, --bobcat-version and --wolverine-version, plus the import's --model, --namespace, --out, --chapter, --aggregate, --starts-stream, --strong-typed-ids, --single-definition, --json and --force, and merges into the stubs only what the specifications need. - A generated spec project pins WolverineFx.Bobcat to this package's own version and Bobcat to the version it was built against (stamped from Directory.Packages.props), instead of constants moved by hand. Bobcat.EventModel 1.0.0-rc.2 keeps three members internal that the writer used. EventModelInternals reaches CuratedScenario.Source/SourceChapter and CuratedFieldTypes.TryInfer by reflection, and copies the trivial EmlangReader.Text, until Bobcat makes them public; it is the one file to delete then. Tests (Wolverine.Bobcat.EventModel.Tests): EmlangSpecWriterTests, SpecProjectWriterTests and DeclaredIdentityTests, the specification halves #755 cut from the import tests, the spec-merge arm of ImportMergeTests plus the idempotency and --force cases for specifications, and write-specs end to end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk
The test JasperFx/bobcat#755 deleted from Bobcat's TagsAndStrongTypedIdsTests, beside the store-only vocabulary's other tests, with its own tag types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk
…tion bridges Bobcat rc.2 made RecordedStep.Failure, CuratedScenario.Source/SourceChapter, CuratedFieldTypes and EmlangReader.Text public (JasperFx/bobcat#755), so EventModelInternals and failStep go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk
jeremydmiller
marked this pull request as ready for review
October 19, 2026 20:07
jeremydmiller
added a commit
that referenced
this pull request
Oct 19, 2026
…ead spec starts with no Appointments The body-less HTTP acts' [EventModelTrigger] take Bobcat's ActTrigger since #5083 moved to Bobcat 1.0.0-rc.2. modeled_read_models.a_single_read_model_needs_a_stream_to_be_about passed only when the collection's other specs left zero or several Appointments behind; it now clears them first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk
This was referenced Oct 21, 2026
This was referenced Oct 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bobcat 1.0.0-rc.2 (JasperFx/bobcat#755) drops every JasperFx, JasperFx.Events and Wolverine dependency from Bobcat core. The pieces that need them move here, as the design of record (
design/jasperfx-decoupling.mdin Bobcat) decided.Refs #5082, JasperFx/bobcat#755
What moves, and where it lands
The Critter Stack vocabulary → WolverineFx.Bobcat (
src/Bobcat/Wolverine.Bobcat), namespaces unchanged (Bobcat.CritterStack,Bobcat), so a consumer's source does not change:CritterStack/:CritterStackScenario,CritterStackSpec,CritterStackActOutcome,EventStores,DocumentStores,StoreRouting,EventStoreAuthoring,CritterStackHostExtensions,ProjectionsBehindand the two timeout exceptions.RecordBuildingstays in Bobcat core.EventModel/:GeneratedEventModel,SpecIdentityAudit.Preflight.AddContainerChecksis now an extension method over Bobcat'sPreflight(PreflightContainerChecks), still delegating to JasperFx'sEnvironmentChecker.[EventModelTrigger(TriggerKind.Http, …)]→ActTrigger.Http. Nothing here usedJasperFx.Testing.DispositionKindor the recovery-hint attributes, and nothing usedEnvironmentCheckResults.Tests
Bobcat.CritterStackScenario.Tests→src/Bobcat/Bobcat.CritterStackScenario.Tests, now net9.0 and net10.0. Marten runs on this repo's docker-compose Postgres throughServers, Fisher on a temp SQLite file, and[PostgresFact]still never skips whenCI=true. It is inwolverine.slnxandCIBobcat.SpecIdentityAuditTests(the pure one and the end-to-end one withSliceIdentitySpecs) andCritterStackSpecRoleTests→Wolverine.Bobcat.Tests. The role specs used to be compiled in a generator harness. Here they are this assembly's own projected specs ([Fact(Explicit = true)]), read throughGeneratedEventModel.EventTagQueryDescriptionTests→Bobcat.CritterStackScenario.Tests, besideEventStores.Describe.The samples →
src/Samples/Bobcat. All 13, plus README, sample-projects.md, docker-compose.yml, init/ and LICENSE.ProjectReferences, the waysrc/Samplesdoes.Directory.Packages.propsimports the root one, so the Critter Stack versions are this repo's.1.0.2-vehicle.1to the published1.1.0-rc.1.build/BobcatSamples.cshasCompileBobcatSamples,TestBobcatSamples(one Postgres database per sample, on 5433) andTestBobcatSamplesOnFisher..github/workflows/bobcat-samples.ymlruns./build.sh BobcatSamples.Bobcatprefix becauseTestSamplesalready exists here.The spec writer → new package WolverineFx.Bobcat.EventModel (
src/Bobcat/Wolverine.Bobcat.EventModel), with thewrite-specsJasperFx command next toscaffold.EmlangSpecWriter,SpecProjectWriter, the spec arm ofImportMerge(SpecMerge) and the spec arm ofImportFileWriter.WriteSpecs(SpecFileWriter).dotnet run -- write-specs board.json(checked: it appears inhelpin BankAccountES).--specs-out,--specs-namespace,--app-project,--store,--bobcat-version,--wolverine-version), plus the import flags the writer needs. It merges into the stubs only the members the specs need.Directory.Packages.props.Wolverine.Bobcat.EventModel.Tests.Findings worth a look
RecordedStep.Failure's setter,CuratedScenario.Source/SourceChapter,CuratedFieldTypes,EmlangReader.Text), so they are called directly.Merge order
Bobcat 1.0.0-rc.2 is published and this branch restores it from nuget.org (the temporary
NuGet.configis gone). Against rc.1 the vocabulary types would be declared twice (CS0433), so this needs rc.2 or later.[EventModelTrigger(TriggerKind.Http, …)]attributes; whichever merges second renames those toActTrigger.Http.On rc.2 from nuget.org, run per framework (both frameworks at once share Marten schemas locally and collide; CI runs one framework per target): Wolverine.Bobcat.Tests 223 passed / 8 skipped on each of net9.0 and net10.0, Bobcat.CritterStackScenario.Tests 208/208 on each, Wolverine.Bobcat.Http.Tests 43/43, Wolverine.Bobcat.EventModel.Tests 156 passed / 2 skipped.
Verified locally
dotnet build wolverine.slnx -c Release -f net9.0and the unpinned build: 0 errors../build.sh CIBobcat --framework net9.0with CI=true:./build.sh BobcatSamples: every sample project compiles, every runnable sample's specs pass, and BankAccountES passes on Fisher (24/24).🤖 Generated with Claude Code
https://claude.ai/code/session_01YDKQhnBVcmVLCTkJbVeADk