[{"data":1,"prerenderedAt":63},["ShallowReactive",2],{"i-lucide:search":3,"i-lucide:sun":8,"i-lucide:menu":10,"blog-index-en":12},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"/>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"/>\u003C/g>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"/>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"/>\u003C/g>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"/>",[13],{"id":14,"title":15,"author":16,"body":17,"date":54,"description":55,"extension":56,"meta":57,"navigation":58,"path":59,"seo":60,"seoTitle":15,"stem":61,"__hash__":62},"blogEn/en/blog/introducing-maran.md","Why the agent takes no shell commands","Innovayse",{"type":18,"value":19,"toc":48},"minimark",[20,24,27,32,35,38,42,45],[21,22,23],"p",{},"Every control panel has the same shape: something a person clicks, and something with root that\ndoes the work. The interesting question is what travels between them.",[21,25,26],{},"The usual answer is a command line. It is the fastest thing to build and the hardest thing to keep\nsafe, because every value a customer controls — a domain, a database name, a file path — eventually\nlands inside a string that a shell will parse. Getting that right once is easy. Getting it right in\nevery place, forever, while the panel grows, is the part nobody manages.",[28,29,31],"h2",{"id":30},"what-we-do-instead","What we do instead",[21,33,34],{},"Maran's root daemon accepts named operations with typed, validated arguments, and nothing else.\nThere is no operation that takes a command to run. A domain is not escaped before it reaches a\nconfiguration file — it is validated as a domain, which is to say letters, digits, hyphens and\ndots, so there is no newline in it to end one directive and begin another.",[21,36,37],{},"The practical effect is that the set of things the daemon can be made to do is finite, written\ndown, and reviewable. An operation that does not exist in the contract cannot be requested, however\ninventive the request.",[28,39,41],{"id":40},"what-it-costs","What it costs",[21,43,44],{},"Every new capability is a contract change rather than a new string. That is slower, and\ndeliberately so: adding one means deciding what its arguments are, what counts as valid, and what\nhappens when the host disagrees — before any of it ships.",[21,46,47],{},"It also rules out a class of feature a panel could otherwise offer: \"run this command for me\". We\nthink that is the right trade for software that holds root on a server somebody else's customers\nlive on.",{"title":49,"searchDepth":50,"depth":50,"links":51},"",2,[52,53],{"id":30,"depth":50,"text":31},{"id":40,"depth":50,"text":41},"2026-09-19","The one design decision that shaped everything else in Maran — a root daemon that takes typed operations and no shell strings — and what it costs.","md",{},true,"/en/blog/introducing-maran",{"title":15,"description":55},"en/blog/introducing-maran","STdbSFhLF8_747edp3DUtf0y88lniGygefkG95y32ts",1790166387883]