Spec 017 phase 5: tranche 2b and the recorded falsehoods — 295 blocks build, both targets met - #194
Merged
Merged
Conversation
…ard block Nine gates at 976e0e0, all exit 0. BUILT 234 -> 246..294; the floor is 4 short of >= 250. Pages with nothing BUILT 57 -> at most 51, as low as 45. pagelint 616 -> 582..573 before P0-7. attr_mismatch 7 -> 1 (PipelineValidation.md:250); ITimerProvider 4 -> 0. The tranche reads 15 hard, not 16: task 2.4's UseEndpoints repair left BrighterControlAPI.md #1 needing only an `app` stub. Hard blocks read as 5 parse, 10 other (six defects, verified at 10.7.0 / Darker 4.1.1), recurrences run. The [RetryableQuery] ledger grep said 9 lines; any second argument finds 20. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…tranche pages Ten tranche pages repaired, and the recurrences their defects reach on eight more: - BuildingAPipeline.md: the pre-V10 logging handler rewritten against 10.7.0; `.Successor =` is `SetSuccessor()`; how a custom generic pipeline handler is registered, run with controls - AgreementDispatcherRouting.md, AgreementDispatcher.md, FAQ.md: "cannot use AutoFromAssemblies" is false — pass the route's handlers in `excludeDynamicHandlerTypes` - DarkerConfigurationReference.md, DarkerBasicConfiguration.md: the query processor defaults to Singleton, not Transient, and the unscoped failure is a root-provider resolution, not a disposed DbContext; `Activator.CreateInstance` cast to Darker's factory types (and on ImplementAQueryHandler.md) - [RetryableQuery]'s second argument is the one policy the decorator runs: QueryPipeline.md, QueryPatterns.md, CQRSWithBrighterAndDarker.md, ImplementAQueryHandler.md, DarkerAndBrighterPipelines.md; QueryPipelinePolicies.md shows a retry wrapped round a breaker - HowConfiguringTheDispatcherWorks.md: V10's MessageMapperRegistry; RmqSubscription<T> defaults to Reactor - The Darker query-pattern pages, CQRSUseCasesAndPatterns.md: usings, whole blocks, and six scaffold units for the types the pages never show Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
28 rows at 1cafef9, and three re-admissions: ParameterizedQueryPatterns.md #3, #5 and ProjectionQueryPatterns.md #4, BUILT before and now compiled with DarkerQueryPatternsContext.cs. --report: exit 0, 985 blocks: 262 BUILT, 706 FAILED, 17 SKIPPED; 40 units, 0 violations. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
BUILT 234 -> 262; pagelint 616 -> 599; pages with nothing BUILT 57 -> 49. Nine defects and the carried [RetryableQuery] row in the ledger, twelve blocks listed as staying FAILED, one split, and four findings off the tranche put to the maintainer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…ched - Monitoring.md rewritten for V10: MonitorConfiguration and a control bus sender in the container, [Monitor] on the handler, the message format captured from a run, and two 10.7.0 defects stated (a throwing handler's exception is replaced; [MonitorAsync] cannot send through ControlBusSenderFactory's sender) - HowConfiguringTheDispatcherWorks.md: Topshelf retired; the Dispatcher run from a console app until Ctrl+C, End() letting the pump finish its message - Handlers declared without `public`: 18 on 6 pages made public, and CommandProcessorConfigurationReference.md says the scan finds only public handlers - DarkerBasicConfiguration.md: Darker's scan takes exported types; names and nesting in a public class do not matter - Found by --explain on the blocks those touched: [UseResiliencePipeline] stacked on one method (CS0579) on five pages, now one composed pipeline; Polly v8's first strategy is the outermost, so MyComprehensivePipeline ran its timeout around all its retries; a FeatureSwitches.md handler awaited without `async` Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
HowConfiguringTheDispatcherWorks.md #3 and Monitoring.md #1, #2. --report: exit 0, 985 blocks: 265 BUILT, 703 FAILED, 17 SKIPPED. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
BUILT 262 -> 265; pagelint 599 -> 585; pages with nothing BUILT 49 -> 48. Seven defect rows, two of them upstream and stated, filing put to the maintainer. The Topshelf row leaves § Blocks that stay FAILED: the block builds. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
… repaired Work in progress, not yet gated: baseline rows, tasks.md records, the S3 ACL fix and the carried 5.1 items are still to come. - PostgreSQLMessageBroker.md: consumer channelName must equal the publication Topic; PostAsync, not PublishAsync, reaches the table; scheduled messages go through the scheduler, visible_timeout delays only a requeue; outbox deposit takes the transaction provider; claim check on a mapper; messagePumpType on every subscription; SQL no longer names a created_at column - PostgreSQLBrokerTradeOffs.md: JSONB/JSON fence split; message size measured (50 MB round-trips, 150 MB rejected); SQS 1 MiB - CloudEventsReference.md, CloudEventsSupport.md: header names as captured from RabbitMQ and Kafka; the mapper chooses the content mode; Kafka partition key from the request context; souce, #4458 - Telemetry.md, ConfiguringOpenTelemetry.md: spans need a registered tracer (AddBrighterInstrumentation); tables rewritten from captured spans; Jaeger exporter replaced by OTLP - S3LuggageStore.md: link label, IHttpClientFactory, list nesting - Units for BrighterControlAPI, CloudEventsReference, PostgreSQL (both pages) and Telemetry Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…er members - S3LuggageStore.md, HandlingLargeMessages.md: ACLs has no default; a missing bucket with none set throws ConfigurationException (run on LocalStack, with a control that sets ACLs and creates the bucket) - BrighterControlAPI.md: list un-indented; response captured from a V10 Dispatcher; availableTopics/topicName are subscription names; PATCH takes the subscription name, case-sensitive; custom base route run - KafkaConfiguration.md, MessageMappers.md: MessageBody takes a ContentType, not a string (as the KafkaSchemaRegistry sample does) - Routing.md, V10MigrationGuide.md, NullableReferenceTypes.md: mappers gain the member they were missing - Command/Event subclasses with no base constructor call given one; V10MigrationGuide's default-mapper example posts rather than publishes (run: PostAsync puts one JSON message on the bus, PublishAsync none) - Unit S3LuggageStoreContext.cs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…built 24 blocks appended; PostgreSQLMessageBroker.md #11 and Telemetry.md #4 re-admitted with their units; Telemetry.md #1 and #4's rows removed, the blocks now at #2 and #5 after the insertion above them. 288 required. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
- FAQ.md #7: MapToMessage returned nothing and MapToRequest was missing; the mapper now maps both ways, [RetrieveClaim] on the way back - PostgreSQLMessageBroker.md, PostgresOutbox.md: the EF Core transaction provider brings the target framework's EF Core, so Npgsql's EF provider must match (9.x on net10.0 → MissingMethodException, run in session 101) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…recorded BUILT 265 → 288; pagelint 585 → 562; pages with nothing BUILT 48 → 44. The maintainer's five rulings; 23 defect ledger rows; seven blocks that stay FAILED on the pin; a split and two insertions; the Jaeger block removed. Three questions put to the maintainer. 31 of 42 tasks ticked. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
99 PackageReferences, 543 reference assemblies. FakeTimeProvider is what InMemoryScheduler.md's rewritten ITimerProvider block (task 5.4) sets as the scheduler's clock. Measured alone, no page changed: 987 blocks, 288 BUILT, and no verdict moves. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
100 PackageReferences, 545 reference assemblies (Avro.dll and the serdes). The Avro serializers DefaultMessageMappers.md's rewritten mapper calls (task 5.4, the maintainer's ruling on the Avro block), at 2.15.0, the Confluent release Paramore.Brighter.MessagingGateway.Kafka 10.7.0 depends on. Measured alone, no page changed: 987 blocks, 288 BUILT, and no verdict moves. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…shAsync InMemoryScheduler.md: ITimerProvider 4 -> 0. The scheduler creates its timers from InMemorySchedulerFactory.TimeProvider; block #5 is now a FakeTimeProvider test, run with controls (advance 5m -> handled before Advance returns; none, 4:59 and 2.5s wall clock -> not). The package it named, Paramore.Brighter.InMemoryScheduler, is a NuGet 404. CQRSWithBrighterAndDarker.md: the Order write model is shown (#7, BUILT). Behind it, Id = command.Id was CS0029 against the read side's Guid key, and #2 passed a CancellationToken positionally as RequestContext (CS1503). BrighterSchedulerSupport.md: the scheduled overloads listed the request before the delay and dropped RequestContext and args; now as 10.7.0. DefaultMessageMappers.md: the Avro mapper rewritten against Confluent's API (maintainer's ruling) as an async mapper constrained to ISpecificRecord, run end to end against a schema registry. A sync mapper is bypassed by PostAsync, and as the default a non-Avro type throws. PublishAsync sweep (maintainer's ruling): three places relied on PublishAsync reaching a mapper or a bus, now PostAsync; one practice that published dummy events to warm caches removed. CloudEvents extension properties are written only by CloudEventJsonMessageMapper, measured, and said so on three pages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
Five rows: InMemoryScheduler.md #5, CQRSWithBrighterAndDarker.md #7, BrighterSchedulerSupport.md #1, DefaultMessageMappers.md #4 and #5. --report exit 0: 989 blocks, 293 BUILT, 679 FAILED, 17 SKIPPED; baseline 293, 0 findings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
Filed on the maintainer's word (2026-09-28) and linked where the page tells readers to match the subscription name's case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…weep, recorded § Phase 5 as executed gains 5.4's entry: the maintainer's three rulings, two pin growths measured alone, the behaviour runs and their controls, BUILT 288 -> 293, pagelint 562 -> 553, pages with nothing BUILT 44 -> 42. Four § Blocks that stay FAILED rows, two § Splits rows, one § Blocks removed row, ten § Defect ledger rows. Task 5.4 ticked: 32 of 42. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…de them Five sync attributes on async handlers, each accepted by the compiler and each a ConfigurationException when the pipeline is built, now the async form: HowServiceActivatorWorks.md (UseInboxAsync), PipelineValidation.md x2, PolicyRetryAndCircuitBreaker.md, ReactorAndProactor.md and V10MigrationGuide.md (UseResiliencePipelineAsync). attr_mismatch.py 7 -> 1: the deliberate Before (error) example, now wrong in prose as well. PipelineValidation.md: the step-order examples also named an argument before a positional one, and the Before comments called step 0 inner, against the page's own rule. The published After (fixed) reported an error under ValidatePipelines; run, it now reports none, the Before one warning. The example warning message now spells attribute names as the validator does. V10MigrationGuide.md: the pipeline registry went to the obsolete PolicyRegistry (a type mismatch) and was built with a generic builder Brighter never reads; now ResiliencePipelineRegistry, from AddBrighterDefault (without it, ConfigurationException, run). Section 5 listed IRequestContext members 10.7.0 does not have (PartitionKey, CustomHeaders, Guid Id, ISpan) and omitted five it does; now as 10.7.0, with partition key and headers set through the Bag, run with a control. IRequestContext.InstrumentationOptions said "added in 10.7.0"; it is after 10.7.0, and now marked Not in a released package yet. ReactorAndProactor.md: said mappers have no async variants and advised Task.Run wrappers. A Proactor maps with IAmAMessageMapperAsync<T>, and a pump given only the other kind of mapper uses the default one silently, run both ways with controls. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…ontext you post with By the maintainer's ruling, the three items 5.5 found and left. PipelineValidation.md: the Replay rule, its two example messages and the Replay Without Causation Tracking section describe a feature after 10.7.0 (no causation code in the tag); now marked Not in a released package yet. The deliberate :250 example keeps its line. MessageMappers.md: the mapper's home page never mentioned IAmAMessageMapperAsync<T>. A new section shows one and says which path uses which kind: Post, DepositPost and a Reactor map with the sync mapper; PostAsync, DepositPostAsync and a Proactor with the async one; a type with only the other kind goes through the default mapper, silently. Run for all four calls. UsingTheContextBag.md: five examples set the partition key, headers or CloudEvents extensions on a handler's own Context and posted nothing, or passed them to SendAsync. Run: the keys act only on the context passed to the call that makes the message; a handler posting without one gets a fresh context, and a caller's context does not carry through. Each example now posts with the context it fills, and the page says why. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
… by 6ddcf7b's insert Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
…s context The Replay recurrence grep found two more pages naming OnceOnlyAction.Replay as available with no marker: DispatcherConfigurationReference.md (ActionOnExists) and BrighterOutboxSupport.md (the Sweeper). Both now say it ships after 10.7.0. UsingTheContextBag.md #4 wrote the PartitionKey object to Context under an example that now fills its own context. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
… 2 and 9 All nine gates exit 0 against 5.1's prediction; BUILT 295 (1 over the ceiling, reconciled), pages with nothing BUILT 41, pin 98 -> 100. Two Splits rows and 5.2's unit count corrected to what was measured. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy
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.
Summary
Phase 5 of spec 017 repairs the 16 tranche 2b pages, which are the remaining pages with one hard block each, and fixes the recorded falsehoods (P0-7):
ITimerProvider, the unshownOrder, and the sync attributes on async handlers. Every tranche page is now whole: each C# block on it either builds against Brighter 10.7.0 / Darker 4.1.1, is skipped with an accepted reason, or is listed with its reason intasks.md§ Blocks that stay FAILED.This PR changes the published site, so it needs your sign-off to merge. After the merge, may I delete the head ref
spec/017-phase5?git diff --name-only origin/master..HEAD -- contentslists 53 pages: 15 of the 16 tranche pages (AggregationQueryPatterns.mdwas made whole by its scaffold unit alone), and 38 pages outside the tranche, changed by P0-7, by repairing recurrences, and on your rulings.Defects found by running the blocks, repaired everywhere they occur
Commands, pipelines and Darker
BuildingAPipeline.mdused.Successor =, but the method isSetSuccessor(). The page also said a manual chain runs from the registry alone; in fact a factory must return the wired instance.[UseResiliencePipeline]was stacked on one method (CS0579) on 5 pages. The attribute is not repeatable, so the strategies are now layered in one pipeline.PolicyRetryAndCircuitBreaker.mddescribed Polly's strategy order backwards: the first strategy added is the outermost, so the example's 10 s timeout covered every retry together.publicnever ran, becauseAutoFromAssemblies()scans only public types. They are now public on 7 pages (your ruling).Activator.CreateInstanceas a factory.Monitoring.mdis rewritten for V10 (your ruling). Two upstream defects found while running it are stated on the page.Transports, external bus and observability
PostgreSQLMessageBroker.mdhad 11 defects. For example:channelNamediffered from the publication'sTopicreceived nothing.PublishAsyncwas said to send to the broker; it writes no row.visible_timeout.[ClaimCheck]was shown with parameters it does not have.messagePumpTypethrows. This last defect recurred on non-generic subscriptions on 5 more pages.AddSource(…)alone is not enough;AddBrighterInstrumentation()is needed.Telemetry.mdis rewritten, including its span names, attributes and propagation headers as captured on the wire.ConfiguringOpenTelemetry.mdnow points the OTLP exporter at Jaeger instead of using the deprecated Jaeger exporter.CloudEventJsonMessageMapper<>.S3LuggageStore.mdsaid ACLs default toPrivate; they arenull.P0-7 and what stood beside it
ITimerProviderdoes not exist: 4 → 0. The InMemory scheduler's time seam isInMemorySchedulerFactory.TimeProvider, and the fake-clock example is run withFakeTimeProvider. The page'sParamore.Brighter.InMemorySchedulerpackage does not exist either.Orderis now shown inCQRSWithBrighterAndDarker.md. Showing it surfaced aCS0029(Idassigned to aGuidkey) and aCancellationTokenpassed wherePublishAsynctakes aRequestContext.HandleAsync→ the async form. These pipelines throwConfigurationExceptionwhen built.attr_mismatch.pynow finds exactly one hit, the deliberate Before (error) example atPipelineValidation.md:250, whose prose now says it is wrong. The published After (fixed) example on that page itself reported an error. It now reports nothing, run withValidatePipelines().PublishAsyncswept wherever it meant the bus (your ruling). It dispatches to handlers in this process only.DefaultMessageMappers.mdis rewritten against Confluent's API (your ruling). This is the one pin change besidesFakeTimeProvider: 98 → 100 packages, each measured alone, and no verdict moved.ReactorAndProactor.mdsaid mappers have no async variants.MessageMappers.mdnow showsIAmAMessageMapperAsync<T>and which call uses which. A pump or a producer call given only the other kind of mapper silently uses the default mapper instead; all four producer calls and both pumps were run.V10MigrationGuide.md§ 4 built a registry Brighter never reads, and § 5 listedIRequestContextmembers that do not exist.InstrumentationOptionswas said to be "added in 10.7.0"; it ships after 10.7.0 and is now marked as not yet released. Replay validation is marked the same way on three pages.UsingTheContextBag.md's examples now post with the context they fill. Bag keys act only on the context passed to the call that makes the message (run, with a control).Every block that asserts behaviour was run against the released packages, with a control. The tables are in
tasks.md§ Phase 5 as executed.Upstream issues, filed in this phase on your word: BrighterCommand/Brighter#4453 and #4454 (monitoring), #4458 (AWS CloudEvents
souce), and #4465 (Control API wrong-case 500). Each is stated on its page.Gates
linkcheckpagelint--verifyversioncheckoptionchecksymbolcheckblockcheckpagelint --changed origin/masterexits 0.c7329bbprints 207 lines. 194 areFAILED -> BUILT; the other 13 are the accepted skip, or insertions and splits recorded in § Splits. The diff was checked with controls in both directions.🤖 Generated with Claude Code
https://claude.ai/code/session_016Am29wrQUS81NVh8dUyNuy