[{"data":1,"prerenderedAt":1138},["ShallowReactive",2],{"docs-nav:en":3,"docs:\u002Fdocs\u002Finfra\u002Fgradient":134},[4],{"title":5,"path":6,"stem":7,"children":8,"page":-1},"Docs","\u002Fdocs","docs",[9,12,16,20,24,42,63,92,113],{"title":10,"path":6,"stem":11},"What is Fougere","docs\u002Findex",{"title":13,"path":14,"stem":15},"Getting started","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",{"title":17,"path":18,"stem":19},"Existing Nuxt app","\u002Fdocs\u002Fexisting-app","docs\u002F02.existing-app",{"title":21,"path":22,"stem":23},"The CLI","\u002Fdocs\u002Fcli","docs\u002F03.cli",{"title":25,"path":26,"stem":27,"children":28,"page":41},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[29,33,37],{"title":30,"path":31,"stem":32},"Philosophy","\u002Fdocs\u002Fconcepts\u002Fphilosophy","docs\u002F2.concepts\u002F1.philosophy",{"title":34,"path":35,"stem":36},"The Frond","\u002Fdocs\u002Fconcepts\u002Ffrond","docs\u002F2.concepts\u002F2.frond",{"title":38,"path":39,"stem":40},"The shortest path","\u002Fdocs\u002Fconcepts\u002Fshortest-path","docs\u002F2.concepts\u002F3.shortest-path",false,{"title":43,"path":44,"stem":45,"children":46,"page":41},"Schema","\u002Fdocs\u002Fschema","docs\u002F3.schema",[47,51,55,59],{"title":48,"path":49,"stem":50},"Entities","\u002Fdocs\u002Fschema\u002Fentities","docs\u002F3.schema\u002F1.entities",{"title":52,"path":53,"stem":54},"Views","\u002Fdocs\u002Fschema\u002Fviews","docs\u002F3.schema\u002F2.views",{"title":56,"path":57,"stem":58},"The identity card","\u002Fdocs\u002Fschema\u002Fcard","docs\u002F3.schema\u002F3.card",{"title":60,"path":61,"stem":62},"Standard Schema","\u002Fdocs\u002Fschema\u002Fstandard-schema","docs\u002F3.schema\u002F4.standard-schema",{"title":64,"path":65,"stem":66,"children":67,"page":41},"Business","\u002Fdocs\u002Fbusiness","docs\u002F4.business",[68,72,76,80,84,88],{"title":69,"path":70,"stem":71},"Handlers","\u002Fdocs\u002Fbusiness\u002Fhandlers","docs\u002F4.business\u002F1.handlers",{"title":73,"path":74,"stem":75},"Presenters","\u002Fdocs\u002Fbusiness\u002Fpresenters","docs\u002F4.business\u002F2.presenters",{"title":77,"path":78,"stem":79},"Collectors","\u002Fdocs\u002Fbusiness\u002Fcollectors","docs\u002F4.business\u002F3.collectors",{"title":81,"path":82,"stem":83},"Errors","\u002Fdocs\u002Fbusiness\u002Ferrors","docs\u002F4.business\u002F4.errors",{"title":85,"path":86,"stem":87},"Seeds","\u002Fdocs\u002Fbusiness\u002Fseeds","docs\u002F4.business\u002F5.seeds",{"title":89,"path":90,"stem":91},"Facts","\u002Fdocs\u002Fbusiness\u002Ffacts","docs\u002F4.business\u002F6.facts",{"title":93,"path":94,"stem":95,"children":96,"page":41},"Client","\u002Fdocs\u002Fclient","docs\u002F5.client",[97,101,105,109],{"title":98,"path":99,"stem":100},"Queries & commands","\u002Fdocs\u002Fclient\u002Fqueries-commands","docs\u002F5.client\u002F1.queries-commands",{"title":102,"path":103,"stem":104},"Forms","\u002Fdocs\u002Fclient\u002Fforms","docs\u002F5.client\u002F2.forms",{"title":106,"path":107,"stem":108},"Session","\u002Fdocs\u002Fclient\u002Fsession","docs\u002F5.client\u002F3.session",{"title":110,"path":111,"stem":112},"invoke","\u002Fdocs\u002Fclient\u002Finvoke","docs\u002F5.client\u002F4.invoke",{"title":114,"path":115,"stem":116,"children":117,"page":41},"Infrastructure","\u002Fdocs\u002Finfra","docs\u002F6.infra",[118,122,126,130],{"title":119,"path":120,"stem":121},"The gradient","\u002Fdocs\u002Finfra\u002Fgradient","docs\u002F6.infra\u002F1.gradient",{"title":123,"path":124,"stem":125},"Surfaces — REST & GraphQL","\u002Fdocs\u002Finfra\u002Fsurfaces","docs\u002F6.infra\u002F2.surfaces",{"title":127,"path":128,"stem":129},"Deployment","\u002Fdocs\u002Finfra\u002Fdeployment","docs\u002F6.infra\u002F3.deployment",{"title":131,"path":132,"stem":133},"Hosts","\u002Fdocs\u002Finfra\u002Fhosts","docs\u002F6.infra\u002F4.hosts",{"id":135,"title":119,"body":136,"description":1133,"extension":1134,"meta":1135,"navigation":500,"path":120,"seo":1136,"stem":121,"__hash__":1137},"docs_en\u002Fdocs\u002F6.infra\u002F1.gradient.md",{"type":137,"value":138,"toc":1122},"minimark",[139,143,147,152,237,244,273,277,288,307,311,317,754,769,780,784,791,837,844,847,851,928,932,938,941,945,963,966,1021,1029,1033,1046,1052,1058,1087,1090,1101,1105,1111,1118],[140,141,119],"h1",{"id":142},"the-gradient",[144,145,146],"p",{},"The gradient lets a Frond move from local execution to a remote process without changing\nits business code or the pages that call it.",[148,149,151],"h2",{"id":150},"the-topology-statement","The topology statement",[153,154,159],"pre",{"className":155,"code":156,"language":157,"meta":158,"style":158},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F fougere.config.ts\nexport default defineFougere({\n  remotes: { blog: 'http:\u002F\u002F127.0.0.1:4100' },\n});\n","ts","",[160,161,162,171,193,225],"code",{"__ignoreMap":158},[163,164,167],"span",{"class":165,"line":166},"line",1,[163,168,170],{"class":169},"sutJx","\u002F\u002F fougere.config.ts\n",[163,172,174,178,181,185,189],{"class":165,"line":173},2,[163,175,177],{"class":176},"sVHd0","export",[163,179,180],{"class":176}," default",[163,182,184],{"class":183},"sGLFI"," defineFougere",[163,186,188],{"class":187},"su5hD","(",[163,190,192],{"class":191},"sP7_E","{\n",[163,194,196,200,203,206,209,211,215,219,222],{"class":165,"line":195},3,[163,197,199],{"class":198},"skxfh","  remotes",[163,201,202],{"class":191},":",[163,204,205],{"class":191}," {",[163,207,208],{"class":198}," blog",[163,210,202],{"class":191},[163,212,214],{"class":213},"sjJ54"," '",[163,216,218],{"class":217},"s_sjI","http:\u002F\u002F127.0.0.1:4100",[163,220,221],{"class":213},"'",[163,223,224],{"class":191}," },\n",[163,226,228,231,234],{"class":165,"line":227},4,[163,229,230],{"class":191},"}",[163,232,233],{"class":187},")",[163,235,236],{"class":191},";\n",[144,238,239,240,243],{},"A Frond declared in ",[160,241,242],{},"remotes"," is still scanned: its entities continue to provide metadata\nfor forms, validation, and DI. Its operations instead run at the remote address. Removing\nthe line restores local execution. The multi-Frond demo covers both configurations,\nincluding a production build:",[153,245,249],{"className":246,"code":247,"language":248,"meta":158,"style":158},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","pnpm dev:blog      # the blog Frond alone, in its own process (:4100)\npnpm dev           # the app — consumes it through the remotes line\n","bash",[160,250,251,263],{"__ignoreMap":158},[163,252,253,257,260],{"class":165,"line":166},[163,254,256],{"class":255},"sbgvK","pnpm",[163,258,259],{"class":217}," dev:blog",[163,261,262],{"class":169},"      # the blog Frond alone, in its own process (:4100)\n",[163,264,265,267,270],{"class":165,"line":173},[163,266,256],{"class":255},[163,268,269],{"class":217}," dev",[163,271,272],{"class":169},"           # the app — consumes it through the remotes line\n",[148,274,276],{"id":275},"the-call-contract","The call contract",[144,278,279,280,283,284,287],{},"A call is a value: ",[160,281,282],{},"(entity, operation, invocation)"," with\n",[160,285,286],{},"invocation = { params, query, body, state }",".",[289,290,291,298,304],"ul",{},[292,293,294,297],"li",{},[160,295,296],{},"createLocalRunner"," executes strictly locally;",[292,299,300,303],{},[160,301,302],{},"createAppRunner"," follows the topology — local façades, remote doublures;",[292,305,306],{},"transports serialize this value without changing its structure.",[148,308,310],{"id":309},"the-wire-format","The wire format",[144,312,313,314,202],{},"Process-to-process is JSON-RPC 2.0 on ",[160,315,316],{},"POST \u002F_fougere\u002Fcall",[153,318,322],{"className":319,"code":320,"language":321,"meta":158,"style":158},"language-jsonc shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F → request\n{ \"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"post.publish\",\n  \"params\": { \"params\": { \"id\": \"…\" }, \"query\": {}, \"body\": null, \"state\": { \"user\": { … } } } }\n\n\u002F\u002F ← success\n{ \"jsonrpc\": \"2.0\", \"id\": 1, \"result\": { \"id\": \"…\", \"status\": \"published\", … } }\n\n\u002F\u002F ← domain failure — revived as FougereError on the calling side\n{ \"jsonrpc\": \"2.0\", \"id\": 1, \"error\": { \"code\": -32000,\n    \"data\": { \"code\": \"CONFLICT\", \"message\": \"Already published\",\n              \"entity\": \"post\", \"operation\": \"publish\" } } }\n","jsonc",[160,323,324,329,391,496,502,508,592,597,603,660,710],{"__ignoreMap":158},[163,325,326],{"class":165,"line":166},[163,327,328],{"class":169},"\u002F\u002F → request\n",[163,330,331,334,338,342,345,347,349,352,354,357,359,362,364,366,370,372,374,377,379,381,383,386,388],{"class":165,"line":173},[163,332,333],{"class":191},"{",[163,335,337],{"class":336},"s39Yj"," \"",[163,339,341],{"class":340},"sseR_","jsonrpc",[163,343,344],{"class":336},"\"",[163,346,202],{"class":191},[163,348,337],{"class":213},[163,350,351],{"class":217},"2.0",[163,353,344],{"class":213},[163,355,356],{"class":191},",",[163,358,337],{"class":336},[163,360,361],{"class":340},"id",[163,363,344],{"class":336},[163,365,202],{"class":191},[163,367,369],{"class":368},"srdBf"," 1",[163,371,356],{"class":191},[163,373,337],{"class":336},[163,375,376],{"class":340},"method",[163,378,344],{"class":336},[163,380,202],{"class":191},[163,382,337],{"class":213},[163,384,385],{"class":217},"post.publish",[163,387,344],{"class":213},[163,389,390],{"class":191},",\n",[163,392,393,396,399,401,403,405,407,410,412,414,416,418,420,422,424,426,429,431,434,436,439,441,443,446,448,451,453,455,458,460,462,465,467,469,471,473,476,478,480,482,486,489,491,493],{"class":165,"line":195},[163,394,395],{"class":336},"  \"",[163,397,398],{"class":340},"params",[163,400,344],{"class":336},[163,402,202],{"class":191},[163,404,205],{"class":191},[163,406,337],{"class":336},[163,408,398],{"class":409},"sZMiF",[163,411,344],{"class":336},[163,413,202],{"class":191},[163,415,205],{"class":191},[163,417,337],{"class":336},[163,419,361],{"class":368},[163,421,344],{"class":336},[163,423,202],{"class":191},[163,425,337],{"class":213},[163,427,428],{"class":217},"…",[163,430,344],{"class":213},[163,432,433],{"class":191}," },",[163,435,337],{"class":336},[163,437,438],{"class":409},"query",[163,440,344],{"class":336},[163,442,202],{"class":191},[163,444,445],{"class":191}," {},",[163,447,337],{"class":336},[163,449,450],{"class":409},"body",[163,452,344],{"class":336},[163,454,202],{"class":191},[163,456,457],{"class":336}," null",[163,459,356],{"class":191},[163,461,337],{"class":336},[163,463,464],{"class":409},"state",[163,466,344],{"class":336},[163,468,202],{"class":191},[163,470,205],{"class":191},[163,472,337],{"class":336},[163,474,475],{"class":368},"user",[163,477,344],{"class":336},[163,479,202],{"class":191},[163,481,205],{"class":191},[163,483,485],{"class":484},"srjyR"," …",[163,487,488],{"class":191}," }",[163,490,488],{"class":191},[163,492,488],{"class":191},[163,494,495],{"class":191}," }\n",[163,497,498],{"class":165,"line":227},[163,499,501],{"emptyLinePlaceholder":500},true,"\n",[163,503,505],{"class":165,"line":504},5,[163,506,507],{"class":169},"\u002F\u002F ← success\n",[163,509,511,513,515,517,519,521,523,525,527,529,531,533,535,537,539,541,543,546,548,550,552,554,556,558,560,562,564,566,568,570,573,575,577,579,582,584,586,588,590],{"class":165,"line":510},6,[163,512,333],{"class":191},[163,514,337],{"class":336},[163,516,341],{"class":340},[163,518,344],{"class":336},[163,520,202],{"class":191},[163,522,337],{"class":213},[163,524,351],{"class":217},[163,526,344],{"class":213},[163,528,356],{"class":191},[163,530,337],{"class":336},[163,532,361],{"class":340},[163,534,344],{"class":336},[163,536,202],{"class":191},[163,538,369],{"class":368},[163,540,356],{"class":191},[163,542,337],{"class":336},[163,544,545],{"class":340},"result",[163,547,344],{"class":336},[163,549,202],{"class":191},[163,551,205],{"class":191},[163,553,337],{"class":336},[163,555,361],{"class":409},[163,557,344],{"class":336},[163,559,202],{"class":191},[163,561,337],{"class":213},[163,563,428],{"class":217},[163,565,344],{"class":213},[163,567,356],{"class":191},[163,569,337],{"class":336},[163,571,572],{"class":409},"status",[163,574,344],{"class":336},[163,576,202],{"class":191},[163,578,337],{"class":213},[163,580,581],{"class":217},"published",[163,583,344],{"class":213},[163,585,356],{"class":191},[163,587,485],{"class":484},[163,589,488],{"class":191},[163,591,495],{"class":191},[163,593,595],{"class":165,"line":594},7,[163,596,501],{"emptyLinePlaceholder":500},[163,598,600],{"class":165,"line":599},8,[163,601,602],{"class":169},"\u002F\u002F ← domain failure — revived as FougereError on the calling side\n",[163,604,606,608,610,612,614,616,618,620,622,624,626,628,630,632,634,636,638,641,643,645,647,649,651,653,655,658],{"class":165,"line":605},9,[163,607,333],{"class":191},[163,609,337],{"class":336},[163,611,341],{"class":340},[163,613,344],{"class":336},[163,615,202],{"class":191},[163,617,337],{"class":213},[163,619,351],{"class":217},[163,621,344],{"class":213},[163,623,356],{"class":191},[163,625,337],{"class":336},[163,627,361],{"class":340},[163,629,344],{"class":336},[163,631,202],{"class":191},[163,633,369],{"class":368},[163,635,356],{"class":191},[163,637,337],{"class":336},[163,639,640],{"class":340},"error",[163,642,344],{"class":336},[163,644,202],{"class":191},[163,646,205],{"class":191},[163,648,337],{"class":336},[163,650,160],{"class":409},[163,652,344],{"class":336},[163,654,202],{"class":191},[163,656,657],{"class":368}," -32000",[163,659,390],{"class":191},[163,661,663,666,669,671,673,675,677,679,681,683,685,688,690,692,694,697,699,701,703,706,708],{"class":165,"line":662},10,[163,664,665],{"class":336},"    \"",[163,667,668],{"class":409},"data",[163,670,344],{"class":336},[163,672,202],{"class":191},[163,674,205],{"class":191},[163,676,337],{"class":336},[163,678,160],{"class":368},[163,680,344],{"class":336},[163,682,202],{"class":191},[163,684,337],{"class":213},[163,686,687],{"class":217},"CONFLICT",[163,689,344],{"class":213},[163,691,356],{"class":191},[163,693,337],{"class":336},[163,695,696],{"class":368},"message",[163,698,344],{"class":336},[163,700,202],{"class":191},[163,702,337],{"class":213},[163,704,705],{"class":217},"Already published",[163,707,344],{"class":213},[163,709,390],{"class":191},[163,711,713,716,719,721,723,725,728,730,732,734,737,739,741,743,746,748,750,752],{"class":165,"line":712},11,[163,714,715],{"class":336},"              \"",[163,717,718],{"class":368},"entity",[163,720,344],{"class":336},[163,722,202],{"class":191},[163,724,337],{"class":213},[163,726,727],{"class":217},"post",[163,729,344],{"class":213},[163,731,356],{"class":191},[163,733,337],{"class":336},[163,735,736],{"class":368},"operation",[163,738,344],{"class":336},[163,740,202],{"class":191},[163,742,337],{"class":213},[163,744,745],{"class":217},"publish",[163,747,344],{"class":213},[163,749,488],{"class":191},[163,751,488],{"class":191},[163,753,495],{"class":191},[144,755,756,758,759,762,763,765,766,768],{},[160,757,376],{}," is ",[160,760,761],{},"entity.op"," and ",[160,764,398],{}," contains the invocation. The browser sends the same\nframe to Nitro, but its ",[160,767,464],{}," is ignored and rebuilt server-side.",[144,770,771,772,775,776,779],{},"The other half of the contract is what a host answers to ",[160,773,774],{},"rpc.discover",": see\n",[777,778,56],"a",{"href":57},", which specifies the document and what to honour to\nwrite a Frond in another language.",[148,781,783],{"id":782},"the-hop-is-loopback-by-default","The hop is loopback by default",[144,785,786,787,790],{},"The receiver binds ",[160,788,789],{},"127.0.0.1"," and caps bodies at 1 MiB. Widening it is one option:",[153,792,794],{"className":155,"code":793,"language":157,"meta":158,"style":158},"await serve(runner, { hosts: ['0.0.0.0'] })   \u002F\u002F a container, saying so\n",[160,795,796],{"__ignoreMap":158},[163,797,798,801,804,807,809,811,814,816,819,821,824,826,829,831,834],{"class":165,"line":166},[163,799,800],{"class":176},"await",[163,802,803],{"class":183}," serve",[163,805,806],{"class":187},"(runner",[163,808,356],{"class":191},[163,810,205],{"class":191},[163,812,813],{"class":198}," hosts",[163,815,202],{"class":191},[163,817,818],{"class":187}," [",[163,820,221],{"class":213},[163,822,823],{"class":217},"0.0.0.0",[163,825,221],{"class":213},[163,827,828],{"class":187},"] ",[163,830,230],{"class":191},[163,832,833],{"class":187},")   ",[163,835,836],{"class":169},"\u002F\u002F a container, saying so\n",[144,838,839,840,843],{},"The default is not caution, and the option is not a hole — it is where a fact meets a\ndeployment. A receiver reads the caller's identity off the wire and re-establishes\nnothing, so whatever can reach the port can claim to be any user. On loopback that set is\n\"this machine\". Widen ",[160,841,842],{},"hosts"," and it becomes whatever the network lets through, which is\nthen the operator's to close — a firewall, a sidecar, a mesh.",[144,845,846],{},"Authenticating the link would not replace it either: a shared secret says a process may\ncall, never which user it speaks for. Identity at the Frond is the open question.",[148,848,850],{"id":849},"behaviour-after-a-split","Behaviour after a split",[852,853,854,867],"table",{},[855,856,857],"thead",{},[858,859,860,864],"tr",{},[861,862,863],"th",{},"Element",[861,865,866],{},"Behaviour",[868,869,870,879,901,908,920],"tbody",{},[858,871,872,876],{},[873,874,875],"td",{},"results",[873,877,878],{},"identical shapes both sides, list results included",[858,880,881,884],{},[873,882,883],{},"errors",[873,885,886,887,890,891,893,894,896,897,900],{},"same ",[160,888,889],{},"FougereError"," with ",[160,892,160],{},", ",[160,895,696],{},", and ",[160,898,899],{},"details",", rebuilt on arrival",[858,902,903,905],{},[873,904,464],{},[873,906,907],{},"the consuming app's session reaches remote collectors",[858,909,910,913],{},[873,911,912],{},"unreachable host",[873,914,915,916,919],{},"typed ",[160,917,918],{},"SERVICE_UNAVAILABLE"," → status 503; calls resume after the host restarts",[858,921,922,925],{},[873,923,924],{},"transport",[873,926,927],{},"timeout and retry on the envelope, without automatic command retries",[148,929,931],{"id":930},"the-price-of-the-split","The price of the split",[144,933,934,935,937],{},"The split adds an HTTP hop and the JSON encoding and decoding it entails. A call remains\na value ",[160,936,282],{},"; the transport frames it and unframes it, then\nthe receiving side runs the same façade as the local path. The cost therefore depends on\nthe network, payload size and runtime: Fougere does not claim to make it zero.",[144,939,940],{},"No figure is quoted here: this repository ships no benchmark harness, and a number you\ncannot re-run is not a measurement.",[148,942,944],{"id":943},"where-the-code-lives","Where the code lives",[144,946,947,948,950,951,955,956,958,959,962],{},"A Frond can also move to a separate repository and remain available through ",[160,949,242],{},".\nThree things are called \"together\" and only one is mandatory: the ",[952,953,954],"strong",{},"contract"," must\ntravel, the ",[952,957,160],{}," need not, the ",[952,960,961],{},"ports"," must reach each other.",[144,964,965],{},"Two commands cover the contract, depending on what you want to share:",[852,967,968,980],{},[855,969,970],{},[858,971,972,974,977],{},[861,973],{},[861,975,976],{},"What it does",[861,978,979],{},"When",[868,981,982,1001],{},[858,983,984,992,998],{},[873,985,986],{},[777,987,989],{"href":988},"\u002Fdocs\u002Fcli#fougere-sync-consume-a-remote-frond",[160,990,991],{},"fougere sync",[873,993,994,995,997],{},"asks the host for ",[160,996,774],{}," and rebuilds its entities locally",[873,999,1000],{},"the host is running; also the only way in for a Frond written in another language",[858,1002,1003,1011,1018],{},[873,1004,1005],{},[777,1006,1008],{"href":1007},"\u002Fdocs\u002Fcli#fougere-build-frond-publish-a-fronds-entities",[160,1009,1010],{},"fougere build-frond",[873,1012,1013,1014,1017],{},"compiles ",[160,1015,1016],{},"entities\u002F**"," into an installable package",[873,1019,1020],{},"you publish the contract as a dependency",[144,1022,1023,1024,775,1026,287],{},"The Frond's source code crosses in neither case. What stays open is the ",[952,1025,961],{},[777,1027,127],{"href":1028},"\u002Fdocs\u002Finfra\u002Fdeployment#splitting-in-production",[148,1030,1032],{"id":1031},"one-recipient-and-only-one","One recipient, and only one",[144,1034,1035,1037,1038,1041,1042,1045],{},[160,1036,242],{}," names an address per Frond, and ",[160,1039,1040],{},"Facade\u003CT>"," resolves to exactly one façade —\n",[160,1043,1044],{},"facadeKeyOf"," produces one key, the container returns one object. Every call in Fougere\nhas a single recipient, by construction.",[144,1047,1048,1049,1051],{},"That covers more than it sounds like. A device behind NAT that cannot be called still\ndeclares ",[160,1050,242],{}," and sends to a gateway it names: one recipient, and the fact that the\ndevice must open the connection is a deployment property, not a different kind of call.",[144,1053,1054,1055,202],{},"What is not covered is ",[952,1056,1057],{},"several recipients for one send",[852,1059,1060,1069],{},[855,1061,1062],{},[858,1063,1064,1066],{},[861,1065],{},[861,1067,1068],{},"who determines the recipients",[868,1070,1071,1079],{},[858,1072,1073,1076],{},[873,1074,1075],{},"a fleet",[873,1077,1078],{},"the sender names the set",[858,1080,1081,1084],{},[873,1082,1083],{},"a fact — a post was published",[873,1085,1086],{},"nobody: whoever declared an interest",[144,1088,1089],{},"Both need the same machinery — fan-out, a channel to members that carry no address, and a\nverdict when three of five succeed. Fougere has none of it. So a post being published,\nwith search reindexing and the newsletter queueing, is written today by naming both at the\nemitting site: the emitter carries the list of everything that follows from its own\naction, and a third reader reopens it.",[144,1091,1092,1093,1095,1096,1100],{},"This section exists to name the half that is here. ",[160,1094,242],{}," reads like ",[1097,1098,1099],"em",{},"the"," topology\nstatement and it is one of two; the other is designed and not shipped. Saying so keeps the\ngap visible rather than surprising.",[148,1102,1104],{"id":1103},"limits","Limits",[144,1106,1107,1108,1110],{},"Moving a Frond to a remote process adds network latency and failure modes. Fougere exposes\nthem as typed errors but does not hide them. Local mode remains the reference mode;\n",[160,1109,242],{}," changes the topology when the need arises.",[144,1112,1113,1114,1117],{},"Next: ",[777,1115,1116],{"href":124},"Surfaces"," — the same operations behind REST and GraphQL.",[1119,1120,1121],"style",{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sseR_, html code.shiki .sseR_{--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srjyR, html code.shiki .srjyR{--shiki-light:#90A4AE;--shiki-light-font-style:inherit;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":158,"searchDepth":173,"depth":173,"links":1123},[1124,1125,1126,1127,1128,1129,1130,1131,1132],{"id":150,"depth":173,"text":151},{"id":275,"depth":173,"text":276},{"id":309,"depth":173,"text":310},{"id":782,"depth":173,"text":783},{"id":849,"depth":173,"text":850},{"id":930,"depth":173,"text":931},{"id":943,"depth":173,"text":944},{"id":1031,"depth":173,"text":1032},{"id":1103,"depth":173,"text":1104},"Configure a local or remote Frond, the protocol it uses, and the network cost.","md",{},{"title":119,"description":1133},"KeT-ru_c2ll7TNbiXZ084RW9FVibC_YecksDErB5I2o",1786637818908]