What changed
PLATFORM.md Step 4 had a single rule: "every SPI gets a default no-op implementation in the owning repo."
During devtown Epic 2 design we discovered this is too coarse. There are two distinct SPI patterns that require different default implementations.
The refinement
Operational SPIs (WorkerProvisioner, CaseChannelProvider, WorkerStatusListener): a do-nothing no-op is valid — the operation can be skipped without breaking the system. No-op in same pure-Java module as the interface. Existing examples are correct.
Vocabulary/registry SPIs (CapabilityRegistry in devtown and equivalents in aml, clinical): an empty implementation is NOT valid — routing and selection break immediately. The default must be a populated implementation expressing domain vocabulary. Lives in the same pure-Java module as the SPI (no CDI annotations — the app module provides the @ApplicationScoped wrapper). This keeps vocabulary cohesive and lets unit tests use new DefaultRegistry() without CDI.
Decision rule: can the system function correctly with an empty/do-nothing implementation? If yes → no-op default. If no → populated default.
Action required
The edit has been made locally to /Users/mdproctor/claude/casehub/parent/docs/PLATFORM.md in the devtown session (which cannot commit cross-repo). Commit it in the parent session:
git add docs/PLATFORM.md
git commit -m "docs: distinguish no-op vs populated SPI defaults in Platform Coherence Protocol
Operational SPIs (WorkerProvisioner etc.) → no-op default.
Vocabulary/registry SPIs (CapabilityRegistry etc.) → populated default.
Decision rule: can system function with empty impl? yes → no-op, no → populated."
Context
Surfaced during devtown Epic 2 (domain model) brainstorming. The CapabilityRegistry SPI has a meaningful default (13 capability tags + 4 routing thresholds) that is domain vocabulary — not infrastructure. Putting it in devtown-domain (plain Java) with the CDI wrapper in devtown-app is correct, but the old rule implied a no-op would suffice.
Refs casehubio/devtown#9
What changed
PLATFORM.md Step 4 had a single rule: "every SPI gets a default no-op implementation in the owning repo."
During devtown Epic 2 design we discovered this is too coarse. There are two distinct SPI patterns that require different default implementations.
The refinement
Operational SPIs (
WorkerProvisioner,CaseChannelProvider,WorkerStatusListener): a do-nothing no-op is valid — the operation can be skipped without breaking the system. No-op in same pure-Java module as the interface. Existing examples are correct.Vocabulary/registry SPIs (
CapabilityRegistryin devtown and equivalents in aml, clinical): an empty implementation is NOT valid — routing and selection break immediately. The default must be a populated implementation expressing domain vocabulary. Lives in the same pure-Java module as the SPI (no CDI annotations — the app module provides the@ApplicationScopedwrapper). This keeps vocabulary cohesive and lets unit tests usenew DefaultRegistry()without CDI.Decision rule: can the system function correctly with an empty/do-nothing implementation? If yes → no-op default. If no → populated default.
Action required
The edit has been made locally to
/Users/mdproctor/claude/casehub/parent/docs/PLATFORM.mdin the devtown session (which cannot commit cross-repo). Commit it in the parent session:Context
Surfaced during devtown Epic 2 (domain model) brainstorming. The
CapabilityRegistrySPI has a meaningful default (13 capability tags + 4 routing thresholds) that is domain vocabulary — not infrastructure. Putting it indevtown-domain(plain Java) with the CDI wrapper indevtown-appis correct, but the old rule implied a no-op would suffice.Refs casehubio/devtown#9