Skip to content

Spec 018 phase 3: S1, the Scheduler pages - #202

Merged
iancooper merged 12 commits into
masterfrom
spec/018-phase3
Oct 14, 2026
Merged

iancooper merged 12 commits into
masterfrom
spec/018-phase3

Conversation

@iancooper

@iancooper iancooper commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Summary

Spec 018 phase 3, S1: the eight Scheduler pages. This changes the published site, so it needs your sign-off.

  • 122 of S1's 129 FAILED blocks now build. 3 were JSON in csharp fences and are retagged json, and 4 stay FAILED and listed, all same-page. With four two-snippet fences split, the eight pages hold 141 C# blocks, of which 137 build. Seven new scaffold units; AzureSchedulerContext.cs extended
  • 20 defects, each repaired at every recurrence (tasks.md § Defect ledger, rows 1 and 4–20). Some of the larger ones:
    • AddServiceActivator/UseExternalBus as current code (D5, D10)
    • CustomScheduler.md implementing two of each interface's five members, with types that don't exist at 10.8.0
    • UseScheduler called on IServiceCollection
    • Quartz clustering and serializer calls on the wrong object, or obsolete at 3.22.4
    • Azure subscription parameters that don't exist
  • Running the blocks overturned one page. .UseScheduler(new HangfireMessageSchedulerFactory()) throws at startup: the factory's Client default reads Hangfire's JobStorage.Current before AddHangfire has set it. There are 12 sites on 6 pages, two outside S1 (InMemoryOptions.md, SchedulingAMessage.md). Each now builds the factory in UseScheduler(provider => …) after resolving IBackgroundJobClientV2. Filed upstream as [Bug] HangfireMessageSchedulerFactory throws when constructed during service configuration (eager BackgroundJobClient) Brighter#4600, as you ruled
  • Twelve behavioural claims run with a control, as spec/018-compile_residual/probe/s1/<name>/ projects against the released packages; three more are read and named (§ Behaviour (3.5))
  • Tools:
    • symbolcheck gains two watchlist rows, with opt-outs on FAQ.md and V10MigrationGuide.md
    • --verify-list now strips comments and strings before counting a file (D11), since both names survive in Brighter only as ///
    • Both pins gain Quartz.Serialization.Json 3.22.4 (D12)
    • probe/page.py and probe/second.py are the repair loop's instruments

Gates

Gate Result
blockcheck --report 993 blocks: 430 BUILT, 546 FAILED, 17 SKIPPED — 0 findings, exit 0. 552 assemblies on each pin, 52 units, 0 violations
pagelint 0 errors / 410 warnings (was 512); --changed strict, 0 errors; --plant 5 / 5
symbolcheck 0 — 24 entries, 14 silenced; --verify-list all 24 DEAD
linkcheck · shape · redirects · --verify · versioncheck · optioncheck unmoved: 168 / 0 · 161 · 77 · 161 = 161 · 0 of 18 · 0 / 59 / 529

All but one are inside the bands task 3.1 predicted. BUILT is 5 above, because 3.1 expected D3 to skip the single options shown alone, and every one was made whole instead (tasks.md § Phase 3 closed).

For you

  1. Sign-off: this changes the published site, on eight Scheduler pages, plus InMemoryOptions.md, SchedulingAMessage.md (the Hangfire repair), and FAQ.md, V10MigrationGuide.md (opt-out comments only). May I merge?
  2. After the merge, may I delete the head ref spec/018-phase3?

🤖 Generated with Claude Code

https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy

iancooper and others added 12 commits October 13, 2026 18:24
Re-draw the groups at f3f685f, read S1's 12 defects at the second
compile (probe/second.py), run the recurrence greps, add D10 (watch
UseExternalBus too) and ledger rows 4-7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
…; watch both V9 names

AwsScheduler.md #3 and AzureScheduler.md #6 called AddServiceActivator
and UseExternalBus, both dead at 10.8.0. Two symbolwatch rows (D5, D10),
opt-outs on FAQ.md and V10MigrationGuide.md. symbolcheck --verify-list
now strips comments and strings before counting a file (D11), since
both names survive in Brighter only as doc comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
…SwitchingSchedulers

CustomScheduler.md implements every member of the four scheduler
interfaces and stores FireSchedulerMessage/FireSchedulerRequest as
Brighter's own schedulers do (ledger 6). BrighterSchedulerSupport.md's
two two-snippet fences split. SwitchingSchedulers.md's literal '...'
becomes '// ...', and the transition example chooses its scheduler at
startup, since UseScheduler<T> cannot infer one T from two factories.
Three scaffold units; probe/page.py for the repair loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
Services take their dependencies by constructor instead of naming
undeclared fields; UseScheduler is called on the builder, not on
IServiceCollection; the test fixture registers its handler with
AsyncHandlers and shows the handler and registry it relies on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
Dead-lettering and lock duration are set on
AzureServiceBusSubscriptionConfiguration; the page passed
deadLetterQueueHandling and lockTimeout, which no overload has (ledger 5).
ServiceBusDefaultAzureClientProvider, not ...AzureCredential...; the
troubleshooting handler is the reader's own, not FireAzureScheduler's;
the ARM fragment is json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
V4 usings throughout; services by constructor; single-option fragments
made whole inside an AwsSchedulerFactory initializer; the troubleshooting
block declares its connection before using it; the IAM policies are json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
Statements before the types they sit with; a lambda body's assignments
end in semicolons; Hangfire.PostgreSql's schema is set on
PostgreSqlStorageOptions; the allow-all dashboard filter Hangfire does
not ship is shown; UseScheduler fragments made whole on the builder;
the UTC/local pair split.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
…son (D12)

Clustering is configured on the persistent store, not the configurator;
UseJsonSerializer is obsolete at 3.22.4 for UseNewtonsoftJsonSerializer;
the misfire threshold is a property; QuartzSchedulerFactory's message id
hook is GetOrCreateSchedulerId; UseScheduler is called on the builder;
statements before types; the UTC/local pair split.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
…FAILED, D12

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
…ilt after its storage

Twelve sites on six pages constructed HangfireMessageSchedulerFactory
while services are configured, which throws: its Client default reads
JobStorage.Current before AddHangfire has set it (Brighter#4600). Each
now builds the factory in UseScheduler's provider lambda after resolving
IBackgroundJobClientV2. Nine probes under probe/s1/, each with a control.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
…ools/README rows 2, 8, 9

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
Quartz's pool-size example shows the connection string where it goes;
the two store-the-id fragments declare the service they sit in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjnH2pJ98aMabu1MyTpRxy
@iancooper
iancooper merged commit 5f2294c into master Oct 14, 2026
10 checks passed
@iancooper
iancooper deleted the spec/018-phase3 branch October 14, 2026 23:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant