[{"data":1,"prerenderedAt":1369},["ShallowReactive",2],{"page-\u002Fv1\u002Fadopt\u002Fapply\u002Fsymfony-full":3},{"id":4,"title":5,"body":6,"description":1362,"extension":1363,"meta":1364,"navigation":1064,"path":1365,"seo":1366,"stem":1367,"__hash__":1368},"content\u002Fv1\u002Fadopt\u002Fapply\u002Fsymfony-full.md","Symfony one-shot apply (full architecture)",{"type":7,"value":8,"toc":1320},"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,665,680,787,791,816,820,868,871,875,906,910,921,923,927,931,941,945,951,955,962,966,974,978,982,984,988,995,997,1001,1008,1010,1014,1019,1022,1028,1032,1114,1118,1147,1151,1216,1220,1240,1244,1258,1262,1279,1283,1291,1295,1305,1309,1316],[10,11,13],"h1",{"id":12},"modular-hexagonal-ddd-one-shot-apply-symfony","Modular Hexagonal DDD — ONE-SHOT APPLY (symfony)",[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],{},"\u002Fsymfony"," · ",[21,45,46],{},"This file:",[34,48,49],{},"\u002Fapply\u002Fsymfony.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],{},"symfony 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\u002Fsymfony.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-symfony-host-mapping","Part C — Symfony host mapping",[210,606,607,615],{},[213,608,609],{},[216,610,611,613],{},[219,612],{},[219,614],{},[232,616,617,634,653],{},[216,618,619,624],{},[237,620,621],{},[21,622,623],{},"Target",[237,625,626,629,630,633],{},[21,627,628],{},"Symfony 8.1.x"," (current stable as of 2026-08; PHP ",[21,631,632],{},"≥ 8.4",")",[216,635,636,641],{},[237,637,638],{},[21,639,640],{},"Docs",[237,642,643,43,649],{},[644,645,646],"a",{"href":646,"rel":647},"https:\u002F\u002Fsymfony.com\u002Fdoc\u002Fcurrent\u002F",[648],"nofollow",[644,650,651],{"href":651,"rel":652},"https:\u002F\u002Fsymfony.com\u002Freleases\u002F8.1",[648],[216,654,655,660],{},[237,656,657],{},[21,658,659],{},"Adapter HTML",[237,661,662],{},[34,663,664],{},"\u003CORIGIN>\u002Fv1\u002Fadapters\u002Fsymfony",[18,666,667,668,675,676,679],{},"Use Flex app skeleton. Prefer ",[21,669,670,671,674],{},"one Symfony bundle (or ",[34,672,673],{},"src\u002F"," namespace) per bounded context"," with Core layers inside — not anemic ",[34,677,678],{},"src\u002FEntity"," dump for all domains.",[210,681,682,692],{},[213,683,684],{},[216,685,686,689],{},[219,687,688],{},"Core",[219,690,691],{},"Symfony 8.1 place",[232,693,694,711,721,742,753,764,776],{},[216,695,696,699],{},[237,697,698],{},"Module root",[237,700,701,32,704,32,707,710],{},[34,702,703],{},"src\u002F{Module}\u002F",[21,705,706],{},"or",[34,708,709],{},"src\u002F{Module}Bundle\u002F"," (PSR-4)",[216,712,713,716],{},[237,714,715],{},"Shared",[237,717,718],{},[34,719,720],{},"src\u002FShared\u002F",[216,722,723,725],{},[237,724,278],{},[237,726,727,730,731,734,735,738,739],{},[34,728,729],{},"config\u002Fservices.yaml"," (+ per-module ",[34,732,733],{},"config\u002Fservices\u002F{module}.yaml",") and\u002For bundle ",[34,736,737],{},"Extension"," \u002F compiler passes — ",[21,740,741],{},"wiring only",[216,743,744,747],{},[237,745,746],{},"Persistence",[237,748,749,752],{},[34,750,751],{},"Infrastructure\u002FPersistence\u002FDoctrine\u002F"," — Entity (Doctrine) + Repository adapters mapping to Domain Entities",[216,754,755,758],{},[237,756,757],{},"ACL adapter",[237,759,760,763],{},[34,761,762],{},"Infrastructure\u002FExternalServices\u002F*AclAdapter.php"," as services",[216,765,766,769],{},[237,767,768],{},"Translation listener",[237,770,771,772,775],{},"Messenger ",[21,773,774],{},"handler"," in consumer Infra → inbound Use Case (async transport)",[216,777,778,781],{},[237,779,780],{},"UI",[237,782,783,786],{},[34,784,785],{},"UI\u002FHttp"," controllers \u002F API Platform resource adapters calling Use Cases — not Domain",[129,788,790],{"id":789},"doctrine-must-quarantine","Doctrine (MUST quarantine)",[323,792,793,800,803,813],{},[77,794,795,796,799],{},"Doctrine ORM entities\u002Fdocuments live in ",[21,797,798],{},"Infrastructure"," (or a clearly named Infra persistence model).",[77,801,802],{},"Domain Entities are plain PHP; repositories implement Domain ports and map to\u002Ffrom Doctrine models.",[77,804,805,808,809,812],{},[21,806,807],{},"Never"," inject ",[34,810,811],{},"EntityManagerInterface"," into Use Cases or Domain.",[77,814,815],{},"Do not put Doctrine entities in messages — pass ids\u002Fprimitives (Messenger docs warn about this).",[129,817,819],{"id":818},"di","DI",[134,821,825],{"className":822,"code":823,"language":824,"meta":140,"style":140},"language-yaml shiki shiki-themes github-light github-dark","# config\u002Fservices\u002Fordering.yaml (example)\nservices:\n  App\\Modules\\Ordering\\Domain\\Ports\\Acl\\WarehouseAvailabilityPortInterface:\n    alias: App\\Modules\\Ordering\\Infrastructure\\ExternalServices\\WarehouseAvailabilityAclAdapter\n","yaml",[34,826,827,836,847,855],{"__ignoreMap":140},[828,829,832],"span",{"class":830,"line":831},"line",1,[828,833,835],{"class":834},"sJ8bj","# config\u002Fservices\u002Fordering.yaml (example)\n",[828,837,839,843],{"class":830,"line":838},2,[828,840,842],{"class":841},"s9eBZ","services",[828,844,846],{"class":845},"sVt8B",":\n",[828,848,850,853],{"class":830,"line":849},3,[828,851,852],{"class":841},"  App\\Modules\\Ordering\\Domain\\Ports\\Acl\\WarehouseAvailabilityPortInterface",[828,854,846],{"class":845},[828,856,858,861,864],{"class":830,"line":857},4,[828,859,860],{"class":841},"    alias",[828,862,863],{"class":845},": ",[828,865,867],{"class":866},"sZZnC","App\\Modules\\Ordering\\Infrastructure\\ExternalServices\\WarehouseAvailabilityAclAdapter\n",[18,869,870],{},"Autoconfigure is fine for Infra\u002FUI; Domain stays free of Symfony attributes that pull the framework into the Domain model (prefer ports).",[129,872,874],{"id":873},"messenger-domain-events","Messenger (Domain Events)",[323,876,877,883,889,900],{},[77,878,879,880,882],{},"Publisher Use Case → Shared ",[34,881,457],{}," → adapter dispatches to Messenger.",[77,884,885,886,888],{},"Consumer: message handler in ",[21,887,798],{}," maps stamp\u002Fpayload → Application DTO → inbound Use Case.",[77,890,891,892,895,896,899],{},"Use async transport (",[34,893,894],{},"doctrine:\u002F\u002F",", Redis, etc.); configure ",[34,897,898],{},"auto_setup=false"," in production for Doctrine transport.",[77,901,902,903,905],{},"Idempotency on ",[34,904,461],{}," in consumer Infra.",[129,907,909],{"id":908},"tooling","Tooling",[323,911,912,915],{},[77,913,914],{},"PHP-CS-Fixer \u002F Symfony CS; PHPUnit or Pest; PHPStan level appropriate; optional Deptrac\u002FArkitect for layer rules.",[77,916,917,920],{},[34,918,919],{},"bin\u002Fconsole"," for wiring — never for business rules inside Domain.",[59,922],{},[10,924,926],{"id":925},"part-d-apply-procedure-symfony","Part D — Apply procedure (Symfony)",[62,928,930],{"id":929},"d1-confirm-host","D1 — Confirm host",[18,932,933,934,32,937,940],{},"Symfony Flex app with ",[34,935,936],{},"symfony\u002Fframework-bundle",[21,938,939],{},"8.1.","* (or document older 7.4 LTS if constrained — still apply Core).",[62,942,944],{"id":943},"d2-readme-pointer","D2 — README pointer",[134,946,949],{"className":947,"code":948,"language":139,"meta":140},[137],"Architecture: Modular Hexagonal Domain-Driven Design\nOne-shot: \u003CORIGIN>\u002Fapply\u002Fsymfony.full.md\nHost: Symfony 8.1 · PHP ≥ 8.4\nModules: src\u002F{Module}\u002F · Shared: src\u002FShared\u002F\n",[34,950,948],{"__ignoreMap":140},[62,952,954],{"id":953},"d3d4-roadmap-optional-prd-product-only","D3–D4 — ROADMAP \u002F optional PRD (product only)",[62,956,958,959],{"id":957},"d5-copy-one-shot-aimodular-hexagonal-dddarchitecturefullmd","D5 — Copy one-shot → ",[34,960,961],{},".ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md",[62,963,965],{"id":964},"d6-composer-psr-4-for-modules-shared","D6 — Composer PSR-4 for Modules + Shared",[62,967,969,970,973],{"id":968},"d7-optional-first-module-under-srcmoduleapplicationdomaininfrastructureui-services-yaml","D7 — Optional first module under ",[34,971,972],{},"src\u002F{Module}\u002F{Application,Domain,Infrastructure,UI}"," + services yaml",[62,975,977],{"id":976},"d8-layer-arch-tests-deptrac-or-phpstan-custom-for-part-b13","D8 — Layer \u002F arch tests (Deptrac or PHPStan custom) for Part B13",[62,979,981],{"id":980},"d9-part-e-then-report-no-commit-unless-asked","D9 — Part E then report — no commit unless asked",[59,983],{},[10,985,987],{"id":986},"part-f-sketch","Part F — Sketch",[18,989,990,991,994],{},"Ordering ACL → Warehouse façade service; Messenger handles ",[34,992,993],{},"OrderFulfilled"," in Warehouse Infra handler.",[59,996],{},[10,998,1000],{"id":999},"part-g-done","Part G — Done",[18,1002,1003,1004,1007],{},"Pointers + ",[34,1005,1006],{},".ai"," mirror + AI files + test plan; no unauthorized commit.",[59,1009],{},[10,1011,1013],{"id":1012},"part-e-assistant-files-optional","Part E — Assistant files (optional)",[18,1015,1016,1017,97],{},"Skip if AI vendor is ",[34,1018,126],{},[18,1020,1021],{},"Create shared folder:",[134,1023,1026],{"className":1024,"code":1025,"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  symfony-host.md         # host-only notes from Part C\n",[34,1027,1025],{"__ignoreMap":140},[129,1029,1031],{"id":1030},"e0-rulescoremd","E0 — RULES.core.md",[134,1033,1037],{"className":1034,"code":1035,"language":1036,"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\u002Fsymfony.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,1038,1039,1044,1049,1054,1059,1066,1072,1078,1084,1090,1096,1102,1108],{"__ignoreMap":140},[828,1040,1041],{"class":830,"line":831},[828,1042,1043],{},"# Modular Hexagonal DDD — Core rules\n",[828,1045,1046],{"class":830,"line":838},[828,1047,1048],{},"Canon: \u003CORIGIN>\u002Fv1\u002Fcore (1.0.0-draft)\n",[828,1050,1051],{"class":830,"line":849},[828,1052,1053],{},"One-shot: \u003CORIGIN>\u002Fapply\u002Fsymfony.full.md\n",[828,1055,1056],{"class":830,"line":857},[828,1057,1058],{},"Local: .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md\n",[828,1060,1062],{"class":830,"line":1061},5,[828,1063,1065],{"emptyLinePlaceholder":1064},true,"\n",[828,1067,1069],{"class":830,"line":1068},6,[828,1070,1071],{},"1. Domain hardest: no host framework, ORM, other modules.\n",[828,1073,1075],{"class":830,"line":1074},7,[828,1076,1077],{},"2. Use Cases: own Domain + Shared ports only.\n",[828,1079,1081],{"class":830,"line":1080},8,[828,1082,1083],{},"3. Cross-module: ACL or Domain Events only.\n",[828,1085,1087],{"class":830,"line":1086},9,[828,1088,1089],{},"4. Thin façades; rich events (eventId, schemaVersion); idempotent consumers.\n",[828,1091,1093],{"class":830,"line":1092},10,[828,1094,1095],{},"5. No cross-module write TX; ACL validate-before-commit.\n",[828,1097,1099],{"class":830,"line":1098},11,[828,1100,1101],{},"6. Shared = technical ≥2 modules only.\n",[828,1103,1105],{"class":830,"line":1104},12,[828,1106,1107],{},"7. *UseCase + __invoke; no literal Feature\u002F folders.\n",[828,1109,1111],{"class":830,"line":1110},13,[828,1112,1113],{},"8. Design test: peer→HTTP, Application\u002FDomain still compile.\n",[129,1115,1117],{"id":1116},"e1-skillmd","E1 — SKILL.md",[134,1119,1121],{"className":1034,"code":1120,"language":1036,"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,1122,1123,1128,1133,1138,1142],{"__ignoreMap":140},[828,1124,1125],{"class":830,"line":831},[828,1126,1127],{},"---\n",[828,1129,1130],{"class":830,"line":838},[828,1131,1132],{},"name: modular-hexagonal-ddd\n",[828,1134,1135],{"class":830,"line":849},[828,1136,1137],{},"description: Enforce Modular Hexagonal DDD. Modules, ACL, Events, Shared, Use Cases.\n",[828,1139,1140],{"class":830,"line":857},[828,1141,1127],{},[828,1143,1144],{"class":830,"line":1061},[828,1145,1146],{},"Follow .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md\n",[129,1148,1150],{"id":1149},"e2-checklistmd","E2 — CHECKLIST.md",[134,1152,1154],{"className":1034,"code":1153,"language":1036,"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,1155,1156,1161,1166,1171,1176,1181,1186,1191,1196,1201,1206,1211],{"__ignoreMap":140},[828,1157,1158],{"class":830,"line":831},[828,1159,1160],{},"- [ ] First-level *UseCase entry\n",[828,1162,1163],{"class":830,"line":838},[828,1164,1165],{},"- [ ] App DTO → __invoke\n",[828,1167,1168],{"class":830,"line":849},[828,1169,1170],{},"- [ ] I\u002FO via Domain ports\n",[828,1172,1173],{"class":830,"line":857},[828,1174,1175],{},"- [ ] No ORM\u002Ffacades in Application\u002FDomain\n",[828,1177,1178],{"class":830,"line":1061},[828,1179,1180],{},"- [ ] Sync peer → local ACL port → thin façade\n",[828,1182,1183],{"class":830,"line":1068},[828,1184,1185],{},"- [ ] Async → rich event + translation listener → inbound UC\n",[828,1187,1188],{"class":830,"line":1074},[828,1189,1190],{},"- [ ] Idempotent eventId\n",[828,1192,1193],{"class":830,"line":1080},[828,1194,1195],{},"- [ ] No cross-module DB TX\n",[828,1197,1198],{"class":830,"line":1086},[828,1199,1200],{},"- [ ] No foreign Application\u002FDomain imports\n",[828,1202,1203],{"class":830,"line":1092},[828,1204,1205],{},"- [ ] Shared only technical ≥2\n",[828,1207,1208],{"class":830,"line":1098},[828,1209,1210],{},"- [ ] No Feature\u002F directories\n",[828,1212,1213],{"class":830,"line":1104},[828,1214,1215],{},"- [ ] Replaceability test = yes\n",[129,1217,1219],{"id":1218},"e3-cursor","E3 — Cursor",[323,1221,1222,1228,1234],{},[77,1223,1224,1227],{},[34,1225,1226],{},".cursor\u002Frules\u002Fmodular-hexagonal-ddd.mdc"," ← E0 + path to ARCHITECTURE.full.md",[77,1229,1230,1233],{},[34,1231,1232],{},".cursor\u002Frules\u002Fsymfony-host.mdc"," ← Part C summary",[77,1235,1236,1239],{},[34,1237,1238],{},".cursor\u002Fskills\u002Fmodular-hexagonal-ddd\u002FSKILL.md"," ← E1",[129,1241,1243],{"id":1242},"e4-claude","E4 — Claude",[323,1245,1246,1252],{},[77,1247,1248,1251],{},[34,1249,1250],{},"CLAUDE.md"," ← pointer to ARCHITECTURE.full.md + E0",[77,1253,1254,1255],{},"Shared ",[34,1256,1257],{},".ai\u002Fmodular-hexagonal-ddd\u002F*",[129,1259,1261],{"id":1260},"e5-gemini","E5 — Gemini",[323,1263,1264,1274],{},[77,1265,1266,1269,1270,1273],{},[34,1267,1268],{},"GEMINI.md"," or ",[34,1271,1272],{},".gemini\u002Finstructions.md"," ← pointer + E0",[77,1275,1254,1276],{},[34,1277,1278],{},".ai\u002F*",[129,1280,1282],{"id":1281},"e6-github-copilot","E6 — GitHub Copilot",[323,1284,1285],{},[77,1286,1287,1290],{},[34,1288,1289],{},".github\u002Fcopilot-instructions.md"," ← E0 + short host section",[129,1292,1294],{"id":1293},"e7-generic","E7 — Generic",[323,1296,1297],{},[77,1298,1299,1302,1303],{},[34,1300,1301],{},"AGENTS.md"," pointing at ",[34,1304,961],{},[129,1306,1308],{"id":1307},"e8-multiple-vendors","E8 — Multiple vendors",[18,1310,1311,1312,1315],{},"One shared ",[34,1313,1314],{},".ai\u002Fmodular-hexagonal-ddd\u002F","; vendor entry files only point to it.",[1317,1318,1319],"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);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":140,"searchDepth":838,"depth":838,"links":1321},[1322,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1342,1343,1344,1345,1347,1348,1350,1351],{"id":64,"depth":838,"text":65,"children":1323},[1324],{"id":131,"depth":849,"text":132},{"id":169,"depth":838,"text":170},{"id":184,"depth":838,"text":185},{"id":207,"depth":838,"text":208},{"id":310,"depth":838,"text":311},{"id":320,"depth":838,"text":321},{"id":381,"depth":838,"text":382},{"id":475,"depth":838,"text":476},{"id":541,"depth":838,"text":542},{"id":553,"depth":838,"text":554},{"id":563,"depth":838,"text":564},{"id":573,"depth":838,"text":574},{"id":588,"depth":838,"text":589,"children":1337},[1338,1339,1340,1341],{"id":789,"depth":849,"text":790},{"id":818,"depth":849,"text":819},{"id":873,"depth":849,"text":874},{"id":908,"depth":849,"text":909},{"id":929,"depth":838,"text":930},{"id":943,"depth":838,"text":944},{"id":953,"depth":838,"text":954},{"id":957,"depth":838,"text":1346},"D5 — Copy one-shot → .ai\u002Fmodular-hexagonal-ddd\u002FARCHITECTURE.full.md",{"id":964,"depth":838,"text":965},{"id":968,"depth":838,"text":1349},"D7 — Optional first module under src\u002F{Module}\u002F{Application,Domain,Infrastructure,UI} + services yaml",{"id":976,"depth":838,"text":977},{"id":980,"depth":838,"text":981,"children":1352},[1353,1354,1355,1356,1357,1358,1359,1360,1361],{"id":1030,"depth":849,"text":1031},{"id":1116,"depth":849,"text":1117},{"id":1149,"depth":849,"text":1150},{"id":1218,"depth":849,"text":1219},{"id":1242,"depth":849,"text":1243},{"id":1260,"depth":849,"text":1261},{"id":1281,"depth":849,"text":1282},{"id":1293,"depth":849,"text":1294},{"id":1307,"depth":849,"text":1308},"Self-contained Modular Hexagonal DDD + Symfony 8.1 apply playbook for AI agents.","md",{},"\u002Fv1\u002Fadopt\u002Fapply\u002Fsymfony-full",{"title":5,"description":1362},"v1\u002Fadopt\u002Fapply\u002Fsymfony-full","blGv3VwFBU1Gd3t-IhRaFqNQC32jWOupkuD8uUD3gZY",1786241408965]