[{"data":1,"prerenderedAt":339},["ShallowReactive",2],{"page-\u002Fv1\u002Fcore\u002Fshared-kernel":3},{"id":4,"title":5,"body":6,"description":331,"extension":332,"meta":333,"navigation":334,"path":335,"seo":336,"stem":337,"__hash__":338},"content\u002Fv1\u002Fcore\u002Fshared-kernel.md","Shared kernel",{"type":7,"value":8,"toc":323},"minimark",[9,13,31,36,106,112,116,146,157,162,229,236,240,287,291,299,310,319],[10,11,5],"h1",{"id":12},"shared-kernel",[14,15,16,17,21,22,26,27,30],"p",{},"Components used by more than one module ",[18,19,20],"strong",{},"may"," live in a Shared kernel (",[23,24,25],"code",{},"Shared\u002F"," or equivalent), mirroring the layered layout of a module — but only when they are ",[18,28,29],{},"truly universal technical\u002Fkernel concepts",", not bounded-context business rules.",[32,33,35],"h2",{"id":34},"promote-to-shared-rule-mandatory","Promote-to-Shared rule (mandatory)",[37,38,39,52],"table",{},[40,41,42],"thead",{},[43,44,45,49],"tr",{},[46,47,48],"th",{},"Situation",[46,50,51],{},"Where it lives",[53,54,55,72,91],"tbody",{},[43,56,57,65],{},[58,59,60,61,64],"td",{},"Technical capability used by ",[18,62,63],{},"only one"," module",[58,66,67,68,71],{},"Keep it inside ",[18,69,70],{},"that module",": Domain port (if needed) + Infrastructure adapter",[43,73,74,85],{},[58,75,76,77,80,81,84],{},"The ",[18,78,79],{},"same"," technical capability is needed by ",[18,82,83],{},"two or more"," modules",[58,86,87,90],{},[18,88,89],{},"Promote"," to Shared (port + adapter + bind in Shared composition root)",[43,92,93,100],{},[58,94,95,96,99],{},"Cross-module ",[18,97,98],{},"business"," concept (member tier, stock line, money amount)",[58,101,102,105],{},[18,103,104],{},"Never"," Shared — use ACL \u002F Domain Events",[14,107,108,111],{},[18,109,110],{},"Start narrow; promote later."," Do not invent Shared “just in case.”",[32,113,115],{"id":114},"typical-shared-candidates-after-promotion","Typical Shared candidates (after promotion)",[117,118,119,126,131,136,141],"ul",{},[120,121,122,125],"li",{},[23,123,124],{},"DomainException"," \u002F base ensure helpers",[120,127,128],{},[23,129,130],{},"DatabaseTransactionInterface",[120,132,133],{},[23,134,135],{},"EventDispatcherInterface",[120,137,138],{},[23,139,140],{},"ClockInterface",[120,142,143],{},[23,144,145],{},"ConfigReaderInterface",[14,147,148,149,152,153,156],{},"These are ",[18,150,151],{},"technical",". A “Money” value object that encodes Ordering pricing rules is ",[18,154,155],{},"not"," a kernel concept — keep it in the owning module or expose via ACL\u002FEvents.",[158,159,161],"h3",{"id":160},"nuance-ubiquitous-technical-shapes","Nuance — ubiquitous technical shapes",[37,163,164,174],{},[40,165,166],{},[43,167,168,171],{},[46,169,170],{},"Candidate",[46,172,173],{},"Shared?",[53,175,176,186,201,219],{},[43,177,178,183],{},[58,179,180,182],{},[23,181,140],{},", transaction, event dispatch",[58,184,185],{},"Yes (after promote rule)",[43,187,188,195],{},[58,189,190,191,194],{},"Opaque id type \u002F UUID wrapper with ",[18,192,193],{},"no"," business rules",[58,196,197,198,200],{},"May promote if ≥2 modules need the ",[18,199,79],{}," technical helper",[43,202,203,213],{},[58,204,205,208,209,212],{},[23,206,207],{},"Money"," with currency ",[18,210,211],{},"plus"," Ordering tax\u002Fpricing policy",[58,214,215,218],{},[18,216,217],{},"No"," — business; keep in owning BC",[43,220,221,224],{},[58,222,223],{},"“MemberTier” enum used by Ordering and Directory",[58,225,226,228],{},[18,227,217],{}," — ACL \u002F Events",[14,230,231,232,235],{},"When in doubt: if removing the type would change a ",[18,233,234],{},"business invariant",", it is not Shared.",[32,237,239],{"id":238},"quick-gate","Quick gate",[241,242,247],"pre",{"className":243,"code":244,"language":245,"meta":246,"style":246},"language-mermaid shiki shiki-themes github-light github-dark","flowchart TD\n    X[Candidate for Shared] --> T{Technical kernel capability?\u003Cbr\u002F>clock, config reader,\u003Cbr\u002F>transaction, event dispatch}\n    T -->|No — business enum\u002Fentity\u002FDTO| N[Keep in owning module\u003Cbr\u002F>expose via ModuleInterface \u002F Events]\n    T -->|Yes| M{Already needed by\u003Cbr\u002F>two or more modules?}\n    M -->|No| ONE[Implement in owning module Infra first]\n    M -->|Yes| S[Promote to Shared\u003Cbr\u002F>port + adapter + bind]\n","mermaid","",[23,248,249,257,263,269,275,281],{"__ignoreMap":246},[250,251,254],"span",{"class":252,"line":253},"line",1,[250,255,256],{},"flowchart TD\n",[250,258,260],{"class":252,"line":259},2,[250,261,262],{},"    X[Candidate for Shared] --> T{Technical kernel capability?\u003Cbr\u002F>clock, config reader,\u003Cbr\u002F>transaction, event dispatch}\n",[250,264,266],{"class":252,"line":265},3,[250,267,268],{},"    T -->|No — business enum\u002Fentity\u002FDTO| N[Keep in owning module\u003Cbr\u002F>expose via ModuleInterface \u002F Events]\n",[250,270,272],{"class":252,"line":271},4,[250,273,274],{},"    T -->|Yes| M{Already needed by\u003Cbr\u002F>two or more modules?}\n",[250,276,278],{"class":252,"line":277},5,[250,279,280],{},"    M -->|No| ONE[Implement in owning module Infra first]\n",[250,282,284],{"class":252,"line":283},6,[250,285,286],{},"    M -->|Yes| S[Promote to Shared\u003Cbr\u002F>port + adapter + bind]\n",[32,288,290],{"id":289},"layout-sketch","Layout sketch",[241,292,297],{"className":293,"code":295,"language":296,"meta":246},[294],"language-text","Shared\u002F\n├── Domain\u002F\n│   ├── Exceptions\u002F\n│   └── Ports\u002F          # ClockInterface, EventDispatcherInterface, …\n├── Application\u002F\n│   └── Providers\u002F      # bind Shared ports\n└── Infrastructure\u002F\n    └── …               # framework adapters for Shared ports\n","text",[23,298,295],{"__ignoreMap":246},[14,300,301,302,305,306,309],{},"Host projects may place Shared under ",[23,303,304],{},"app\u002FShared"," or ",[23,307,308],{},"src\u002FShared",". The promote rule does not change.",[14,311,312,313,318],{},"Next: ",[314,315,317],"a",{"href":316},"\u002Fv1\u002Fcore\u002Fdecision-tree","decision tree",".",[320,321,322],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":246,"searchDepth":259,"depth":259,"links":324},[325,326,329,330],{"id":34,"depth":259,"text":35},{"id":114,"depth":259,"text":115,"children":327},[328],{"id":160,"depth":265,"text":161},{"id":238,"depth":259,"text":239},{"id":289,"depth":259,"text":290},"Promote-to-Shared rule — technical capabilities used by two or more modules; never business concepts.","md",{},true,"\u002Fv1\u002Fcore\u002Fshared-kernel",{"title":5,"description":331},"v1\u002Fcore\u002Fshared-kernel","zNd2RVQimB_wdeRxAo1j5kb7X2KMElIrC-zm1V8_Pn0",1786241412398]