[{"data":1,"prerenderedAt":3201},["ShallowReactive",2],{"docs-nav":3,"docs:\u002Fdocs\u002Freference\u002Fconfiguration":139},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136],{"path":5,"title":6},"\u002Fdocs\u002Faccess-gating","Protect a local route",{"path":8,"title":9},"\u002Fdocs\u002Farchitecture\u002Fsecurity-and-trust","Security and trust",{"path":11,"title":12},"\u002Fdocs\u002Fconcepts\u002Fbuilds-and-deployments","Build and deploy",{"path":14,"title":15},"\u002Fdocs\u002Fconcepts\u002Fconfiguration-ownership","Where configuration belongs",{"path":17,"title":18},"\u002Fdocs\u002Fconcepts\u002Fenvironments-and-secrets","Environment values and secrets",{"path":20,"title":21},"\u002Fdocs\u002Fconcepts\u002Fmental-model","How projects fit together",{"path":23,"title":24},"\u002Fdocs\u002Fconcepts\u002Fplans-and-apply","Plans and apply",{"path":26,"title":27},"\u002Fdocs\u002Fconcepts\u002Ftargets-and-runtimes","Choose a target and runtime",{"path":29,"title":30},"\u002Fdocs\u002Fcontribute\u002Freleases","Publish a release",{"path":32,"title":33},"\u002Fdocs\u002Fdevelopment-mounts","Development mounts",{"path":35,"title":36},"\u002Fdocs\u002Fgetting-started","Getting started",{"path":38,"title":39},"\u002Fdocs\u002Fhelp\u002Ffaq","FAQ",{"path":41,"title":42},"\u002Fdocs\u002Fhelp\u002Ftroubleshooting","Troubleshooting",{"path":44,"title":45},"\u002Fdocs\u002Fhow-to\u002Fdeploy-production","Prepare a deployment environment",{"path":47,"title":48},"\u002Fdocs\u002Fhow-to\u002Fswarm-cluster","Run on a multi-node Swarm",{"path":50,"title":51},"\u002Fdocs","mm documentation",{"path":53,"title":54},"\u002Fdocs\u002Fjobs-and-schedules","Jobs and schedules",{"path":56,"title":57},"\u002Fdocs\u002Flocal-dashboard","Local dashboard",{"path":59,"title":60},"\u002Fdocs\u002Flocal-https","Local HTTPS",{"path":62,"title":63},"\u002Fdocs\u002Flocal-services","Local services",{"path":65,"title":66},"\u002Fdocs\u002Fmcp","Let an AI agent work on your project",{"path":68,"title":69},"\u002Fdocs\u002Fmulti-project-hosts","Run multiple projects on one host",{"path":71,"title":72},"\u002Fdocs\u002Fonboarding","Set up a project",{"path":74,"title":75},"\u002Fdocs\u002Fopenbao","Use OpenBao",{"path":77,"title":78},"\u002Fdocs\u002Fproject\u002Fcontributing","Contributing",{"path":80,"title":81},"\u002Fdocs\u002Fproject\u002Flicense","License",{"path":83,"title":84},"\u002Fdocs\u002Fproject\u002Fsecurity","Security",{"path":86,"title":87},"\u002Fdocs\u002Freference\u002Fcapability-matrix","Supported features and platforms",{"path":89,"title":90},"\u002Fdocs\u002Freference\u002Fcli","CLI command reference",{"path":92,"title":93},"\u002Fdocs\u002Freference\u002Fconfiguration","Configuration",{"path":95,"title":96},"\u002Fdocs\u002Freference\u002Fenvironment-variables","Environment variables",{"path":98,"title":99},"\u002Fdocs\u002Freference\u002Ferrors-and-exit-codes","Errors and exit codes",{"path":101,"title":102},"\u002Fdocs\u002Freference\u002Fknown-issues","Known limitations",{"path":104,"title":105},"\u002Fdocs\u002Fremote-access","Manage remote access",{"path":107,"title":108},"\u002Fdocs\u002Fremote-daemon","Set up a remote host",{"path":110,"title":111},"\u002Fdocs\u002Fruntime-observability","Status, logs, and commands",{"path":113,"title":114},"\u002Fdocs\u002Fsecret-delivery","Pass secrets to your app",{"path":116,"title":117},"\u002Fdocs\u002Fsecret-providers","Choose a secret store",{"path":119,"title":120},"\u002Fdocs\u002Fstart\u002Finstall","Install mm",{"path":122,"title":123},"\u002Fdocs\u002Fterminal-ui","Terminal UI",{"path":125,"title":126},"\u002Fdocs\u002Ftutorials\u002Fdotnet-web-api",".NET web API example",{"path":128,"title":129},"\u002Fdocs\u002Ftutorials\u002Ffirst-local-app","First local app",{"path":131,"title":132},"\u002Fdocs\u002Ftutorials\u002Flaravel-rust","Laravel and Rust example",{"path":134,"title":135},"\u002Fdocs\u002Ftutorials\u002Fnode-fullstack","Node full stack example",{"path":137,"title":138},"\u002Fdocs\u002Fvault","Use HashiCorp Vault",{"id":140,"title":93,"body":141,"description":3195,"extension":3196,"meta":3197,"navigation":974,"path":92,"seo":3198,"stem":3199,"__hash__":3200},"docs\u002Fdocs\u002Freference\u002Fconfiguration.md",{"type":142,"value":143,"toc":3184},"minimark",[144,175,183,193,196,211,216,222,260,278,284,302,306,313,375,397,400,431,434,508,514,520,536,540,548,935,945,949,1224,1248,1268,1272,1696,1719,1736,1742,1811,1814,1847,1857,1870,1873,2183,2207,2213,2343,2347,2354,2550,2565,2838,2872,2876,3096,3111,3115,3121,3150,3166,3172,3175,3180],[145,146,147,148,152,153,156,157,160,161,164,165,170,171,174],"p",{},"mm discovers the shared project file, ",[149,150,151],"code",{},".config\u002Fmm.yaml",", starting at ",[149,154,155],{},"--root","\n(or the current directory) and searching its parents. Any top-level key except\n",[149,158,159],{},"schema-version"," can instead live in its own file under ",[149,162,163],{},".config\u002Fmm\u002F"," (see\n",[166,167,169],"a",{"href":168},"#split-a-large-configuration","split a large configuration","). If present,\n",[149,172,173],{},".config\u002Fmm.overrides.yaml"," beside that file supplies checkout-local settings.",[145,176,177,178,182],{},"The current schema is ",[179,180,181],"strong",{},"version 1",":",[184,185,191],"pre",{"className":186,"code":188,"language":189,"meta":190},[187],"language-text","schema-version: 1\n","text","",[149,192,188],{"__ignoreMap":190},[145,194,195],{},"Unknown fields are errors throughout the typed schema. YAML must be valid UTF-8,\neach configuration file must be a regular file no larger than 1 MiB (4 MiB across\nall of them), and neither they nor configured project paths may contain symlink\ncomponents. On Unix, files mm\nedits must be owned by the current user and not writable by group or others;\nproject directories have the equivalent ownership and write restrictions.",[145,197,198,199,202,203,206,207,210],{},"Paths in configuration are project-relative unless a field explicitly says\notherwise. Absolute paths and ",[149,200,201],{},".."," traversal are rejected. Compose files and\nmodule directories must exist. Build contexts and Dockerfiles are relative to\ntheir module; ",[149,204,205],{},"build.extra-inputs"," are relative to the project root. A\ndevelopment mount ",[149,208,209],{},"target"," is instead an absolute POSIX container path.",[212,213,215],"h2",{"id":214},"local-overrides","Local overrides",[145,217,218,219,221],{},"Create ",[149,220,173],{}," with just the settings to change locally:",[184,223,227],{"className":224,"code":225,"language":226,"meta":190,"style":190},"language-yaml shiki shiki-themes mm","build:\n  platforms: [linux\u002Farm64]\n","yaml",[149,228,229,242],{"__ignoreMap":190},[230,231,234,238],"span",{"class":232,"line":233},"line",1,[230,235,237],{"class":236},"sWZmh","build",[230,239,241],{"class":240},"sIbZ0",":\n",[230,243,245,248,250,253,257],{"class":232,"line":244},2,[230,246,247],{"class":236},"  platforms",[230,249,182],{"class":240},[230,251,252],{"class":240}," [",[230,254,256],{"class":255},"sv8ni","linux\u002Farm64",[230,258,259],{"class":240},"]\n",[145,261,262,263,266,267,270,271,274,275,277],{},"The override uses the same field names as the shared file. Maps merge recursively;\nscalars and lists replace the shared value; omitted keys inherit it. An empty\nmap leaves inherited keys intact. ",[149,264,265],{},"null"," is an explicit value: it clears nullable\nfields, such as ",[149,268,269],{},"default-environment",", and is invalid for non-nullable fields.\nUse ",[149,272,273],{},"{}"," for an empty override file. The shared configuration must remain complete\nand valid on its own; defaults are applied when deserializing the merged result.\nBoth sources use schema version 1, and the override need not repeat ",[149,276,159],{},".",[145,279,280,281,283],{},"All project commands use the effective configuration, including validation,\nbuilds, deployment and setup inspection. Existing CLI and private target\u002Fruntime\npreference precedence still applies. Paths keep their usual project-relative\nmeaning. An invalid override is an error, rather than a fallback to shared values.\nChanging either source requires a new review for configuration-dependent plans.\nConfig-editing commands write the shared file that declares the key, either\n",[149,282,151],{}," or its split file; a local override still takes precedence\nover an edited shared setting.",[145,285,286,289,290,293,294,297,298,277],{},[149,287,288],{},"mm init"," includes ",[149,291,292],{},"\u002F.config\u002Fmm.overrides.yaml"," in the project ",[149,295,296],{},".gitignore"," as\npart of its reviewed setup. Existing projects should add and commit this rule\nonce. Keep the override untracked. See ",[166,299,301],{"href":300},"..\u002Fconcepts\u002Fbuilds-and-deployments#local-build-platforms","local build platforms",[212,303,305],{"id":304},"split-a-large-configuration","Split a large configuration",[145,307,308,309,312],{},"When one key grows large, or needs its own reviewers, move it to its own file.\n",[149,310,311],{},"mm config split"," reviews the move first, like other config edits:",[184,314,318],{"className":315,"code":316,"language":317,"meta":190,"style":190},"language-sh shiki shiki-themes mm","mm config split stacks                        # prints the plan and its hash\nmm config split stacks --plan HASH --yes      # applies exactly that plan\nmm config sources                             # shows where each key lives\n","sh",[149,319,320,339,362],{"__ignoreMap":190},[230,321,322,326,329,332,335],{"class":232,"line":233},[230,323,325],{"class":324},"svrjQ","mm",[230,327,328],{"class":255}," config",[230,330,331],{"class":255}," split",[230,333,334],{"class":255}," stacks",[230,336,338],{"class":337},"sP7nD","                        # prints the plan and its hash\n",[230,340,341,343,345,347,349,353,356,359],{"class":232,"line":244},[230,342,325],{"class":324},[230,344,328],{"class":255},[230,346,331],{"class":255},[230,348,334],{"class":255},[230,350,352],{"class":351},"sbRf1"," --plan",[230,354,355],{"class":255}," HASH",[230,357,358],{"class":351}," --yes",[230,360,361],{"class":337},"      # applies exactly that plan\n",[230,363,365,367,369,372],{"class":232,"line":364},3,[230,366,325],{"class":324},[230,368,328],{"class":255},[230,370,371],{"class":255}," sources",[230,373,374],{"class":337},"                             # shows where each key lives\n",[145,376,377,378,381,382,385,386,388,389,392,393,396],{},"Expected result: ",[149,379,380],{},".config\u002Fmm\u002Fstacks.yaml"," holds the value of ",[149,383,384],{},"stacks",", with its\ncomments, and ",[149,387,151],{}," no longer has a ",[149,390,391],{},"stacks:"," key. The plan is\nrefused unless the project means exactly the same thing before and after the\nmove. ",[149,394,395],{},"mm config join stacks"," moves the key back.",[145,398,399],{},"A split file holds only the key's value, without the key itself:",[184,401,403],{"className":224,"code":402,"language":226,"meta":190,"style":190},"# .config\u002Fmm\u002Fstacks.yaml\napp:\n  files: [compose.yaml]\n",[149,404,405,410,417],{"__ignoreMap":190},[230,406,407],{"class":232,"line":233},[230,408,409],{"class":337},"# .config\u002Fmm\u002Fstacks.yaml\n",[230,411,412,415],{"class":232,"line":244},[230,413,414],{"class":236},"app",[230,416,241],{"class":240},[230,418,419,422,424,426,429],{"class":232,"line":364},[230,420,421],{"class":236},"  files",[230,423,182],{"class":240},[230,425,252],{"class":240},[230,427,428],{"class":255},"compose.yaml",[230,430,259],{"class":240},[145,432,433],{},"You can also create or edit these files by hand. The rules:",[435,436,437,449,455,477,483,489,494,505],"ul",{},[438,439,440,442,443,445,446,277],"li",{},[149,441,151],{}," is still required. mm finds the project by it, and it keeps\n",[149,444,159],{},". Every other top-level key can be split, including ",[149,447,448],{},"project",[438,450,451,452,454],{},"Each key lives in exactly one place. A key in both ",[149,453,151],{}," and its\nsplit file is an error that names both; nothing is merged.",[438,456,457,458,461,462,465,466,469,470,472,473,476],{},"File names are the exact key plus ",[149,459,460],{},".yaml",", such as\n",[149,463,464],{},".config\u002Fmm\u002Fenvironment-delivery.yaml",". Any other file, a ",[149,467,468],{},".yml"," extension, a\nsubdirectory, or a symlink in ",[149,471,163],{}," is an error. Hidden files and names\nending in ",[149,474,475],{},"~"," are skipped, so editor swap files don't break loading.",[438,478,479,480,482],{},"An empty split file is an error. Write ",[149,481,273],{}," for an empty map, or delete the\nfile.",[438,484,485,486,488],{},"Paths inside a split file are relative to the project root, as in\n",[149,487,151],{},". Errors name the split file and the line.",[438,490,491,493],{},[149,492,173],{}," overlays the combined result, as before.",[438,495,496,497,500,501,504],{},"Commit split files. Remote environments load configuration from a commit, so\n",[149,498,499],{},"mm config validate"," warns (",[149,502,503],{},"MM_CONFIG_SOURCE_IGNORED",") when git ignores one.",[438,506,507],{},"Splitting changes the configuration fingerprint, so plans reviewed before the\nmove must be reviewed again. Projects that split nothing keep their existing\nfingerprint.",[145,509,510,511,182],{},"To give a key its own reviewers, list its file in ",[149,512,513],{},"CODEOWNERS",[184,515,518],{"className":516,"code":517,"language":189,"meta":190},[187],"\u002F.config\u002Fmm\u002Fenvironments.yaml  @acme\u002Fplatform\n",[149,519,517],{"__ignoreMap":190},[145,521,522,523,526,527,530,531,277],{},"Editors can validate a split file with its own schema. ",[149,524,525],{},"mm config schema KEY","\nprints it, and the docs publish one per key at ",[149,528,529],{},"\u002Fschema\u002Fmm\u002FKEY.schema.json",",\nfor example ",[166,532,534],{"href":533},"\u002Fschema\u002Fmm\u002Fstacks.schema.json",[149,535,533],{},[212,537,539],{"id":538},"top-level-fields","Top-level fields",[145,541,542,543,547],{},"New to the file? Start with ",[166,544,546],{"href":545},"..\u002Fconcepts\u002Fconfiguration-ownership","where configuration belongs","\nor a runnable example. The sections below are a field reference; YAML fragments\nshow the relevant settings and are not complete projects unless noted.",[549,550,551,567],"table",{},[552,553,554],"thead",{},[555,556,557,561,564],"tr",{},[558,559,560],"th",{},"Field",[558,562,563],{},"Required",[558,565,566],{},"Shape and default",[568,569,570,587,605,625,636,662,689,701,712,724,736,748,770,782,794,808,822,834,846,858,874,897,916],"tbody",{},[555,571,572,577,580],{},[573,574,575],"td",{},[149,576,159],{},[573,578,579],{},"yes",[573,581,582,583,586],{},"Integer ",[149,584,585],{},"1",". Missing, zero, and every other value are errors.",[555,588,589,593,595],{},[573,590,591],{},[149,592,448],{},[573,594,579],{},[573,596,597,600,601,604],{},[149,598,599],{},"{id, name, development-environment?}",". ",[149,602,603],{},"id"," is a UUID.",[555,606,607,611,614],{},[573,608,609],{},[149,610,269],{},[573,612,613],{},"no",[573,615,616,617,620,621,624],{},"Environment selected when neither ",[149,618,619],{},"--environment"," nor ",[149,622,623],{},"MM_ENVIRONMENT"," is set.",[555,626,627,631,633],{},[573,628,629],{},[149,630,209],{},[573,632,579],{},[573,634,635],{},"Default target name.",[555,637,638,643,645],{},[573,639,640],{},[149,641,642],{},"runtime",[573,644,613],{},[573,646,647,650,651,654,655,658,659,277],{},[149,648,649],{},"{driver?}","; driver is ",[149,652,653],{},"podman-compose",", ",[149,656,657],{},"docker-compose",", or ",[149,660,661],{},"docker-swarm",[555,663,664,668,670],{},[573,665,666],{},[149,667,237],{},[573,669,613],{},[573,671,672,675,676,654,679,681,682,600,685,688],{},[149,673,674],{},"{platforms, tag-strategy}","; defaults to ",[149,677,678],{},"linux\u002Famd64",[149,680,256],{},", and ",[149,683,684],{},"auto",[149,686,687],{},"immutable"," is also valid.",[555,690,691,696,698],{},[573,692,693],{},[149,694,695],{},"networks",[573,697,613],{},[573,699,700],{},"Map of named empty objects. Stacks and modules attach names from this catalog.",[555,702,703,707,709],{},[573,704,705],{},[149,706,384],{},[573,708,579],{},[573,710,711],{},"Map of Compose stack definitions.",[555,713,714,719,721],{},[573,715,716],{},[149,717,718],{},"modules",[573,720,613],{},[573,722,723],{},"Map of source modules and their services.",[555,725,726,731,733],{},[573,727,728],{},[149,729,730],{},"secrets",[573,732,613],{},[573,734,735],{},"Map of logical secret declarations; never put secret material in this file.",[555,737,738,743,745],{},[573,739,740],{},[149,741,742],{},"bindings",[573,744,613],{},[573,746,747],{},"Project-wide environment bindings.",[555,749,750,755,757],{},[573,751,752],{},[149,753,754],{},"environment-delivery",[573,756,613],{},[573,758,759,762,763,766,767,277],{},[149,760,761],{},"{default?, development-default?}"," using ",[149,764,765],{},"direct"," or ",[149,768,769],{},"env-file",[555,771,772,777,779],{},[573,773,774],{},[149,775,776],{},"environments",[573,778,579],{},[573,780,781],{},"Map of environment overlays; at least one is required.",[555,783,784,789,791],{},[573,785,786],{},[149,787,788],{},"ingress",[573,790,613],{},[573,792,793],{},"Project automatic-local and middleware policy.",[555,795,796,801,803],{},[573,797,798],{},[149,799,800],{},"development-mounts",[573,802,613],{},[573,804,805,277],{},[149,806,807],{},"{sensitive-patterns: [...]}",[555,809,810,815,817],{},[573,811,812],{},[149,813,814],{},"development-mail",[573,816,613],{},[573,818,819,277],{},[149,820,821],{},"{enabled?, bindings?}",[555,823,824,829,831],{},[573,825,826],{},[149,827,828],{},"jobs",[573,830,613],{},[573,832,833],{},"Map of named one-shot command declarations.",[555,835,836,841,843],{},[573,837,838],{},[149,839,840],{},"schedules",[573,842,613],{},[573,844,845],{},"Map of durable five-field cron triggers referring to jobs.",[555,847,848,853,855],{},[573,849,850],{},[149,851,852],{},"gates",[573,854,613],{},[573,856,857],{},"Map of declarative provider and ingress references.",[555,859,860,865,867],{},[573,861,862],{},[149,863,864],{},"users",[573,866,613],{},[573,868,869,870,277],{},"Who may reach each remote environment. See ",[166,871,873],{"href":872},"..\u002Fremote-access","remote access",[555,875,876,881,883],{},[573,877,878],{},[149,879,880],{},"agents",[573,882,613],{},[573,884,885,886,889,890,893,894,277],{},"What an AI agent may do, per environment or ",[149,887,888],{},"*",". Default ",[149,891,892],{},"view",". See ",[166,895,880],{"href":896},"..\u002Fmcp",[555,898,899,904,906],{},[573,900,901],{},[149,902,903],{},"targets",[573,905,613],{},[573,907,908,909,766,912,915],{},"Remote targets: ",[149,910,911],{},"{host, port?, host-key, daemon-fingerprint, members?}",[149,913,914],{},"{nodes, swarm, setup?}",". See the remote daemon guide.",[555,917,918,923,925],{},[573,919,920],{},[149,921,922],{},"registries",[573,924,613],{},[573,926,927,928,893,931,277],{},"Image registry logins by host: ",[149,929,930],{},"{username, password: {secret}}",[166,932,934],{"href":933},"..\u002Fhow-to\u002Fdeploy-production#pull-from-a-private-registry","prepare a deployment environment",[145,936,937,938,681,941,944],{},"Names used for projects, stacks, modules, services, networks, jobs, schedules,\nand gates contain only ASCII letters, digits, ",[149,939,940],{},"-",[149,942,943],{},"_",". More restrictive\nengine-specific checks also apply where relevant.",[212,946,948],{"id":947},"stacks-and-ingress","Stacks and ingress",[184,950,952],{"className":224,"code":951,"language":226,"meta":190,"style":190},"networks:\n  frontend: {}\n\nstacks:\n  app:\n    project-name: myapp-{environment}-{stack} # optional; {project-id} also works\n    files: [compose.yaml, compose.local.yaml]\n    networks: [frontend]\n    shared-volumes: [uploads] # Swarm: every node can mount these\n    ingress:\n      - domain: app\n        route: \u002F # default\n        service: web # optional when unambiguous\n        port: 8080 # optional\n        https: true # default\n        environments: [local, staging] # empty means all\n\ningress:\n  automatic-local: true\n  middlewares:\n    redirects:\n      file: .config\u002Ftraefik\u002Fredirects.yaml\n      environments: [local]\n",[149,953,954,960,970,976,983,991,1005,1025,1040,1059,1067,1081,1095,1109,1124,1137,1160,1165,1172,1183,1191,1199,1210],{"__ignoreMap":190},[230,955,956,958],{"class":232,"line":233},[230,957,695],{"class":236},[230,959,241],{"class":240},[230,961,962,965,967],{"class":232,"line":244},[230,963,964],{"class":236},"  frontend",[230,966,182],{"class":240},[230,968,969],{"class":240}," {}\n",[230,971,972],{"class":232,"line":364},[230,973,975],{"emptyLinePlaceholder":974},true,"\n",[230,977,979,981],{"class":232,"line":978},4,[230,980,384],{"class":236},[230,982,241],{"class":240},[230,984,986,989],{"class":232,"line":985},5,[230,987,988],{"class":236},"  app",[230,990,241],{"class":240},[230,992,994,997,999,1002],{"class":232,"line":993},6,[230,995,996],{"class":236},"    project-name",[230,998,182],{"class":240},[230,1000,1001],{"class":255}," myapp-{environment}-{stack}",[230,1003,1004],{"class":337}," # optional; {project-id} also works\n",[230,1006,1008,1011,1013,1015,1017,1020,1023],{"class":232,"line":1007},7,[230,1009,1010],{"class":236},"    files",[230,1012,182],{"class":240},[230,1014,252],{"class":240},[230,1016,428],{"class":255},[230,1018,1019],{"class":240},",",[230,1021,1022],{"class":255}," compose.local.yaml",[230,1024,259],{"class":240},[230,1026,1028,1031,1033,1035,1038],{"class":232,"line":1027},8,[230,1029,1030],{"class":236},"    networks",[230,1032,182],{"class":240},[230,1034,252],{"class":240},[230,1036,1037],{"class":255},"frontend",[230,1039,259],{"class":240},[230,1041,1043,1046,1048,1050,1053,1056],{"class":232,"line":1042},9,[230,1044,1045],{"class":236},"    shared-volumes",[230,1047,182],{"class":240},[230,1049,252],{"class":240},[230,1051,1052],{"class":255},"uploads",[230,1054,1055],{"class":240},"]",[230,1057,1058],{"class":337}," # Swarm: every node can mount these\n",[230,1060,1062,1065],{"class":232,"line":1061},10,[230,1063,1064],{"class":236},"    ingress",[230,1066,241],{"class":240},[230,1068,1070,1073,1076,1078],{"class":232,"line":1069},11,[230,1071,1072],{"class":240},"      -",[230,1074,1075],{"class":236}," domain",[230,1077,182],{"class":240},[230,1079,1080],{"class":255}," app\n",[230,1082,1084,1087,1089,1092],{"class":232,"line":1083},12,[230,1085,1086],{"class":236},"        route",[230,1088,182],{"class":240},[230,1090,1091],{"class":255}," \u002F",[230,1093,1094],{"class":337}," # default\n",[230,1096,1098,1101,1103,1106],{"class":232,"line":1097},13,[230,1099,1100],{"class":236},"        service",[230,1102,182],{"class":240},[230,1104,1105],{"class":255}," web",[230,1107,1108],{"class":337}," # optional when unambiguous\n",[230,1110,1112,1115,1117,1121],{"class":232,"line":1111},14,[230,1113,1114],{"class":236},"        port",[230,1116,182],{"class":240},[230,1118,1120],{"class":1119},"s1Wbj"," 8080",[230,1122,1123],{"class":337}," # optional\n",[230,1125,1127,1130,1132,1135],{"class":232,"line":1126},15,[230,1128,1129],{"class":236},"        https",[230,1131,182],{"class":240},[230,1133,1134],{"class":1119}," true",[230,1136,1094],{"class":337},[230,1138,1140,1143,1145,1147,1150,1152,1155,1157],{"class":232,"line":1139},16,[230,1141,1142],{"class":236},"        environments",[230,1144,182],{"class":240},[230,1146,252],{"class":240},[230,1148,1149],{"class":255},"local",[230,1151,1019],{"class":240},[230,1153,1154],{"class":255}," staging",[230,1156,1055],{"class":240},[230,1158,1159],{"class":337}," # empty means all\n",[230,1161,1163],{"class":232,"line":1162},17,[230,1164,975],{"emptyLinePlaceholder":974},[230,1166,1168,1170],{"class":232,"line":1167},18,[230,1169,788],{"class":236},[230,1171,241],{"class":240},[230,1173,1175,1178,1180],{"class":232,"line":1174},19,[230,1176,1177],{"class":236},"  automatic-local",[230,1179,182],{"class":240},[230,1181,1182],{"class":1119}," true\n",[230,1184,1186,1189],{"class":232,"line":1185},20,[230,1187,1188],{"class":236},"  middlewares",[230,1190,241],{"class":240},[230,1192,1194,1197],{"class":232,"line":1193},21,[230,1195,1196],{"class":236},"    redirects",[230,1198,241],{"class":240},[230,1200,1202,1205,1207],{"class":232,"line":1201},22,[230,1203,1204],{"class":236},"      file",[230,1206,182],{"class":240},[230,1208,1209],{"class":255}," .config\u002Ftraefik\u002Fredirects.yaml\n",[230,1211,1213,1216,1218,1220,1222],{"class":232,"line":1212},23,[230,1214,1215],{"class":236},"      environments",[230,1217,182],{"class":240},[230,1219,252],{"class":240},[230,1221,1149],{"class":255},[230,1223,259],{"class":240},[145,1225,1226,1228,1229,1232,1233,1236,1237,1239,1240,1243,1244,1247],{},[149,1227,788],{}," under a stack accepts either one route mapping or a list. Domain keys\nresolve through the selected environment's ",[149,1230,1231],{},"domains",". Route paths start with\n",[149,1234,1235],{},"\u002F",", contain no traversal or repeated slash, and have no trailing slash except\nfor ",[149,1238,1235],{},". Middleware files are bounded, project-relative regular files; the\ncurrently supported document shape is ",[149,1241,1242],{},"http.middlewares"," with\n",[149,1245,1246],{},"replacePathRegex"," definitions.",[145,1249,1250,1253,1254,1257,1258,658,1261,1264,1265,277],{},[149,1251,1252],{},"shared-volumes"," lists top-level Compose volume names from that stack. On a\nmulti-node Docker Swarm, mm stores them on its built-in shared storage so a\nservice can run on any node and see the same files. Do not set ",[149,1255,1256],{},"driver",",\n",[149,1259,1260],{},"driver_opts",[149,1262,1263],{},"external"," on them; mm sets those. Other runtimes and\nsingle-node Swarm treat them as ordinary volumes. See\n",[166,1266,48],{"href":1267},"..\u002Fhow-to\u002Fswarm-cluster",[212,1269,1271],{"id":1270},"modules-services-and-builds","Modules, services, and builds",[184,1273,1275],{"className":224,"code":1274,"language":226,"meta":190,"style":190},"modules:\n  api:\n    path: apps\u002Fapi\n    networks: [frontend]\n    env:\n      template: .env.example\n    build:\n      enabled: true # default\n      context: . # optional\n      dockerfile: Dockerfile # optional\n      image: ghcr.io\u002Facme\u002Fapi # required when enabled\n      default-variant: production\n      targets: { production: \"\", debug: debug }\n      args: { APP_MODE: production }\n      secrets: { npm_token: npm.token }\n      credential-only-secrets: [npm_token] # optional\n      depends-on: { base: MM_BASE_IMAGE }\n      extra-inputs: [package-lock.json]\n    services:\n      web:\n        stack: app\n        role: http\n        http-port: 8080\n        automatic-local-ingress: true\n        local-https: true\n        development-mail: true\n        networks: [frontend]\n        placement: edge # Swarm only: node, group, `managers`, or a list\n        env:\n          APP.DEBUG: false\n        secret-files:\n          database-password:\n            secret: database.password\n            uid: \"0\" # defaults shown\n            gid: \"0\"\n            mode: 292 # YAML integer for 0444\n",[149,1276,1277,1283,1290,1300,1312,1319,1329,1336,1347,1359,1371,1384,1394,1424,1442,1461,1477,1496,1510,1517,1524,1533,1543,1553,1563,1573,1583,1597,1611,1619,1630,1638,1646,1657,1671,1682],{"__ignoreMap":190},[230,1278,1279,1281],{"class":232,"line":233},[230,1280,718],{"class":236},[230,1282,241],{"class":240},[230,1284,1285,1288],{"class":232,"line":244},[230,1286,1287],{"class":236},"  api",[230,1289,241],{"class":240},[230,1291,1292,1295,1297],{"class":232,"line":364},[230,1293,1294],{"class":236},"    path",[230,1296,182],{"class":240},[230,1298,1299],{"class":255}," apps\u002Fapi\n",[230,1301,1302,1304,1306,1308,1310],{"class":232,"line":978},[230,1303,1030],{"class":236},[230,1305,182],{"class":240},[230,1307,252],{"class":240},[230,1309,1037],{"class":255},[230,1311,259],{"class":240},[230,1313,1314,1317],{"class":232,"line":985},[230,1315,1316],{"class":236},"    env",[230,1318,241],{"class":240},[230,1320,1321,1324,1326],{"class":232,"line":993},[230,1322,1323],{"class":236},"      template",[230,1325,182],{"class":240},[230,1327,1328],{"class":255}," .env.example\n",[230,1330,1331,1334],{"class":232,"line":1007},[230,1332,1333],{"class":236},"    build",[230,1335,241],{"class":240},[230,1337,1338,1341,1343,1345],{"class":232,"line":1027},[230,1339,1340],{"class":236},"      enabled",[230,1342,182],{"class":240},[230,1344,1134],{"class":1119},[230,1346,1094],{"class":337},[230,1348,1349,1352,1354,1357],{"class":232,"line":1042},[230,1350,1351],{"class":236},"      context",[230,1353,182],{"class":240},[230,1355,1356],{"class":1119}," .",[230,1358,1123],{"class":337},[230,1360,1361,1364,1366,1369],{"class":232,"line":1061},[230,1362,1363],{"class":236},"      dockerfile",[230,1365,182],{"class":240},[230,1367,1368],{"class":255}," Dockerfile",[230,1370,1123],{"class":337},[230,1372,1373,1376,1378,1381],{"class":232,"line":1069},[230,1374,1375],{"class":236},"      image",[230,1377,182],{"class":240},[230,1379,1380],{"class":255}," ghcr.io\u002Facme\u002Fapi",[230,1382,1383],{"class":337}," # required when enabled\n",[230,1385,1386,1389,1391],{"class":232,"line":1083},[230,1387,1388],{"class":236},"      default-variant",[230,1390,182],{"class":240},[230,1392,1393],{"class":255}," production\n",[230,1395,1396,1399,1401,1404,1407,1409,1412,1414,1417,1419,1421],{"class":232,"line":1097},[230,1397,1398],{"class":236},"      targets",[230,1400,182],{"class":240},[230,1402,1403],{"class":240}," {",[230,1405,1406],{"class":236}," production",[230,1408,182],{"class":240},[230,1410,1411],{"class":255}," \"\"",[230,1413,1019],{"class":240},[230,1415,1416],{"class":236}," debug",[230,1418,182],{"class":240},[230,1420,1416],{"class":255},[230,1422,1423],{"class":240}," }\n",[230,1425,1426,1429,1431,1433,1436,1438,1440],{"class":232,"line":1111},[230,1427,1428],{"class":236},"      args",[230,1430,182],{"class":240},[230,1432,1403],{"class":240},[230,1434,1435],{"class":236}," APP_MODE",[230,1437,182],{"class":240},[230,1439,1406],{"class":255},[230,1441,1423],{"class":240},[230,1443,1444,1447,1449,1451,1454,1456,1459],{"class":232,"line":1126},[230,1445,1446],{"class":236},"      secrets",[230,1448,182],{"class":240},[230,1450,1403],{"class":240},[230,1452,1453],{"class":236}," npm_token",[230,1455,182],{"class":240},[230,1457,1458],{"class":255}," npm.token",[230,1460,1423],{"class":240},[230,1462,1463,1466,1468,1470,1473,1475],{"class":232,"line":1139},[230,1464,1465],{"class":236},"      credential-only-secrets",[230,1467,182],{"class":240},[230,1469,252],{"class":240},[230,1471,1472],{"class":255},"npm_token",[230,1474,1055],{"class":240},[230,1476,1123],{"class":337},[230,1478,1479,1482,1484,1486,1489,1491,1494],{"class":232,"line":1162},[230,1480,1481],{"class":236},"      depends-on",[230,1483,182],{"class":240},[230,1485,1403],{"class":240},[230,1487,1488],{"class":236}," base",[230,1490,182],{"class":240},[230,1492,1493],{"class":255}," MM_BASE_IMAGE",[230,1495,1423],{"class":240},[230,1497,1498,1501,1503,1505,1508],{"class":232,"line":1167},[230,1499,1500],{"class":236},"      extra-inputs",[230,1502,182],{"class":240},[230,1504,252],{"class":240},[230,1506,1507],{"class":255},"package-lock.json",[230,1509,259],{"class":240},[230,1511,1512,1515],{"class":232,"line":1174},[230,1513,1514],{"class":236},"    services",[230,1516,241],{"class":240},[230,1518,1519,1522],{"class":232,"line":1185},[230,1520,1521],{"class":236},"      web",[230,1523,241],{"class":240},[230,1525,1526,1529,1531],{"class":232,"line":1193},[230,1527,1528],{"class":236},"        stack",[230,1530,182],{"class":240},[230,1532,1080],{"class":255},[230,1534,1535,1538,1540],{"class":232,"line":1201},[230,1536,1537],{"class":236},"        role",[230,1539,182],{"class":240},[230,1541,1542],{"class":255}," http\n",[230,1544,1545,1548,1550],{"class":232,"line":1212},[230,1546,1547],{"class":236},"        http-port",[230,1549,182],{"class":240},[230,1551,1552],{"class":1119}," 8080\n",[230,1554,1556,1559,1561],{"class":232,"line":1555},24,[230,1557,1558],{"class":236},"        automatic-local-ingress",[230,1560,182],{"class":240},[230,1562,1182],{"class":1119},[230,1564,1566,1569,1571],{"class":232,"line":1565},25,[230,1567,1568],{"class":236},"        local-https",[230,1570,182],{"class":240},[230,1572,1182],{"class":1119},[230,1574,1576,1579,1581],{"class":232,"line":1575},26,[230,1577,1578],{"class":236},"        development-mail",[230,1580,182],{"class":240},[230,1582,1182],{"class":1119},[230,1584,1586,1589,1591,1593,1595],{"class":232,"line":1585},27,[230,1587,1588],{"class":236},"        networks",[230,1590,182],{"class":240},[230,1592,252],{"class":240},[230,1594,1037],{"class":255},[230,1596,259],{"class":240},[230,1598,1600,1603,1605,1608],{"class":232,"line":1599},28,[230,1601,1602],{"class":236},"        placement",[230,1604,182],{"class":240},[230,1606,1607],{"class":255}," edge",[230,1609,1610],{"class":337}," # Swarm only: node, group, `managers`, or a list\n",[230,1612,1614,1617],{"class":232,"line":1613},29,[230,1615,1616],{"class":236},"        env",[230,1618,241],{"class":240},[230,1620,1622,1625,1627],{"class":232,"line":1621},30,[230,1623,1624],{"class":236},"          APP.DEBUG",[230,1626,182],{"class":240},[230,1628,1629],{"class":1119}," false\n",[230,1631,1633,1636],{"class":232,"line":1632},31,[230,1634,1635],{"class":236},"        secret-files",[230,1637,241],{"class":240},[230,1639,1641,1644],{"class":232,"line":1640},32,[230,1642,1643],{"class":236},"          database-password",[230,1645,241],{"class":240},[230,1647,1649,1652,1654],{"class":232,"line":1648},33,[230,1650,1651],{"class":236},"            secret",[230,1653,182],{"class":240},[230,1655,1656],{"class":255}," database.password\n",[230,1658,1660,1663,1665,1668],{"class":232,"line":1659},34,[230,1661,1662],{"class":236},"            uid",[230,1664,182],{"class":240},[230,1666,1667],{"class":255}," \"0\"",[230,1669,1670],{"class":337}," # defaults shown\n",[230,1672,1674,1677,1679],{"class":232,"line":1673},35,[230,1675,1676],{"class":236},"            gid",[230,1678,182],{"class":240},[230,1680,1681],{"class":255}," \"0\"\n",[230,1683,1685,1688,1690,1693],{"class":232,"line":1684},36,[230,1686,1687],{"class":236},"            mode",[230,1689,182],{"class":240},[230,1691,1692],{"class":1119}," 292",[230,1694,1695],{"class":337}," # YAML integer for 0444\n",[145,1697,1698,1699,654,1702,654,1705,654,1708,654,1711,1714,1715,1718],{},"Service roles are ",[149,1700,1701],{},"http",[149,1703,1704],{},"database",[149,1706,1707],{},"queue",[149,1709,1710],{},"worker",[149,1712,1713],{},"scheduler",", and\n",[149,1716,1717],{},"job",". Infrastructure and background roles do not receive automatic ingress.",[145,1720,1721,1724,1725,1728,1729,654,1732,1735],{},[149,1722,1723],{},"placement"," chooses where a service runs on a multi-node Docker Swarm. Use a\nnode hostname (",[149,1726,1727],{},"mgr-1","), a placement group created with\n",[149,1730,1731],{},"mm target swarm group set",[149,1733,1734],{},"managers",", or a list whose entries must all hold.\nCompose runtimes and single-node Swarm ignore it, so the same file works on a\nlaptop. On a cluster, a service that keeps data in a non-shared named volume\nmust be placed on exactly one node.",[145,1737,1738,1739,1741],{},"Set ",[149,1740,776],{}," on a service to run it only in the named environments. Omitted\nor empty lists mean all environments; every name must be configured:",[184,1743,1745],{"className":224,"code":1744,"language":226,"meta":190,"style":190},"modules:\n  api:\n    services:\n      scheduler:\n        stack: app\n        role: scheduler\n        environments: [integration, uat, production]\n",[149,1746,1747,1753,1759,1765,1772,1780,1789],{"__ignoreMap":190},[230,1748,1749,1751],{"class":232,"line":233},[230,1750,718],{"class":236},[230,1752,241],{"class":240},[230,1754,1755,1757],{"class":232,"line":244},[230,1756,1287],{"class":236},[230,1758,241],{"class":240},[230,1760,1761,1763],{"class":232,"line":364},[230,1762,1514],{"class":236},[230,1764,241],{"class":240},[230,1766,1767,1770],{"class":232,"line":978},[230,1768,1769],{"class":236},"      scheduler",[230,1771,241],{"class":240},[230,1773,1774,1776,1778],{"class":232,"line":985},[230,1775,1528],{"class":236},[230,1777,182],{"class":240},[230,1779,1080],{"class":255},[230,1781,1782,1784,1786],{"class":232,"line":993},[230,1783,1537],{"class":236},[230,1785,182],{"class":240},[230,1787,1788],{"class":255}," scheduler\n",[230,1790,1791,1793,1795,1797,1800,1802,1805,1807,1809],{"class":232,"line":1007},[230,1792,1142],{"class":236},[230,1794,182],{"class":240},[230,1796,252],{"class":240},[230,1798,1799],{"class":255},"integration",[230,1801,1019],{"class":240},[230,1803,1804],{"class":255}," uat",[230,1806,1019],{"class":240},[230,1808,1406],{"class":255},[230,1810,259],{"class":240},[145,1812,1813],{},"For other environments, mm omits that service from the generated Compose files,\nenvironment\u002Fsecret delivery, managed networks and automatic ingress. Build and\nimage declarations remain module-level; a deployment needs published images only\nfor modules with active services. Deployment and stack-compilation plans list\nexcluded services. Applying a deployment removes previously deployed excluded\nservices; a stack with no remaining services is removed as a whole.",[145,1815,1816,1817,654,1820,1257,1823,658,1826,1829,1830,654,1833,654,1836,1839,1840,1842,1843,1846],{},"Active services cannot depend on excluded ones through ",[149,1818,1819],{},"depends_on",[149,1821,1822],{},"links",[149,1824,1825],{},"volumes_from",[149,1827,1828],{},"service:"," namespace sharing (",[149,1831,1832],{},"network_mode",[149,1834,1835],{},"ipc",[149,1837,1838],{},"pid",").\nOptional ",[149,1841,1819],{}," entries with ",[149,1844,1845],{},"required: false"," are removed. Dependency\nchecks apply to each source Compose file; remove conflicting references from\nearlier files as well as later overrides. Explicit ingress routes must allowlist\ncompatible environments. Jobs and schedules targeting an excluded service are\ninactive in that environment.",[145,1848,1849,1850,1853,1854,277],{},"Build ",[149,1851,1852],{},"args"," are public values; names that look secret are rejected and belong\nunder ",[149,1855,1856],{},"build.secrets",[145,1858,1859,1862,1863,1865,1866,277],{},[149,1860,1861],{},"credential-only-secrets"," lists keys of ",[149,1864,1856],{}," that only authenticate\nfetching inputs, such as a package registry token. They are still mounted, but\nthey are left out of the build fingerprint, so they do not prevent reusing an\nunchanged image or promoting a build to another environment. Any other build\nsecret disables both. See ",[166,1867,1869],{"href":1868},"..\u002Fsecret-delivery#build-secrets","build secrets",[212,1871,54],{"id":1872},"jobs-and-schedules",[184,1874,1876],{"className":224,"code":1875,"language":226,"meta":190,"style":190},"jobs:\n  migrate:\n    module: api\n    service: web\n    command: [\"php\", \"artisan\", \"migrate\", \"--force\"]\n    environment: production # optional fixed environment\n    timeout: 10m\n    retry: { attempts: 3, backoff: 5s, max-backoff: 5m }\n    output-limit-bytes: 65536\n    history-limit: 100\n\nschedules:\n  framework:\n    job: migrate\n    cron: \"0 2 * * *\"\n    timezone: America\u002FNew_York\n    enabled: true\n    starts-at: 2026-01-01T00:00:00Z\n    ends-at: 2027-01-01T00:00:00Z\n    jitter: 30s\n    concurrency: forbid # allow, forbid, replace\n    misfire: run-once # skip or {bounded-catch-up: {maximum: 10}}\n    retry: { attempts: 2, backoff: 10s, max-backoff: 1m } # optional override\n    timeout: 5m # optional override\n",[149,1877,1878,1884,1891,1901,1911,1940,1952,1962,2001,2011,2021,2025,2031,2038,2048,2058,2068,2077,2088,2098,2108,2121,2134,2173],{"__ignoreMap":190},[230,1879,1880,1882],{"class":232,"line":233},[230,1881,828],{"class":236},[230,1883,241],{"class":240},[230,1885,1886,1889],{"class":232,"line":244},[230,1887,1888],{"class":236},"  migrate",[230,1890,241],{"class":240},[230,1892,1893,1896,1898],{"class":232,"line":364},[230,1894,1895],{"class":236},"    module",[230,1897,182],{"class":240},[230,1899,1900],{"class":255}," api\n",[230,1902,1903,1906,1908],{"class":232,"line":978},[230,1904,1905],{"class":236},"    service",[230,1907,182],{"class":240},[230,1909,1910],{"class":255}," web\n",[230,1912,1913,1916,1918,1920,1923,1925,1928,1930,1933,1935,1938],{"class":232,"line":985},[230,1914,1915],{"class":236},"    command",[230,1917,182],{"class":240},[230,1919,252],{"class":240},[230,1921,1922],{"class":255},"\"php\"",[230,1924,1019],{"class":240},[230,1926,1927],{"class":255}," \"artisan\"",[230,1929,1019],{"class":240},[230,1931,1932],{"class":255}," \"migrate\"",[230,1934,1019],{"class":240},[230,1936,1937],{"class":255}," \"--force\"",[230,1939,259],{"class":240},[230,1941,1942,1945,1947,1949],{"class":232,"line":993},[230,1943,1944],{"class":236},"    environment",[230,1946,182],{"class":240},[230,1948,1406],{"class":255},[230,1950,1951],{"class":337}," # optional fixed environment\n",[230,1953,1954,1957,1959],{"class":232,"line":1007},[230,1955,1956],{"class":236},"    timeout",[230,1958,182],{"class":240},[230,1960,1961],{"class":255}," 10m\n",[230,1963,1964,1967,1969,1971,1974,1976,1979,1981,1984,1986,1989,1991,1994,1996,1999],{"class":232,"line":1027},[230,1965,1966],{"class":236},"    retry",[230,1968,182],{"class":240},[230,1970,1403],{"class":240},[230,1972,1973],{"class":236}," attempts",[230,1975,182],{"class":240},[230,1977,1978],{"class":1119}," 3",[230,1980,1019],{"class":240},[230,1982,1983],{"class":236}," backoff",[230,1985,182],{"class":240},[230,1987,1988],{"class":255}," 5s",[230,1990,1019],{"class":240},[230,1992,1993],{"class":236}," max-backoff",[230,1995,182],{"class":240},[230,1997,1998],{"class":255}," 5m",[230,2000,1423],{"class":240},[230,2002,2003,2006,2008],{"class":232,"line":1042},[230,2004,2005],{"class":236},"    output-limit-bytes",[230,2007,182],{"class":240},[230,2009,2010],{"class":1119}," 65536\n",[230,2012,2013,2016,2018],{"class":232,"line":1061},[230,2014,2015],{"class":236},"    history-limit",[230,2017,182],{"class":240},[230,2019,2020],{"class":1119}," 100\n",[230,2022,2023],{"class":232,"line":1069},[230,2024,975],{"emptyLinePlaceholder":974},[230,2026,2027,2029],{"class":232,"line":1083},[230,2028,840],{"class":236},[230,2030,241],{"class":240},[230,2032,2033,2036],{"class":232,"line":1097},[230,2034,2035],{"class":236},"  framework",[230,2037,241],{"class":240},[230,2039,2040,2043,2045],{"class":232,"line":1111},[230,2041,2042],{"class":236},"    job",[230,2044,182],{"class":240},[230,2046,2047],{"class":255}," migrate\n",[230,2049,2050,2053,2055],{"class":232,"line":1126},[230,2051,2052],{"class":236},"    cron",[230,2054,182],{"class":240},[230,2056,2057],{"class":255}," \"0 2 * * *\"\n",[230,2059,2060,2063,2065],{"class":232,"line":1139},[230,2061,2062],{"class":236},"    timezone",[230,2064,182],{"class":240},[230,2066,2067],{"class":255}," America\u002FNew_York\n",[230,2069,2070,2073,2075],{"class":232,"line":1162},[230,2071,2072],{"class":236},"    enabled",[230,2074,182],{"class":240},[230,2076,1182],{"class":1119},[230,2078,2079,2082,2084],{"class":232,"line":1167},[230,2080,2081],{"class":236},"    starts-at",[230,2083,182],{"class":240},[230,2085,2087],{"class":2086},"sN9xe"," 2026-01-01T00:00:00Z\n",[230,2089,2090,2093,2095],{"class":232,"line":1174},[230,2091,2092],{"class":236},"    ends-at",[230,2094,182],{"class":240},[230,2096,2097],{"class":2086}," 2027-01-01T00:00:00Z\n",[230,2099,2100,2103,2105],{"class":232,"line":1185},[230,2101,2102],{"class":236},"    jitter",[230,2104,182],{"class":240},[230,2106,2107],{"class":255}," 30s\n",[230,2109,2110,2113,2115,2118],{"class":232,"line":1193},[230,2111,2112],{"class":236},"    concurrency",[230,2114,182],{"class":240},[230,2116,2117],{"class":255}," forbid",[230,2119,2120],{"class":337}," # allow, forbid, replace\n",[230,2122,2123,2126,2128,2131],{"class":232,"line":1201},[230,2124,2125],{"class":236},"    misfire",[230,2127,182],{"class":240},[230,2129,2130],{"class":255}," run-once",[230,2132,2133],{"class":337}," # skip or {bounded-catch-up: {maximum: 10}}\n",[230,2135,2136,2138,2140,2142,2144,2146,2149,2151,2153,2155,2158,2160,2162,2164,2167,2170],{"class":232,"line":1212},[230,2137,1966],{"class":236},[230,2139,182],{"class":240},[230,2141,1403],{"class":240},[230,2143,1973],{"class":236},[230,2145,182],{"class":240},[230,2147,2148],{"class":1119}," 2",[230,2150,1019],{"class":240},[230,2152,1983],{"class":236},[230,2154,182],{"class":240},[230,2156,2157],{"class":255}," 10s",[230,2159,1019],{"class":240},[230,2161,1993],{"class":236},[230,2163,182],{"class":240},[230,2165,2166],{"class":255}," 1m",[230,2168,2169],{"class":240}," }",[230,2171,2172],{"class":337}," # optional override\n",[230,2174,2175,2177,2179,2181],{"class":232,"line":1555},[230,2176,1956],{"class":236},[230,2178,182],{"class":240},[230,2180,1998],{"class":255},[230,2182,2172],{"class":337},[145,2184,2185,2186,654,2189,654,2192,654,2195,658,2198,2201,2202,2206],{},"Durations use one compact suffix: ",[149,2187,2188],{},"ms",[149,2190,2191],{},"s",[149,2193,2194],{},"m",[149,2196,2197],{},"h",[149,2199,2200],{},"d",". Commands are\nargument vectors and never shell strings. A job reuses the named service's\nimage, environment, networks, mounts, and secret delivery contract. See\n",[166,2203,2205],{"href":2204},"..\u002Fjobs-and-schedules","Jobs and durable schedules"," for timing, recovery,\nand operational semantics.",[145,2208,2209,2210,182],{},"A module can also contain ",[149,2211,2212],{},"development-mount",[184,2214,2216],{"className":224,"code":2215,"language":226,"meta":190,"style":190},"development-mount:\n  source: .\n  target: \u002Fworkspace\n  mode: read-write # or read-only\n  services: [web]\n  preset: node # laravel, node, dotnet, or rust\n  preserve: [{ path: \u002Fworkspace\u002Fnode_modules }]\n  excludes: [dist]\n  protected: [.env]\n  safe-exceptions: []\n",[149,2217,2218,2224,2234,2244,2257,2271,2284,2305,2319,2333],{"__ignoreMap":190},[230,2219,2220,2222],{"class":232,"line":233},[230,2221,2212],{"class":236},[230,2223,241],{"class":240},[230,2225,2226,2229,2231],{"class":232,"line":244},[230,2227,2228],{"class":236},"  source",[230,2230,182],{"class":240},[230,2232,2233],{"class":1119}," .\n",[230,2235,2236,2239,2241],{"class":232,"line":364},[230,2237,2238],{"class":236},"  target",[230,2240,182],{"class":240},[230,2242,2243],{"class":255}," \u002Fworkspace\n",[230,2245,2246,2249,2251,2254],{"class":232,"line":978},[230,2247,2248],{"class":236},"  mode",[230,2250,182],{"class":240},[230,2252,2253],{"class":255}," read-write",[230,2255,2256],{"class":337}," # or read-only\n",[230,2258,2259,2262,2264,2266,2269],{"class":232,"line":985},[230,2260,2261],{"class":236},"  services",[230,2263,182],{"class":240},[230,2265,252],{"class":240},[230,2267,2268],{"class":255},"web",[230,2270,259],{"class":240},[230,2272,2273,2276,2278,2281],{"class":232,"line":993},[230,2274,2275],{"class":236},"  preset",[230,2277,182],{"class":240},[230,2279,2280],{"class":255}," node",[230,2282,2283],{"class":337}," # laravel, node, dotnet, or rust\n",[230,2285,2286,2289,2291,2294,2297,2299,2302],{"class":232,"line":1007},[230,2287,2288],{"class":236},"  preserve",[230,2290,182],{"class":240},[230,2292,2293],{"class":240}," [{",[230,2295,2296],{"class":236}," path",[230,2298,182],{"class":240},[230,2300,2301],{"class":255}," \u002Fworkspace\u002Fnode_modules",[230,2303,2304],{"class":240}," }]\n",[230,2306,2307,2310,2312,2314,2317],{"class":232,"line":1027},[230,2308,2309],{"class":236},"  excludes",[230,2311,182],{"class":240},[230,2313,252],{"class":240},[230,2315,2316],{"class":255},"dist",[230,2318,259],{"class":240},[230,2320,2321,2324,2326,2328,2331],{"class":232,"line":1042},[230,2322,2323],{"class":236},"  protected",[230,2325,182],{"class":240},[230,2327,252],{"class":240},[230,2329,2330],{"class":255},".env",[230,2332,259],{"class":240},[230,2334,2335,2338,2340],{"class":232,"line":1061},[230,2336,2337],{"class":236},"  safe-exceptions",[230,2339,182],{"class":240},[230,2341,2342],{"class":240}," []\n",[212,2344,2346],{"id":2345},"bindings-environments-and-secrets","Bindings, environments, and secrets",[145,2348,2349,2350,2353],{},"Binding keys use dot-separated uppercase names such as ",[149,2351,2352],{},"DB.HOST",". A binding is\nexactly one of these untagged shapes:",[184,2355,2357],{"className":224,"code":2356,"language":226,"meta":190,"style":190},"bindings:\n  APP.DEBUG: { value: false }\n  DB.PASSWORD: { secret: database.password }\n  APP.URL: { cast: url, value-ref: domains.app }\n\nenvironments:\n  local:\n    domains: { app: app.example.test }\n    bindings:\n      APP.DEBUG: { value: true }\n    runtime: { driver: podman-compose }\n    target: local\n    build-variant: debug\n    environment-delivery: env-file\n    automatic-local-ingress: true\n",[149,2358,2359,2365,2384,2403,2432,2436,2442,2449,2468,2475,2492,2511,2521,2531,2541],{"__ignoreMap":190},[230,2360,2361,2363],{"class":232,"line":233},[230,2362,742],{"class":236},[230,2364,241],{"class":240},[230,2366,2367,2370,2372,2374,2377,2379,2382],{"class":232,"line":244},[230,2368,2369],{"class":236},"  APP.DEBUG",[230,2371,182],{"class":240},[230,2373,1403],{"class":240},[230,2375,2376],{"class":236}," value",[230,2378,182],{"class":240},[230,2380,2381],{"class":1119}," false",[230,2383,1423],{"class":240},[230,2385,2386,2389,2391,2393,2396,2398,2401],{"class":232,"line":364},[230,2387,2388],{"class":236},"  DB.PASSWORD",[230,2390,182],{"class":240},[230,2392,1403],{"class":240},[230,2394,2395],{"class":236}," secret",[230,2397,182],{"class":240},[230,2399,2400],{"class":255}," database.password",[230,2402,1423],{"class":240},[230,2404,2405,2408,2410,2412,2415,2417,2420,2422,2425,2427,2430],{"class":232,"line":978},[230,2406,2407],{"class":236},"  APP.URL",[230,2409,182],{"class":240},[230,2411,1403],{"class":240},[230,2413,2414],{"class":236}," cast",[230,2416,182],{"class":240},[230,2418,2419],{"class":255}," url",[230,2421,1019],{"class":240},[230,2423,2424],{"class":236}," value-ref",[230,2426,182],{"class":240},[230,2428,2429],{"class":255}," domains.app",[230,2431,1423],{"class":240},[230,2433,2434],{"class":232,"line":985},[230,2435,975],{"emptyLinePlaceholder":974},[230,2437,2438,2440],{"class":232,"line":993},[230,2439,776],{"class":236},[230,2441,241],{"class":240},[230,2443,2444,2447],{"class":232,"line":1007},[230,2445,2446],{"class":236},"  local",[230,2448,241],{"class":240},[230,2450,2451,2454,2456,2458,2461,2463,2466],{"class":232,"line":1027},[230,2452,2453],{"class":236},"    domains",[230,2455,182],{"class":240},[230,2457,1403],{"class":240},[230,2459,2460],{"class":236}," app",[230,2462,182],{"class":240},[230,2464,2465],{"class":255}," app.example.test",[230,2467,1423],{"class":240},[230,2469,2470,2473],{"class":232,"line":1042},[230,2471,2472],{"class":236},"    bindings",[230,2474,241],{"class":240},[230,2476,2477,2480,2482,2484,2486,2488,2490],{"class":232,"line":1061},[230,2478,2479],{"class":236},"      APP.DEBUG",[230,2481,182],{"class":240},[230,2483,1403],{"class":240},[230,2485,2376],{"class":236},[230,2487,182],{"class":240},[230,2489,1134],{"class":1119},[230,2491,1423],{"class":240},[230,2493,2494,2497,2499,2501,2504,2506,2509],{"class":232,"line":1069},[230,2495,2496],{"class":236},"    runtime",[230,2498,182],{"class":240},[230,2500,1403],{"class":240},[230,2502,2503],{"class":236}," driver",[230,2505,182],{"class":240},[230,2507,2508],{"class":255}," podman-compose",[230,2510,1423],{"class":240},[230,2512,2513,2516,2518],{"class":232,"line":1083},[230,2514,2515],{"class":236},"    target",[230,2517,182],{"class":240},[230,2519,2520],{"class":255}," local\n",[230,2522,2523,2526,2528],{"class":232,"line":1097},[230,2524,2525],{"class":236},"    build-variant",[230,2527,182],{"class":240},[230,2529,2530],{"class":255}," debug\n",[230,2532,2533,2536,2538],{"class":232,"line":1111},[230,2534,2535],{"class":236},"    environment-delivery",[230,2537,182],{"class":240},[230,2539,2540],{"class":255}," env-file\n",[230,2542,2543,2546,2548],{"class":232,"line":1126},[230,2544,2545],{"class":236},"    automatic-local-ingress",[230,2547,182],{"class":240},[230,2549,1182],{"class":1119},[145,2551,2552,2553,2555,2556,2558,2559,2561,2562,2564],{},"Environment bindings override project bindings. ",[149,2554,765],{}," passes\noperation-scoped interpolation values to the runtime; ",[149,2557,769],{}," uses a private,\noperation-scoped file. With a declared development environment, the built-in\ndefault is ",[149,2560,769],{}," for that environment and ",[149,2563,765],{}," elsewhere. Explicit\nenvironment, development, and general policy values override those defaults.",[184,2566,2568],{"className":224,"code":2567,"language":226,"meta":190,"style":190},"providers:\n  staging-secrets:\n    driver: openbao\n    scope: project\n    mode: external\n    address: https:\u002F\u002Fbao.example.test:8200\n    storage-mount: mm-kv\n    automation-auth-mount: mm-approle\n    trust-bundle: company-ca.pem\n    expected-trust-sha256: sha256:HEX_DIGEST\n\nsecrets:\n  database.password:\n    storage:\n      provider: staging-secrets # age, env, or a declared provider instance\n      location: projects\u002Fexample\u002Fdb\n    input: { prompt: Database password }\n    rotation:\n      strategy: manual # manual, replace-and-redeploy, coordinated\n      interval-days: 90\n\n  app.key:\n    storage: { provider: age, location: app.key }\n    generate: { preset: bytes, length: 32, encoding: base64-url }\n",[149,2569,2570,2577,2584,2594,2604,2614,2624,2634,2644,2654,2664,2668,2674,2681,2688,2701,2711,2730,2737,2750,2760,2764,2771,2799],{"__ignoreMap":190},[230,2571,2572,2575],{"class":232,"line":233},[230,2573,2574],{"class":236},"providers",[230,2576,241],{"class":240},[230,2578,2579,2582],{"class":232,"line":244},[230,2580,2581],{"class":236},"  staging-secrets",[230,2583,241],{"class":240},[230,2585,2586,2589,2591],{"class":232,"line":364},[230,2587,2588],{"class":236},"    driver",[230,2590,182],{"class":240},[230,2592,2593],{"class":255}," openbao\n",[230,2595,2596,2599,2601],{"class":232,"line":978},[230,2597,2598],{"class":236},"    scope",[230,2600,182],{"class":240},[230,2602,2603],{"class":255}," project\n",[230,2605,2606,2609,2611],{"class":232,"line":985},[230,2607,2608],{"class":236},"    mode",[230,2610,182],{"class":240},[230,2612,2613],{"class":255}," external\n",[230,2615,2616,2619,2621],{"class":232,"line":993},[230,2617,2618],{"class":236},"    address",[230,2620,182],{"class":240},[230,2622,2623],{"class":255}," https:\u002F\u002Fbao.example.test:8200\n",[230,2625,2626,2629,2631],{"class":232,"line":1007},[230,2627,2628],{"class":236},"    storage-mount",[230,2630,182],{"class":240},[230,2632,2633],{"class":255}," mm-kv\n",[230,2635,2636,2639,2641],{"class":232,"line":1027},[230,2637,2638],{"class":236},"    automation-auth-mount",[230,2640,182],{"class":240},[230,2642,2643],{"class":255}," mm-approle\n",[230,2645,2646,2649,2651],{"class":232,"line":1042},[230,2647,2648],{"class":236},"    trust-bundle",[230,2650,182],{"class":240},[230,2652,2653],{"class":255}," company-ca.pem\n",[230,2655,2656,2659,2661],{"class":232,"line":1061},[230,2657,2658],{"class":236},"    expected-trust-sha256",[230,2660,182],{"class":240},[230,2662,2663],{"class":255}," sha256:HEX_DIGEST\n",[230,2665,2666],{"class":232,"line":1069},[230,2667,975],{"emptyLinePlaceholder":974},[230,2669,2670,2672],{"class":232,"line":1083},[230,2671,730],{"class":236},[230,2673,241],{"class":240},[230,2675,2676,2679],{"class":232,"line":1097},[230,2677,2678],{"class":236},"  database.password",[230,2680,241],{"class":240},[230,2682,2683,2686],{"class":232,"line":1111},[230,2684,2685],{"class":236},"    storage",[230,2687,241],{"class":240},[230,2689,2690,2693,2695,2698],{"class":232,"line":1126},[230,2691,2692],{"class":236},"      provider",[230,2694,182],{"class":240},[230,2696,2697],{"class":255}," staging-secrets",[230,2699,2700],{"class":337}," # age, env, or a declared provider instance\n",[230,2702,2703,2706,2708],{"class":232,"line":1139},[230,2704,2705],{"class":236},"      location",[230,2707,182],{"class":240},[230,2709,2710],{"class":255}," projects\u002Fexample\u002Fdb\n",[230,2712,2713,2716,2718,2720,2723,2725,2728],{"class":232,"line":1162},[230,2714,2715],{"class":236},"    input",[230,2717,182],{"class":240},[230,2719,1403],{"class":240},[230,2721,2722],{"class":236}," prompt",[230,2724,182],{"class":240},[230,2726,2727],{"class":255}," Database password",[230,2729,1423],{"class":240},[230,2731,2732,2735],{"class":232,"line":1167},[230,2733,2734],{"class":236},"    rotation",[230,2736,241],{"class":240},[230,2738,2739,2742,2744,2747],{"class":232,"line":1174},[230,2740,2741],{"class":236},"      strategy",[230,2743,182],{"class":240},[230,2745,2746],{"class":255}," manual",[230,2748,2749],{"class":337}," # manual, replace-and-redeploy, coordinated\n",[230,2751,2752,2755,2757],{"class":232,"line":1185},[230,2753,2754],{"class":236},"      interval-days",[230,2756,182],{"class":240},[230,2758,2759],{"class":1119}," 90\n",[230,2761,2762],{"class":232,"line":1193},[230,2763,975],{"emptyLinePlaceholder":974},[230,2765,2766,2769],{"class":232,"line":1201},[230,2767,2768],{"class":236},"  app.key",[230,2770,241],{"class":240},[230,2772,2773,2775,2777,2779,2782,2784,2787,2789,2792,2794,2797],{"class":232,"line":1212},[230,2774,2685],{"class":236},[230,2776,182],{"class":240},[230,2778,1403],{"class":240},[230,2780,2781],{"class":236}," provider",[230,2783,182],{"class":240},[230,2785,2786],{"class":255}," age",[230,2788,1019],{"class":240},[230,2790,2791],{"class":236}," location",[230,2793,182],{"class":240},[230,2795,2796],{"class":255}," app.key",[230,2798,1423],{"class":240},[230,2800,2801,2804,2806,2808,2811,2813,2816,2818,2821,2823,2826,2828,2831,2833,2836],{"class":232,"line":1555},[230,2802,2803],{"class":236},"    generate",[230,2805,182],{"class":240},[230,2807,1403],{"class":240},[230,2809,2810],{"class":236}," preset",[230,2812,182],{"class":240},[230,2814,2815],{"class":255}," bytes",[230,2817,1019],{"class":240},[230,2819,2820],{"class":236}," length",[230,2822,182],{"class":240},[230,2824,2825],{"class":1119}," 32",[230,2827,1019],{"class":240},[230,2829,2830],{"class":236}," encoding",[230,2832,182],{"class":240},[230,2834,2835],{"class":255}," base64-url",[230,2837,1423],{"class":240},[145,2839,2840,2841,2844,2845,2848,2849,2852,2853,2856,2857,681,2860,2863,2864,2867,2868,2871],{},"Generator presets are ",[149,2842,2843],{},"password"," (length 32), ",[149,2846,2847],{},"token"," (48), ",[149,2850,2851],{},"bytes"," (32 and\n",[149,2854,2855],{},"base64-url","), ",[149,2858,2859],{},"laravel-app-key",[149,2861,2862],{},"uuid",". Length overrides must be 16–4096.\nOther byte encodings are ",[149,2865,2866],{},"base64"," and ",[149,2869,2870],{},"hex",". Provider instance names are stable\nand independent of driver\u002Fmode. Credentials and recovery material remain\nprivate mm state, not project configuration.",[212,2873,2875],{"id":2874},"development-mail-jobs-schedules-and-gates","Development mail, jobs, schedules, and gates",[184,2877,2879],{"className":224,"code":2878,"language":226,"meta":190,"style":190},"development-mail:\n  enabled: true\n  bindings:\n    MAIL_HOST: smtp-host\n    MAIL_PORT: smtp-port\n    MAIL_URL: smtp-url\n    MAIL_UI: ui-url\n\njobs:\n  migrate:\n    module: api\n    service: web\n    command: [php, artisan, migrate, --force]\n    environment: staging # optional\n\nschedules:\n  nightly-migrate:\n    job: migrate\n    cron: \"0 2 * * *\"\n    enabled: true # default\n\ngates:\n  admin:\n    provider: password-cap\n    ingress: [admin]\n",[149,2880,2881,2887,2896,2903,2913,2923,2933,2943,2947,2953,2959,2967,2975,3003,3013,3017,3023,3030,3038,3046,3056,3060,3066,3073,3083],{"__ignoreMap":190},[230,2882,2883,2885],{"class":232,"line":233},[230,2884,814],{"class":236},[230,2886,241],{"class":240},[230,2888,2889,2892,2894],{"class":232,"line":244},[230,2890,2891],{"class":236},"  enabled",[230,2893,182],{"class":240},[230,2895,1182],{"class":1119},[230,2897,2898,2901],{"class":232,"line":364},[230,2899,2900],{"class":236},"  bindings",[230,2902,241],{"class":240},[230,2904,2905,2908,2910],{"class":232,"line":978},[230,2906,2907],{"class":236},"    MAIL_HOST",[230,2909,182],{"class":240},[230,2911,2912],{"class":255}," smtp-host\n",[230,2914,2915,2918,2920],{"class":232,"line":985},[230,2916,2917],{"class":236},"    MAIL_PORT",[230,2919,182],{"class":240},[230,2921,2922],{"class":255}," smtp-port\n",[230,2924,2925,2928,2930],{"class":232,"line":993},[230,2926,2927],{"class":236},"    MAIL_URL",[230,2929,182],{"class":240},[230,2931,2932],{"class":255}," smtp-url\n",[230,2934,2935,2938,2940],{"class":232,"line":1007},[230,2936,2937],{"class":236},"    MAIL_UI",[230,2939,182],{"class":240},[230,2941,2942],{"class":255}," ui-url\n",[230,2944,2945],{"class":232,"line":1027},[230,2946,975],{"emptyLinePlaceholder":974},[230,2948,2949,2951],{"class":232,"line":1042},[230,2950,828],{"class":236},[230,2952,241],{"class":240},[230,2954,2955,2957],{"class":232,"line":1061},[230,2956,1888],{"class":236},[230,2958,241],{"class":240},[230,2960,2961,2963,2965],{"class":232,"line":1069},[230,2962,1895],{"class":236},[230,2964,182],{"class":240},[230,2966,1900],{"class":255},[230,2968,2969,2971,2973],{"class":232,"line":1083},[230,2970,1905],{"class":236},[230,2972,182],{"class":240},[230,2974,1910],{"class":255},[230,2976,2977,2979,2981,2983,2986,2988,2991,2993,2996,2998,3001],{"class":232,"line":1097},[230,2978,1915],{"class":236},[230,2980,182],{"class":240},[230,2982,252],{"class":240},[230,2984,2985],{"class":255},"php",[230,2987,1019],{"class":240},[230,2989,2990],{"class":255}," artisan",[230,2992,1019],{"class":240},[230,2994,2995],{"class":255}," migrate",[230,2997,1019],{"class":240},[230,2999,3000],{"class":255}," --force",[230,3002,259],{"class":240},[230,3004,3005,3007,3009,3011],{"class":232,"line":1111},[230,3006,1944],{"class":236},[230,3008,182],{"class":240},[230,3010,1154],{"class":255},[230,3012,1123],{"class":337},[230,3014,3015],{"class":232,"line":1126},[230,3016,975],{"emptyLinePlaceholder":974},[230,3018,3019,3021],{"class":232,"line":1139},[230,3020,840],{"class":236},[230,3022,241],{"class":240},[230,3024,3025,3028],{"class":232,"line":1162},[230,3026,3027],{"class":236},"  nightly-migrate",[230,3029,241],{"class":240},[230,3031,3032,3034,3036],{"class":232,"line":1167},[230,3033,2042],{"class":236},[230,3035,182],{"class":240},[230,3037,2047],{"class":255},[230,3039,3040,3042,3044],{"class":232,"line":1174},[230,3041,2052],{"class":236},[230,3043,182],{"class":240},[230,3045,2057],{"class":255},[230,3047,3048,3050,3052,3054],{"class":232,"line":1185},[230,3049,2072],{"class":236},[230,3051,182],{"class":240},[230,3053,1134],{"class":1119},[230,3055,1094],{"class":337},[230,3057,3058],{"class":232,"line":1193},[230,3059,975],{"emptyLinePlaceholder":974},[230,3061,3062,3064],{"class":232,"line":1201},[230,3063,852],{"class":236},[230,3065,241],{"class":240},[230,3067,3068,3071],{"class":232,"line":1212},[230,3069,3070],{"class":236},"  admin",[230,3072,241],{"class":240},[230,3074,3075,3078,3080],{"class":232,"line":1555},[230,3076,3077],{"class":236},"    provider",[230,3079,182],{"class":240},[230,3081,3082],{"class":255}," password-cap\n",[230,3084,3085,3087,3089,3091,3094],{"class":232,"line":1565},[230,3086,1064],{"class":236},[230,3088,182],{"class":240},[230,3090,252],{"class":240},[230,3092,3093],{"class":255},"admin",[230,3095,259],{"class":240},[145,3097,3098,3099,3102,3103,3106,3107,3110],{},"Jobs require an existing module\u002Fservice and a non-empty argument vector.\nSchedules require an existing job and exactly five cron fields. A gate\ndeclaration names a gate driver such as ",[149,3100,3101],{},"password-cap"," and optional ingress\nreferences. Operational policies, users, sessions, and credentials are private\nstate rather than project configuration. The ",[149,3104,3105],{},"--secret-provider"," accepted by\n",[149,3108,3109],{},"mm access add"," separately selects storage for access secrets; it is not this driver\nfield.",[212,3112,3114],{"id":3113},"schema-and-validation","Schema and validation",[145,3116,3117,3120],{},[149,3118,3119],{},"mm config schema"," prints the generated JSON Schema without loading a project or\nprobing a container engine:",[184,3122,3124],{"className":315,"code":3123,"language":317,"meta":190,"style":190},"mm config schema > mm.schema.json\nmm config validate\n",[149,3125,3126,3141],{"__ignoreMap":190},[230,3127,3128,3130,3132,3135,3138],{"class":232,"line":233},[230,3129,325],{"class":324},[230,3131,328],{"class":255},[230,3133,3134],{"class":255}," schema",[230,3136,3137],{"class":240}," >",[230,3139,3140],{"class":255}," mm.schema.json\n",[230,3142,3143,3145,3147],{"class":232,"line":244},[230,3144,325],{"class":324},[230,3146,328],{"class":255},[230,3148,3149],{"class":255}," validate\n",[145,3151,3152,3153,3158,3159,3162,3163,3165],{},"The same generated schema is published as\n",[166,3154,3156],{"href":3155},"\u002Fschema\u002Fmm.schema.json",[149,3157,3155],{},", with one schema per\ntop-level key for split files under ",[149,3160,3161],{},"\u002Fschema\u002Fmm\u002F",". Core tests compare that file\nbyte-for-byte with ",[149,3164,3119],{},", while the hand-written sections above explain\ncross-resource behavior that JSON Schema alone cannot express.",[145,3167,3168,3171],{},[149,3169,3170],{},".\u002Fscripts\u002Fgenerate-artifacts.sh"," is the only checked-in generation path. The\nschema carries its source and generation command and must not be manually edited.",[145,3173,3174],{},"Schema 1 is the complete current project contract. Missing or different schema\nversions are rejected rather than guessed or rewritten.",[145,3176,3177,3179],{},[149,3178,499],{}," resolves the selected environment and performs cross-resource,\npath, file, ingress, build, environment, and secret-reference checks without\ninspecting containers.",[3181,3182,3183],"style",{},"html pre.shiki code .sWZmh, html code.shiki .sWZmh{--shiki-default:var(--mm-code-key)}html pre.shiki code .sIbZ0, html code.shiki .sIbZ0{--shiki-default:var(--mm-code-punctuation)}html pre.shiki code .sv8ni, html code.shiki .sv8ni{--shiki-default:var(--mm-code-string)}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 pre.shiki code .svrjQ, html code.shiki .svrjQ{--shiki-default:var(--mm-code-function)}html pre.shiki code .sP7nD, html code.shiki .sP7nD{--shiki-default:var(--mm-code-comment)}html pre.shiki code .sbRf1, html code.shiki .sbRf1{--shiki-default:var(--mm-code-option)}html pre.shiki code .s1Wbj, html code.shiki .s1Wbj{--shiki-default:var(--mm-code-constant)}html pre.shiki code .sN9xe, html code.shiki .sN9xe{--shiki-default:var(--mm-code-fg)}",{"title":190,"searchDepth":244,"depth":244,"links":3185},[3186,3187,3188,3189,3190,3191,3192,3193,3194],{"id":214,"depth":244,"text":215},{"id":304,"depth":244,"text":305},{"id":538,"depth":244,"text":539},{"id":947,"depth":244,"text":948},{"id":1270,"depth":244,"text":1271},{"id":1872,"depth":244,"text":54},{"id":2345,"depth":244,"text":2346},{"id":2874,"depth":244,"text":2875},{"id":3113,"depth":244,"text":3114},"Schema version 1 project configuration for mm.","md",{},{"title":93,"description":3195},"docs\u002Freference\u002Fconfiguration","_0G2eacuwP8PvHFhjSsEwqT5lGjIB2OPN49gnSBwATE",1794512545911]