[{"data":1,"prerenderedAt":1365},["ShallowReactive",2],{"page-\u002Fv1\u002Fadopt\u002Fapply\u002Fcakephp-full":3},{"id":4,"title":5,"body":6,"description":1358,"extension":1359,"meta":1360,"navigation":1064,"path":1361,"seo":1362,"stem":1363,"__hash__":1364},"content\u002Fv1\u002Fadopt\u002Fapply\u002Fcakephp-full.md","CakePHP one-shot apply (full architecture)",{"type":7,"value":8,"toc":1316},"minimark",[9,14,58,61,66,73,128,133,143,145,149,161,163,167,171,182,186,192,205,209,301,308,312,318,322,379,383,390,443,473,477,519,539,543,551,555,561,565,571,575,586,590,599,601,605,675,698,803,807,838,842,905,911,915,928,932,948,950,954,962,966,974,978,986,990,994,996,1000,1003,1005,1009,1011,1015,1020,1023,1029,1033,1110,1114,1143,1147,1212,1216,1236,1240,1254,1258,1274,1278,1286,1290,1301,1305,1312],[10,11,13],"h1",{"id":12},"modular-hexagonal-ddd-one-shot-apply-cakephp","Modular Hexagonal DDD — ONE-SHOT APPLY (cakephp)",[15,16,17],"blockquote",{},[18,19,20,24,25,28,29,32,33,37,32,40,43,44,32,47,50,53,54,57],"p",{},[21,22,23],"strong",{},"Self-contained."," An AI agent should fetch ",[21,26,27],{},"this file only"," and execute it.\n",[21,30,31],{},"Core version:"," ",[34,35,36],"code",{},"1.0.0-draft",[21,38,39],{},"Short HTML entry:",[34,41,42],{},"\u002Fcakephp"," · ",[21,45,46],{},"This file:",[34,48,49],{},"\u002Fapply\u002Fcakephp.full.md",[21,51,52],{},"AI-neutral:"," assistant files are optional; architecture does not require any AI vendor.\n",[21,55,56],{},"Host baseline researched:"," see Part C header (versions as of 2026-08).",[59,60],"hr",{},[62,63,65],"h2",{"id":64},"_0-agent-mandate","0. Agent mandate",[18,67,68,69,72],{},"You are bootstrapping a ",[21,70,71],{},"cakephp application repository"," (not the docs site).",[74,75,76,80,87,98,104,121],"ol",{},[77,78,79],"li",{},"Treat this document as the complete working standard for this session.",[77,81,82,83,86],{},"Execute ",[21,84,85],{},"Part D"," in order after reading Parts A–C.",[77,88,89,90,93,94,97],{},"When writing module code, obey ",[21,91,92],{},"Part B (Core)"," and ",[21,95,96],{},"Part C (host)",".",[77,99,100,103],{},[21,101,102],{},"Do not create a git commit"," unless the human explicitly asks.",[77,105,106,107,110,111,110,114,110,117,120],{},"Rename illustrative contexts ",[34,108,109],{},"Ordering",", ",[34,112,113],{},"Warehouse",[34,115,116],{},"Directory",[34,118,119],{},"Identity"," to the human’s domains.",[77,122,123,124,127],{},"If AI vendor is ",[34,125,126],{},"none",", skip Part E.",[129,130,132],"h3",{"id":131},"programmer-prompt","Programmer prompt",[134,135,141],"pre",{"className":136,"code":138,"language":139,"meta":140},[137],"language-text","Apply Modular Hexagonal DDD from \u003CORIGIN>\u002Fapply\u002Fcakephp.full.md\nAI assistant: \u003Ccursor|claude|gemini|copilot|generic|none>\nBounded contexts: \u003Clist>\nDo not commit unless I ask.\n","text","",[34,142,138],{"__ignoreMap":140},[59,144],{},[10,146,148],{"id":147},"part-a-design-test","Part A — Design test",[15,150,151],{},[18,152,153,154,93,157,160],{},"If the peer module is deleted and replaced by HTTP, does this module’s ",[21,155,156],{},"Application",[21,158,159],{},"Domain"," still compile?",[59,162],{},[10,164,166],{"id":165},"part-b-complete-core-architecture","Part B — Complete Core architecture",[62,168,170],{"id":169},"b1-purpose","B1. Purpose",[18,172,173,174,177,178,181],{},"Build applications as ",[21,175,176],{},"replaceable bounded-context modules"," using Hexagonal Architecture (ports & adapters) + DDD. This docs site is the ",[21,179,180],{},"sole canon","; consuming repos keep thin pointers, not a forked essay.",[62,183,185],{"id":184},"b2-module-layout-must","B2. Module layout (MUST)",[134,187,190],{"className":188,"code":189,"language":139,"meta":140},[137],"{Module}\u002F\n  Application\u002F     # UseCases, Application DTO, Providers \u002F composition root\n  Domain\u002F          # Entities, Ports, Events, Enums, Domain DTOs\n  Infrastructure\u002F  # Persistence adapters, ExternalServices (ACL), Config, listeners\n  UI\u002F              # Controllers, Routes, validation, admin UI, console\nShared\u002F            # Promoted technical ports\u002Fadapters only (after promote rule)\n",[34,191,189],{"__ignoreMap":140},[18,193,194,195,110,198,201,202],{},"Host roots vary (",[34,196,197],{},"app\u002FModules",[34,199,200],{},"src\u002FModules",", packages). ",[21,203,204],{},"Roles do not.",[62,206,208],{"id":207},"b3-strictness-ladder-must","B3. Strictness ladder (MUST)",[210,211,212,231],"table",{},[213,214,215],"thead",{},[216,217,218,222,225,228],"tr",{},[219,220,221],"th",{},"Strictness",[219,223,224],{},"Area",[219,226,227],{},"Allowed",[219,229,230],{},"Forbidden",[232,233,234,250,269,285],"tbody",{},[216,235,236,240,244,247],{},[237,238,239],"td",{},"Hardest",[237,241,242],{},[21,243,159],{},[237,245,246],{},"Own Domain types + Shared kernel ports",[237,248,249],{},"Other modules; host facades\u002Fhelpers; ORM; framework traits on Domain Events",[216,251,252,255,260,263],{},[237,253,254],{},"Strict",[237,256,257],{},[21,258,259],{},"Application Use Cases \u002F App DTOs",[237,261,262],{},"Own Domain + Shared ports",[237,264,265,266],{},"Facades, ORM, foreign Application\u002FDomain, peer ",[34,267,268],{},"*ModuleInterface",[216,270,271,274,279,282],{},[237,272,273],{},"Relaxed",[237,275,276],{},[21,277,278],{},"Composition root",[237,280,281],{},"Container binds, routes, config merge",[237,283,284],{},"Business rules",[216,286,287,290,295,298],{},[237,288,289],{},"Outer",[237,291,292],{},[21,293,294],{},"Infrastructure & UI",[237,296,297],{},"Framework, ORM, HTTP, ACL adapters, admin",[237,299,300],{},"Leaking ORM\u002Fforeign Domain into Domain\u002FUse Cases",[18,302,303,304,307],{},"Dependency direction: ",[21,305,306],{},"Domain ← Application ← Infrastructure\u002FUI",". Ports in Domain; adapters in Infrastructure.",[62,309,311],{"id":310},"b4-golden-flow-must","B4. Golden flow (MUST)",[134,313,316],{"className":314,"code":315,"language":139,"meta":140},[137],"UI → Application DTO → first-level *UseCase::__invoke\n  → Domain (Entity \u002F Domain service)\n  → Domain Port\n  → Infrastructure adapter (ORM \u002F ACL \u002F HTTP)\n  → back as Entity \u002F result\n  → UI presents\n",[34,317,315],{"__ignoreMap":140},[62,319,321],{"id":320},"b5-use-cases-dtos-must","B5. Use Cases & DTOs (MUST)",[323,324,325,335,349,356,366,373,376],"ul",{},[77,326,327,328,331,332,97],{},"First-level: ",[34,329,330],{},"Application\u002FUseCases\u002F{Capability}\u002FSomethingUseCase"," with single public ",[34,333,334],{},"__invoke",[77,336,337,338,32,341,344,345,348],{},"Nested helpers: ",[21,339,340],{},"no",[34,342,343],{},"UseCase"," suffix; ",[21,346,347],{},"not"," called from UI.",[77,350,351,352,355],{},"Mirror ",[34,353,354],{},"{Capability}\u002F"," for DTOs and Ports.",[77,357,358,359,362,363,97],{},"ACL need ports: ",[34,360,361],{},"Domain\u002FPorts\u002FAcl\u002F",". Module façades: ",[34,364,365],{},"Domain\u002FPorts\u002FModule\u002F",[77,367,368,369,372],{},"Never create a literal ",[34,370,371],{},"Feature\u002F"," directory.",[77,374,375],{},"Application DTO = UI\u002FCLI input. Domain DTO = intra-module only.",[77,377,378],{},"Other modules never call Use Cases — only ACL \u002F Events.",[62,380,382],{"id":381},"b6-cross-module-bridges-must","B6. Cross-module bridges (MUST)",[18,384,385,386,389],{},"Application\u002FDomain of A ",[21,387,388],{},"never"," import Application\u002FDomain of B.",[210,391,392,402],{},[213,393,394],{},[216,395,396,399],{},[219,397,398],{},"Need",[219,400,401],{},"Bridge",[232,403,404,425],{},[216,405,406,412],{},[237,407,408,409],{},"Peer answer ",[21,410,411],{},"now",[237,413,414,417,418,421,422],{},[21,415,416],{},"Sync ACL",": local ",[34,419,420],{},"{Need}PortInterface"," → Infra ACL adapter → thin peer ",[34,423,424],{},"{This}ModuleInterface",[216,426,427,433],{},[237,428,429,430],{},"Peer reacts ",[21,431,432],{},"later",[237,434,435,438,439,442],{},[21,436,437],{},"Async Domain Event"," → consumer Infra ",[21,440,441],{},"translation listener"," → inbound Use Case",[323,444,445,452,470],{},[77,446,447,448,451],{},"Mapping only in ACL adapter; façades thin + HTTP-mappable; Prefer ACL ",[21,449,450],{},"validate before"," local commit.",[77,453,454,455,458,459,462,463,462,466,469],{},"Events: pure Domain class; Shared ",[34,456,457],{},"EventDispatcherInterface","; ",[34,460,461],{},"eventId"," + ",[34,464,465],{},"occurredAt",[34,467,468],{},"schemaVersion"," + rich happy-path payload; idempotent consumers; no Domain re-fetch on happy path; prefer outbox.",[77,471,472],{},"No cross-module write transaction. Reports: ACL reads or owned projections.",[62,474,476],{"id":475},"b7-shared-promote-rule-must","B7. Shared promote rule (MUST)",[210,478,479,489],{},[213,480,481],{},[216,482,483,486],{},[219,484,485],{},"Situation",[219,487,488],{},"Where",[232,490,491,499,507],{},[216,492,493,496],{},[237,494,495],{},"Tech used by one module",[237,497,498],{},"That module’s Infrastructure",[216,500,501,504],{},[237,502,503],{},"Same tech used by ≥2 modules",[237,505,506],{},"Promote to Shared",[216,508,509,516],{},[237,510,511,512,515],{},"Cross-module ",[21,513,514],{},"business"," concept",[237,517,518],{},"Never Shared — ACL \u002F Events",[18,520,521,522,110,525,110,528,110,530,110,533,110,536,97],{},"Typical Shared: ",[34,523,524],{},"DomainException",[34,526,527],{},"DatabaseTransactionInterface",[34,529,457],{},[34,531,532],{},"ClockInterface",[34,534,535],{},"ConfigReaderInterface",[34,537,538],{},"Ensure",[62,540,542],{"id":541},"b8b9-persistence-ui-must","B8–B9. Persistence & UI (MUST)",[323,544,545,548],{},[77,546,547],{},"Map persistence records ↔ Domain Entities in Infrastructure; never leak ORM into Use Cases\u002FDomain.",[77,549,550],{},"UI: authorize → DTO → Use Case → present.",[62,552,554],{"id":553},"b10-decision-tree","B10. Decision tree",[134,556,559],{"className":557,"code":558,"language":139,"meta":140},[137],"Only this module? → Golden flow\nNeed peer now? → ACL\nPeer later? → Event\nMulti-step? → Orchestration (still ACL+Events)\nReport across contexts? → Projection \u002F ACL read\nTech in 2+ modules? → Shared\nBusiness in 2+ modules? → ACL\u002FEvents — never Shared\n",[34,560,558],{"__ignoreMap":140},[62,562,564],{"id":563},"b11-anti-patterns","B11. Anti-patterns",[18,566,567,568,570],{},"Peer imports in Use Cases; god façades; thin-ID events; Shared business enums; ORM in Domain; Entity extends ORM; literal ",[34,569,371],{},"; cross-module DB TX; ORM joins across modules for policy.",[62,572,574],{"id":573},"b12-examples","B12. Examples",[18,576,577,110,579,110,581,110,583,585],{},[34,578,109],{},[34,580,113],{},[34,582,116],{},[34,584,119],{}," only — rename to your domains.",[62,587,589],{"id":588},"b13-quality-assertions","B13. Quality assertions",[18,591,592,593,595,596,598],{},"Boundary tests must fail CI if: foreign Application\u002FDomain imports; peer ",[34,594,268],{}," in Use Cases; ORM\u002Ffacades in Domain\u002FUse Cases; literal ",[34,597,371],{}," folders. Also: behaviour tests, formatter, static analysis, event idempotency.",[59,600],{},[10,602,604],{"id":603},"part-c-cakephp-host-mapping","Part C — CakePHP host mapping",[210,606,607,615],{},[213,608,609],{},[216,610,611,613],{},[219,612],{},[219,614],{},[232,616,617,634,650,663],{},[216,618,619,624],{},[237,620,621],{},[21,622,623],{},"Target",[237,625,626,629,630,633],{},[21,627,628],{},"CakePHP 5.4.x"," (e.g. 5.4.1 as of 2026-07; PHP ",[21,631,632],{},"8.2–8.5",")",[216,635,636,641],{},[237,637,638],{},[21,639,640],{},"Docs",[237,642,643,649],{},[644,645,646],"a",{"href":646,"rel":647},"https:\u002F\u002Fbook.cakephp.org\u002F5\u002F",[648],"nofollow"," · Plugins · Dependency Injection",[216,651,652,657],{},[237,653,654],{},[21,655,656],{},"App skeleton",[237,658,659,662],{},[34,660,661],{},"cakephp\u002Fapp"," ^5.4",[216,664,665,670],{},[237,666,667],{},[21,668,669],{},"Adapter HTML",[237,671,672],{},[34,673,674],{},"\u003CORIGIN>\u002Fv1\u002Fadapters\u002Fcakephp",[18,676,677,678,681,682,685,686,689,690,693,694,697],{},"Map each bounded context to a ",[21,679,680],{},"CakePHP plugin"," (or ",[34,683,684],{},"src\u002F{Module}"," namespaces) containing Core layers. CakeORM ",[34,687,688],{},"Table"," \u002F ",[34,691,692],{},"Entity"," classes are ",[21,695,696],{},"Infrastructure",", not Domain Entities.",[210,699,700,710],{},[213,701,702],{},[216,703,704,707],{},[219,705,706],{},"Core",[219,708,709],{},"CakePHP 5.4 place",[232,711,712,726,740,757,773,781,789],{},[216,713,714,717],{},[237,715,716],{},"Module root",[237,718,719,722,723],{},[34,720,721],{},"plugins\u002F{Module}\u002F"," (plugin) or ",[34,724,725],{},"src\u002F{Module}\u002F",[216,727,728,731],{},[237,729,730],{},"Shared",[237,732,733,736,737],{},[34,734,735],{},"plugins\u002FShared\u002F"," or ",[34,738,739],{},"src\u002FShared\u002F",[216,741,742,744],{},[237,743,278],{},[237,745,746,749,750,753,754],{},[34,747,748],{},"Application::services()"," and plugin ",[34,751,752],{},"Plugin::services(ContainerInterface)"," — ",[21,755,756],{},"bindings only",[216,758,759,762],{},[237,760,761],{},"Persistence",[237,763,764,753,767,769,770,772],{},[34,765,766],{},"Infrastructure\u002FPersistence\u002F",[34,768,688],{}," classes + Cake ",[34,771,692],{}," maps → Domain Entities in repositories",[216,774,775,778],{},[237,776,777],{},"ACL adapter",[237,779,780],{},"Infra service registered in DI; inject local port into Use Cases",[216,782,783,786],{},[237,784,785],{},"Translation listener",[237,787,788],{},"Queue listener \u002F Cake event subscriber in Infra → inbound Use Case",[216,790,791,794],{},[237,792,793],{},"UI",[237,795,796,797,689,799,802],{},"Controllers in plugin ",[34,798,793],{},[34,800,801],{},"Controller"," calling Use Cases; no business rules in Tables",[129,804,806],{"id":805},"orm-quarantine","ORM quarantine",[323,808,809,818,821],{},[77,810,811,812,814,815,817],{},"Do ",[21,813,347],{}," treat Cake ",[34,816,692],{}," as Domain Entity.",[77,819,820],{},"Prefer constructor injection of ports into Use Cases.",[77,822,823,824,827,828,831,832,837],{},"From CakePHP 5.3+, ",[34,825,826],{},"TableContainer"," delegate enables injecting ",[34,829,830],{},"*Table"," into Infra services — still keep Tables out of Domain\u002FUse Cases (",[644,833,836],{"href":834,"rel":835},"https:\u002F\u002Fbook.cakephp.org\u002F5\u002Fen\u002Fdevelopment\u002Fdependency-injection.html",[648],"DI \u002F TableContainer",").",[129,839,841],{"id":840},"di-example","DI example",[134,843,847],{"className":844,"code":845,"language":846,"meta":140,"style":140},"language-php shiki shiki-themes github-light github-dark","\u002F\u002F plugins\u002FOrdering\u002Fsrc\u002FOrderingPlugin.php\npublic function services(ContainerInterface $container): void\n{\n    $container->add(WarehouseAvailabilityPortInterface::class)\n        ->setConcrete(WarehouseAvailabilityAclAdapter::class);\n    $container->add(PlaceOrderUseCase::class)\n        ->addArgument(WarehouseAvailabilityPortInterface::class)\n        \u002F* + other ports *\u002F;\n}\n","php",[34,848,849,857,863,869,875,881,887,893,899],{"__ignoreMap":140},[850,851,854],"span",{"class":852,"line":853},"line",1,[850,855,856],{},"\u002F\u002F plugins\u002FOrdering\u002Fsrc\u002FOrderingPlugin.php\n",[850,858,860],{"class":852,"line":859},2,[850,861,862],{},"public function services(ContainerInterface $container): void\n",[850,864,866],{"class":852,"line":865},3,[850,867,868],{},"{\n",[850,870,872],{"class":852,"line":871},4,[850,873,874],{},"    $container->add(WarehouseAvailabilityPortInterface::class)\n",[850,876,878],{"class":852,"line":877},5,[850,879,880],{},"        ->setConcrete(WarehouseAvailabilityAclAdapter::class);\n",[850,882,884],{"class":852,"line":883},6,[850,885,886],{},"    $container->add(PlaceOrderUseCase::class)\n",[850,888,890],{"class":852,"line":889},7,[850,891,892],{},"        ->addArgument(WarehouseAvailabilityPortInterface::class)\n",[850,894,896],{"class":852,"line":895},8,[850,897,898],{},"        \u002F* + other ports *\u002F;\n",[850,900,902],{"class":852,"line":901},9,[850,903,904],{},"}\n",[18,906,907,908,97],{},"Enable plugins in ",[34,909,910],{},"Application::bootstrap()",[129,912,914],{"id":913},"events","Events",[323,916,917,923],{},[77,918,919,920,922],{},"Wrap Cake events or a queue in Shared ",[34,921,457],{}," adapter.",[77,924,925,926,97],{},"Consumer plugin Infra subscriber\u002Flistener → Use Case; idempotent ",[34,927,461],{},[129,929,931],{"id":930},"tooling","Tooling",[323,933,934,945],{},[77,935,936,937,940,941,944],{},"PHPUnit; PHPStan; ",[34,938,939],{},"bin\u002Fcake"," bake ",[21,942,943],{},"only"," into Infrastructure\u002FUI paths you specify.",[77,946,947],{},"Rector\u002FCake upgrades: keep Domain pure when upgrading 5.x minors.",[59,949],{},[10,951,953],{"id":952},"part-d-apply-procedure-cakephp","Part D — Apply procedure (CakePHP)",[62,955,957,958,961],{"id":956},"d1-confirm-cakephp-54-app-cakephpcakephp-54","D1 — Confirm CakePHP 5.4 app (",[34,959,960],{},"cakephp\u002Fcakephp"," ^5.4)",[62,963,965],{"id":964},"d2-readme-one-shot-plugin-layout","D2 — README one-shot + plugin layout",[62,967,969,970,973],{"id":968},"d3d5-roadmap-prd-ai-architecture-copy","D3–D5 — ROADMAP \u002F PRD \u002F ",[34,971,972],{},".ai"," ARCHITECTURE copy",[62,975,977],{"id":976},"d6-create-first-plugin-module-with-applicationdomaininfrastructureui","D6 — Create first plugin module with Application\u002FDomain\u002FInfrastructure\u002FUI",[62,979,981,982,985],{"id":980},"d7-register-plugin-services-bindings","D7 — Register plugin + ",[34,983,984],{},"services()"," bindings",[62,987,989],{"id":988},"d8-tests-no-tableentity-in-applicationdomain","D8 — Tests: no Table\u002FEntity in Application\u002FDomain",[62,991,993],{"id":992},"d9-part-e-no-commit-unless-asked","D9 — Part E — no commit unless asked",[59,995],{},[10,997,999],{"id":998},"part-f-sketch","Part F — Sketch",[18,1001,1002],{},"Ordering controller → Use Case → ACL port → Warehouse plugin façade service; async subscriber in Warehouse plugin.",[59,1004],{},[10,1006,1008],{"id":1007},"part-g-done-checklist-standard","Part G — Done checklist (standard)",[59,1010],{},[10,1012,1014],{"id":1013},"part-e-assistant-files-optional","Part E — Assistant files (optional)",[18,1016,1017,1018,97],{},"Skip if AI vendor is ",[34,1019,126],{},[18,1021,1022],{},"Create shared folder:",[134,1024,1027],{"className":1025,"code":1026,"language":139,"meta":140},[137],".ai\u002Fmodular-hexagonal-ddd\u002F\n  ARCHITECTURE.full.md   # copy of the host one-shot you fetched\n  RULES.core.md\n  SKILL.md\n  CHECKLIST.md\n  cakephp-host.md         # host-only notes from Part C\n",[34,1028,1026],{"__ignoreMap":140},[129,1030,1032],{"id":1031},"e0-rulescoremd","E0 — RULES.core.md",[134,1034,1038],{"className":1035,"code":1036,"language":1037,"meta":140,"style":140},"language-markdown shiki shiki-themes github-light github-dark","# Modular Hexagonal DDD — Core rules\nCanon: \u003CORIGIN>\u002Fv1\u002Fcore (1.0.0-draft)\nOne-shot: \u003CORIGIN>\u002Fapply\u002Fcakephp.full.md\nLocal: .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md\n\n1. Domain hardest: no host framework, ORM, other modules.\n2. Use Cases: own Domain + Shared ports only.\n3. Cross-module: ACL or Domain Events only.\n4. Thin façades; rich events (eventId, schemaVersion); idempotent consumers.\n5. No cross-module write TX; ACL validate-before-commit.\n6. Shared = technical ≥2 modules only.\n7. *UseCase + __invoke; no literal Feature\u002F folders.\n8. Design test: peer→HTTP, Application\u002FDomain still compile.\n","markdown",[34,1039,1040,1045,1050,1055,1060,1066,1071,1076,1081,1086,1092,1098,1104],{"__ignoreMap":140},[850,1041,1042],{"class":852,"line":853},[850,1043,1044],{},"# Modular Hexagonal DDD — Core rules\n",[850,1046,1047],{"class":852,"line":859},[850,1048,1049],{},"Canon: \u003CORIGIN>\u002Fv1\u002Fcore (1.0.0-draft)\n",[850,1051,1052],{"class":852,"line":865},[850,1053,1054],{},"One-shot: \u003CORIGIN>\u002Fapply\u002Fcakephp.full.md\n",[850,1056,1057],{"class":852,"line":871},[850,1058,1059],{},"Local: .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md\n",[850,1061,1062],{"class":852,"line":877},[850,1063,1065],{"emptyLinePlaceholder":1064},true,"\n",[850,1067,1068],{"class":852,"line":883},[850,1069,1070],{},"1. Domain hardest: no host framework, ORM, other modules.\n",[850,1072,1073],{"class":852,"line":889},[850,1074,1075],{},"2. Use Cases: own Domain + Shared ports only.\n",[850,1077,1078],{"class":852,"line":895},[850,1079,1080],{},"3. Cross-module: ACL or Domain Events only.\n",[850,1082,1083],{"class":852,"line":901},[850,1084,1085],{},"4. Thin façades; rich events (eventId, schemaVersion); idempotent consumers.\n",[850,1087,1089],{"class":852,"line":1088},10,[850,1090,1091],{},"5. No cross-module write TX; ACL validate-before-commit.\n",[850,1093,1095],{"class":852,"line":1094},11,[850,1096,1097],{},"6. Shared = technical ≥2 modules only.\n",[850,1099,1101],{"class":852,"line":1100},12,[850,1102,1103],{},"7. *UseCase + __invoke; no literal Feature\u002F folders.\n",[850,1105,1107],{"class":852,"line":1106},13,[850,1108,1109],{},"8. Design test: peer→HTTP, Application\u002FDomain still compile.\n",[129,1111,1113],{"id":1112},"e1-skillmd","E1 — SKILL.md",[134,1115,1117],{"className":1035,"code":1116,"language":1037,"meta":140,"style":140},"---\nname: modular-hexagonal-ddd\ndescription: Enforce Modular Hexagonal DDD. Modules, ACL, Events, Shared, Use Cases.\n---\nFollow .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md\n",[34,1118,1119,1124,1129,1134,1138],{"__ignoreMap":140},[850,1120,1121],{"class":852,"line":853},[850,1122,1123],{},"---\n",[850,1125,1126],{"class":852,"line":859},[850,1127,1128],{},"name: modular-hexagonal-ddd\n",[850,1130,1131],{"class":852,"line":865},[850,1132,1133],{},"description: Enforce Modular Hexagonal DDD. Modules, ACL, Events, Shared, Use Cases.\n",[850,1135,1136],{"class":852,"line":871},[850,1137,1123],{},[850,1139,1140],{"class":852,"line":877},[850,1141,1142],{},"Follow .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md\n",[129,1144,1146],{"id":1145},"e2-checklistmd","E2 — CHECKLIST.md",[134,1148,1150],{"className":1035,"code":1149,"language":1037,"meta":140,"style":140},"- [ ] First-level *UseCase entry\n- [ ] App DTO → __invoke\n- [ ] I\u002FO via Domain ports\n- [ ] No ORM\u002Ffacades in Application\u002FDomain\n- [ ] Sync peer → local ACL port → thin façade\n- [ ] Async → rich event + translation listener → inbound UC\n- [ ] Idempotent eventId\n- [ ] No cross-module DB TX\n- [ ] No foreign Application\u002FDomain imports\n- [ ] Shared only technical ≥2\n- [ ] No Feature\u002F directories\n- [ ] Replaceability test = yes\n",[34,1151,1152,1157,1162,1167,1172,1177,1182,1187,1192,1197,1202,1207],{"__ignoreMap":140},[850,1153,1154],{"class":852,"line":853},[850,1155,1156],{},"- [ ] First-level *UseCase entry\n",[850,1158,1159],{"class":852,"line":859},[850,1160,1161],{},"- [ ] App DTO → __invoke\n",[850,1163,1164],{"class":852,"line":865},[850,1165,1166],{},"- [ ] I\u002FO via Domain ports\n",[850,1168,1169],{"class":852,"line":871},[850,1170,1171],{},"- [ ] No ORM\u002Ffacades in Application\u002FDomain\n",[850,1173,1174],{"class":852,"line":877},[850,1175,1176],{},"- [ ] Sync peer → local ACL port → thin façade\n",[850,1178,1179],{"class":852,"line":883},[850,1180,1181],{},"- [ ] Async → rich event + translation listener → inbound UC\n",[850,1183,1184],{"class":852,"line":889},[850,1185,1186],{},"- [ ] Idempotent eventId\n",[850,1188,1189],{"class":852,"line":895},[850,1190,1191],{},"- [ ] No cross-module DB TX\n",[850,1193,1194],{"class":852,"line":901},[850,1195,1196],{},"- [ ] No foreign Application\u002FDomain imports\n",[850,1198,1199],{"class":852,"line":1088},[850,1200,1201],{},"- [ ] Shared only technical ≥2\n",[850,1203,1204],{"class":852,"line":1094},[850,1205,1206],{},"- [ ] No Feature\u002F directories\n",[850,1208,1209],{"class":852,"line":1100},[850,1210,1211],{},"- [ ] Replaceability test = yes\n",[129,1213,1215],{"id":1214},"e3-cursor","E3 — Cursor",[323,1217,1218,1224,1230],{},[77,1219,1220,1223],{},[34,1221,1222],{},".cursor\u002Frules\u002Fmodular-hexagonal-ddd.mdc"," ← E0 + path to ARCHITECTURE.full.md",[77,1225,1226,1229],{},[34,1227,1228],{},".cursor\u002Frules\u002Fcakephp-host.mdc"," ← Part C summary",[77,1231,1232,1235],{},[34,1233,1234],{},".cursor\u002Fskills\u002Fmodular-hexagonal-ddd\u002FSKILL.md"," ← E1",[129,1237,1239],{"id":1238},"e4-claude","E4 — Claude",[323,1241,1242,1248],{},[77,1243,1244,1247],{},[34,1245,1246],{},"CLAUDE.md"," ← pointer to ARCHITECTURE.full.md + E0",[77,1249,1250,1251],{},"Shared ",[34,1252,1253],{},".ai\u002Fmodular-hexagonal-ddd\u002F*",[129,1255,1257],{"id":1256},"e5-gemini","E5 — Gemini",[323,1259,1260,1269],{},[77,1261,1262,736,1265,1268],{},[34,1263,1264],{},"GEMINI.md",[34,1266,1267],{},".gemini\u002Finstructions.md"," ← pointer + E0",[77,1270,1250,1271],{},[34,1272,1273],{},".ai\u002F*",[129,1275,1277],{"id":1276},"e6-github-copilot","E6 — GitHub Copilot",[323,1279,1280],{},[77,1281,1282,1285],{},[34,1283,1284],{},".github\u002Fcopilot-instructions.md"," ← E0 + short host section",[129,1287,1289],{"id":1288},"e7-generic","E7 — Generic",[323,1291,1292],{},[77,1293,1294,1297,1298],{},[34,1295,1296],{},"AGENTS.md"," pointing at ",[34,1299,1300],{},".ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md",[129,1302,1304],{"id":1303},"e8-multiple-vendors","E8 — Multiple vendors",[18,1306,1307,1308,1311],{},"One shared ",[34,1309,1310],{},".ai\u002Fmodular-hexagonal-ddd\u002F","; vendor entry files only point to it.",[1313,1314,1315],"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":140,"searchDepth":859,"depth":859,"links":1317},[1318,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1338,1340,1341,1343,1344,1346,1347],{"id":64,"depth":859,"text":65,"children":1319},[1320],{"id":131,"depth":865,"text":132},{"id":169,"depth":859,"text":170},{"id":184,"depth":859,"text":185},{"id":207,"depth":859,"text":208},{"id":310,"depth":859,"text":311},{"id":320,"depth":859,"text":321},{"id":381,"depth":859,"text":382},{"id":475,"depth":859,"text":476},{"id":541,"depth":859,"text":542},{"id":553,"depth":859,"text":554},{"id":563,"depth":859,"text":564},{"id":573,"depth":859,"text":574},{"id":588,"depth":859,"text":589,"children":1333},[1334,1335,1336,1337],{"id":805,"depth":865,"text":806},{"id":840,"depth":865,"text":841},{"id":913,"depth":865,"text":914},{"id":930,"depth":865,"text":931},{"id":956,"depth":859,"text":1339},"D1 — Confirm CakePHP 5.4 app (cakephp\u002Fcakephp ^5.4)",{"id":964,"depth":859,"text":965},{"id":968,"depth":859,"text":1342},"D3–D5 — ROADMAP \u002F PRD \u002F .ai ARCHITECTURE copy",{"id":976,"depth":859,"text":977},{"id":980,"depth":859,"text":1345},"D7 — Register plugin + services() bindings",{"id":988,"depth":859,"text":989},{"id":992,"depth":859,"text":993,"children":1348},[1349,1350,1351,1352,1353,1354,1355,1356,1357],{"id":1031,"depth":865,"text":1032},{"id":1112,"depth":865,"text":1113},{"id":1145,"depth":865,"text":1146},{"id":1214,"depth":865,"text":1215},{"id":1238,"depth":865,"text":1239},{"id":1256,"depth":865,"text":1257},{"id":1276,"depth":865,"text":1277},{"id":1288,"depth":865,"text":1289},{"id":1303,"depth":865,"text":1304},"Self-contained Modular Hexagonal DDD + CakePHP 5.4 apply playbook for AI agents.","md",{},"\u002Fv1\u002Fadopt\u002Fapply\u002Fcakephp-full",{"title":5,"description":1358},"v1\u002Fadopt\u002Fapply\u002Fcakephp-full","KYkBGhiBOnYZ788uHg8JPZN4KVng6dhPBcvniq29ZXY",1786241410354]