{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Jon Molina",
  "home_page_url": "https://digitalknk.com/",
  "feed_url": "https://digitalknk.com/feed.json",
  "authors": [
    {
      "name": "Jon Molina",
      "url": "https://digitalknk.com/"
    }
  ],
  "items": [
    {
      "id": "https://digitalknk.com/posts/2026/07/13/116911232456215287",
      "url": "https://digitalknk.com/posts/2026/07/13/116911232456215287",
      "content_html": "<p>How I configured Codex with specialized subagents and safer defaults: <a href=\"https://digitalknk.com/posts/2026/07/13/how-i-configured-codex-with-specialized-subagents-and-safer--f59c6afb\" rel=\"noopener noreferrer\"><span>https://</span><span>digitalknk.com/posts/2026/07/1</span><span>3/how-i-configured-codex-with-specialized-subagents-and-safer--f59c6afb</span></a></p>",
      "date_published": "2026-07-13T06:23:55.088Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/07/13/how-i-configured-codex-with-specialized-subagents-and-safer--f59c6afb",
      "url": "https://digitalknk.com/posts/2026/07/13/how-i-configured-codex-with-specialized-subagents-and-safer--f59c6afb",
      "title": "How I configured Codex with specialized subagents and safer defaults",
      "content_html": "<p>I use Codex across several projects, and I wanted its behavior to be consistent from one task to the next. I had a few specific goals:</p><ul><li><p>Plan work before editing, then delegate independent parts to the right subagent.</p></li><li><p>Stop destructive commands before a bad path or broad cleanup request turns into data loss.</p></li></ul><p>Codex already supports the pieces needed for this. Global instructions live in <code>~/.codex/AGENTS.md</code>, custom agents live under <code>~/.codex/agents/</code>, and executable command policies can live under <code>~/.codex/rules/</code>.</p><p>This article describes my current setup on Codex CLI 0.144.x. These features can change, especially command rules, which are still documented as experimental. Check the current <a href=\"https://learn.chatgpt.com/docs/agent-configuration/subagents\" rel=\"noopener noreferrer\">Codex subagent documentation</a> and <a href=\"https://learn.chatgpt.com/docs/agent-configuration/rules\" rel=\"noopener noreferrer\">rules documentation</a> before copying the configuration unchanged.</p><p>The planning, delegation, and destructive-operation configuration is available in the <code>digitalknk/codex-global-agent-setup</code><a href=\"https://github.com/digitalknk/codex-global-agent-setup\" rel=\"noopener noreferrer\"> repository</a>.</p><h2>The directory layout</h2><p>My global Codex configuration now includes these files:</p><pre><code>~/.codex/\n├── AGENTS.md\n├── agents/\n│   ├── luna-xhigh.toml\n│   └── terra-high.toml\n└── rules/\n    ├── default.rules\n    └── safety.rules\n</code></pre><p>The files have different jobs:</p><ul><li><p><code>AGENTS.md</code> tells the main agent how to plan, delegate work, and handle destructive operations.</p></li><li><p>Each file under <code>agents/</code> defines a custom agent, including its model, reasoning effort, description, and instructions.</p></li><li><p>Files under <code>rules/</code> evaluate command prefixes and return <code>allow</code>, <code>prompt</code>, or <code>forbidden</code>.</p></li></ul><p>That distinction matters. An instruction is guidance for the model. A command rule is an executable policy check. The sandbox is the actual filesystem and network boundary. I use all of them instead of expecting one file to handle everything.</p><h2>Why I created two worker agents</h2><p>The main model is responsible for planning and coordination. I wanted it to choose between two workers based on the work in the plan.</p><p>My Luna worker handles bounded work such as a targeted search, a mechanical change, or a clearly specified test. I run it with <code>xhigh</code> reasoning:</p><pre><code>name = \"luna_worker\"\ndescription = \"\"\"\nFast implementation worker for bounded, low-risk tasks, mechanical changes,\ntargeted exploration, straightforward tests, and clearly specified fixes.\nChoose this when speed and efficiency matter more than deeper reasoning.\n\"\"\"\nmodel = \"gpt-5.6-luna\"\nmodel_reasoning_effort = \"xhigh\"\n\ndeveloper_instructions = \"\"\"\nComplete the assigned scope independently.\nStay within the files and responsibilities assigned by the parent.\nRun relevant verification and return a concise result with changed files,\ntests run, and any remaining risks.\n\"\"\"\n</code></pre><p>My Terra worker handles debugging, cross-file changes, architecture-sensitive work, and integration. It runs with <code>high</code> reasoning:</p><pre><code>name = \"terra_worker\"\ndescription = \"\"\"\nBalanced implementation worker for ambiguous changes, debugging, integration\nwork, cross-file reasoning, architecture-sensitive changes, and tasks requiring\nstronger judgment. Choose this when correctness and follow-through outweigh speed.\n\"\"\"\nmodel = \"gpt-5.6-terra\"\nmodel_reasoning_effort = \"high\"\n\ndeveloper_instructions = \"\"\"\nComplete the assigned scope independently.\nInspect the real execution path before editing, preserve existing conventions,\nrun relevant verification, and return changed files, tests run, and remaining risks.\n\"\"\"\n</code></pre><p>The model IDs available to you may be different. Use <code>/model</code> in the app or inspect the model catalog in your Codex client before pinning a model name. The important part is the division of responsibility. Give each agent a narrow description that helps the planner make a useful choice.</p><h2>Making <code>/plan</code> produce a delegation map</h2><p>Defining custom workers does not guarantee that every plan will use them. I added a planning section to my global <code>AGENTS.md</code> so the coordinator knows when delegation is expected.</p><pre><code>## Planning and delegated execution\n\nWhen Plan mode is active:\n\n- Build an implementation-ready plan grounded in the actual workspace.\n- Use subagents for independent read-only investigation when parallel research\n  would materially improve the plan.\n- Do not begin implementation while still in Plan mode.\n- Include a delegation map identifying which plan steps can run independently\n  and whether `luna_worker` or `terra_worker` is the better fit for each step.\n\nAfter the user approves the plan, starts a goal, or otherwise authorizes execution:\n\n- Treat that authorization as an explicit request to use subagents for independent\n  implementation, investigation, and verification work whenever the task can be\n  safely decomposed.\n- Choose only `luna_worker` or `terra_worker` for delegated work.\n- Choose `luna_worker` for bounded, straightforward, low-risk, mechanical, or\n  speed-sensitive work.\n- Choose `terra_worker` for ambiguous, cross-cutting, debugging-heavy,\n  architecture-sensitive, or integration-sensitive work.\n- Run independent agents concurrently when their scopes do not overlap.\n- Give every agent a specific scope, expected output, and verification requirement.\n- Wait for all required agents, integrate their results, resolve conflicts, and\n  perform final end-to-end verification in the main task.\n- Keep tightly coupled work in the main task.\n</code></pre><p>Plan mode still remains Plan mode. The agent can investigate and prepare the work, but it should not begin implementation until I approve the plan or otherwise authorize execution. Once approved, the coordinator can start independent workers concurrently and collect their results.</p><p>Codex can delegate when the user asks directly or when an applicable <code>AGENTS.md</code> or skill requests it. Each subagent consumes its own model and tool usage, so delegation has a cost. I reserve it for work that can actually run independently.</p><h2>Why I added destructive-operation rules</h2><p>An agent that can edit files and run shell commands needs clearer boundaries than \"be careful.\" The failure mode I cared about most was a recursive deletion pointed at the wrong directory.</p><p>My behavioral policy says that Codex must never recursively delete the filesystem root, my home directory, the active workspace root, or a repository root. Recursive deletion elsewhere requires an explicit request naming the exact target, path resolution, inspection, and fresh confirmation.</p><p>The policy also covers other operations that can discard work or destroy external state:</p><ul><li><p><code>git reset --hard</code>, <code>git clean</code>, destructive restore operations, history rewriting, and force pushes</p></li><li><p>Recursive permission or ownership changes</p></li><li><p>Disk formatting and raw-device writes</p></li><li><p>Database drops, infrastructure destruction, namespace deletion, and bulk cloud-resource deletion</p></li></ul><p>I also tell the agent to prefer Trash or a quarantine directory when practical, run dry-run commands where available, and preserve files it does not recognize.</p><p>This belongs in <code>AGENTS.md</code> because no short list of command prefixes can describe every destructive equivalent. It is still only a behavioral layer, so I added executable rules as a second barrier.</p><h2>Blocking root and home deletion</h2><p>Codex rules use exact argument prefixes. This sample blocks common recursive forms targeting <code>/</code> or a configured home directory:</p><pre><code>prefix_rule(\n    pattern = [\n        [\"rm\", \"/bin/rm\", \"/usr/bin/rm\"],\n        [\"-rf\", \"-fr\", \"-r\", \"-R\", \"--recursive\"],\n        [\"/\", \"/Users/YOUR_USERNAME\", \"/Users/YOUR_USERNAME/\"],\n    ],\n    decision = \"forbidden\",\n    justification = \"Never recursively delete the filesystem root or the user's home directory.\",\n    match = [\n        \"rm -rf /\",\n        \"rm -fr /Users/YOUR_USERNAME\",\n        \"/bin/rm -R /Users/YOUR_USERNAME\",\n    ],\n    not_match = [\n        \"rm -rf /Users/YOUR_USERNAME/project/tmp\",\n        \"rm file.txt\",\n    ],\n)\n</code></pre><p>Use the absolute home path. Do not assume <code>~</code> or <code>$HOME</code> will behave like a shell expansion inside an exact argument rule.</p><p>I use <code>forbidden</code> for the filesystem root and home directory. For recursive deletion elsewhere, I use <code>prompt</code>:</p><pre><code>prefix_rule(\n    pattern = [\n        [\"rm\", \"/bin/rm\", \"/usr/bin/rm\"],\n        [\"-rf\", \"-fr\", \"-r\", \"-R\", \"--recursive\"],\n    ],\n    decision = \"prompt\",\n    justification = \"Recursive deletion requires fresh approval and a verified absolute target.\",\n    match = [\n        \"rm -rf build\",\n        \"rm -r /tmp/example\",\n        \"/bin/rm --recursive generated\",\n    ],\n    not_match = [\n        \"rm file.txt\",\n        \"rmdir empty-directory\",\n    ],\n)\n</code></pre><p>My full rules file also handles separate <code>-r -f</code> arguments, <code>sudo rm</code>, destructive Git commands, recursive permission changes, disk tools, Docker prune, Terraform and OpenTofu destroy, Kubernetes namespace deletion, and database administration commands.</p><p>I keep a <a href=\"https://gist.github.com/digitalknk/598276d8d7bcdc63e9a09fbd59c36a40\" rel=\"noopener noreferrer\">sanitized copy of the complete rules file</a> separate so it can be reviewed and tested on its own. Replace <code>/Users/YOUR_USERNAME</code> with your absolute home path before installing it. Linux users will usually want <code>/home/YOUR_USERNAME</code> instead.</p><p>Rules are prefix-based, so they cannot prove that every destructive command is covered. Alternate programs, complex scripts, and remote APIs can have the same effect without sharing these prefixes. This is why I keep the behavioral policy and sandbox enabled as well.</p><h2>Keeping the sandbox and approvals enabled</h2><p>My normal configuration uses:</p><pre><code>approval_policy = \"on-request\"\napprovals_reviewer = \"user\"\nsandbox_mode = \"workspace-write\"\n</code></pre><p>The <a href=\"https://learn.chatgpt.com/docs/sandboxing\" rel=\"noopener noreferrer\">Codex sandbox documentation</a> describes the sandbox and approvals as separate controls. The sandbox defines the technical boundary. The approval policy determines when Codex must stop and ask before crossing it.</p><p>I do not treat a command rule as permission to run Codex with unrestricted access. I keep the project boundary as the default and use Full Access only when a specific task requires it and I understand the added risk.</p><h2>Testing the command rules</h2><p>Codex includes <code>execpolicy check</code> for validating rule files without running the command. I used it for every rule before restarting Codex.</p><p>To test root deletion:</p><pre><code>codex execpolicy check --pretty \\\n  --rules ~/.codex/rules/safety.rules \\\n  -- rm -rf /\n</code></pre><p>The expected decision is:</p><pre><code>{\n  \"decision\": \"forbidden\"\n}\n</code></pre><p>Test the configured home path too:</p><pre><code>codex execpolicy check --pretty \\\n  --rules ~/.codex/rules/safety.rules \\\n  -- rm -rf /Users/YOUR_USERNAME\n</code></pre><p>Then confirm that an ordinary recursive project path prompts instead of being silently allowed:</p><pre><code>codex execpolicy check --pretty \\\n  --rules ~/.codex/rules/safety.rules \\\n  -- rm -rf /some/project\n</code></pre><p>Expected decision:</p><pre><code>{\n  \"decision\": \"prompt\"\n}\n</code></pre><p>I also test rules together with my existing defaults:</p><pre><code>codex execpolicy check --pretty \\\n  --rules ~/.codex/rules/default.rules \\\n  --rules ~/.codex/rules/safety.rules \\\n  -- rm -rf src-tauri/icons/android src-tauri/icons/ios\n</code></pre><p>When multiple rules match, Codex uses the most restrictive result. In my configuration, a previous narrow <code>allow</code> for that icon cleanup is overridden by the broader recursive-deletion <code>prompt</code>.</p><p>The <code>match</code> and <code>not_match</code> entries inside the rules file act as inline tests when Codex loads it. They are worth maintaining. A safety rule that does not match the command form you expect is false confidence.</p><h2>Installing the setup</h2><p>Create the directories:</p><pre><code>mkdir -p ~/.codex/agents ~/.codex/rules\n</code></pre><p>Then:</p><ol><li><p>Add each custom agent as a standalone TOML file under <code>~/.codex/agents/</code>.</p></li><li><p>Add the planning and destructive-operation instructions to <code>~/.codex/AGENTS.md</code>.</p></li><li><p>Add command rules under <code>~/.codex/rules/</code>.</p></li><li><p>Replace every example home path with the correct absolute path for your machine.</p></li><li><p>Run <code>codex execpolicy check</code> against destructive and harmless examples.</p></li><li><p>Restart Codex so it reloads the rule files.</p></li><li><p>Start a new task so the global instructions and custom agents are loaded cleanly.</p></li></ol><p>After restarting, I test the behavior with a disposable project. I ask for a plan that has two independent work items, inspect which custom worker the coordinator chooses, and confirm that a recursive removal request produces an approval prompt. I do not test destructive policies against directories containing real work.</p><h2>What this setup does not guarantee</h2><p>No prompt or prefix-rule file can eliminate every possible failure. Models can misunderstand instructions, command-line tools have aliases and wrappers, and destructive actions can happen through APIs that never invoke <code>rm</code>.</p><p>The setup improves my defaults in several practical ways. Plans state how work will be delegated. Worker selection is explicit. Dangerous commands meet a policy barrier before execution.</p><p>That is the standard I wanted: predictable coordination, clear approval points, and fewer surprises when Codex moves from answering questions to changing a real workspace.</p>",
      "date_published": "2026-07-13T01:56:58.099Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/06/18/working-on-a-new-side-project-though-is-a273786e",
      "url": "https://digitalknk.com/posts/2026/06/18/working-on-a-new-side-project-though-is-a273786e",
      "content_html": "Working on a new side project though is something I been wanting to build but just haven't had the energy to do so.",
      "date_published": "2026-06-18T00:04:35.534Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/04/14/116405111964542802",
      "url": "https://digitalknk.com/posts/2026/04/14/116405111964542802",
      "content_html": "<p>Follow-up to my Coeus launch post from earlier:<br>Coeus isn&#39;t locked to Claude Code. I built it on ACP (Agent Client Protocol) plus direct API support, so it works with any agent that speaks either.</p><p>That means free-tier agents (Gemini, Kilo, OpenCode, Qwen Code) work out of the box. No paid subscription needed to try it.</p><p><a href=\"https://usecoeus.com/\" rel=\"noopener noreferrer\"><span>https://</span><span>usecoeus.com</span><span></span></a></p><p><a href=\"https://mastodon.social/tags/AI\" rel=\"noopener noreferrer\">#<span>AI</span></a></p>",
      "date_published": "2026-04-14T21:10:49.270Z",
      "tags": [
        "ai"
      ]
    },
    {
      "id": "https://digitalknk.com/posts/2026/04/14/116404098299612890",
      "url": "https://digitalknk.com/posts/2026/04/14/116404098299612890",
      "content_html": "<p>Today I launch the beta for something I&#39;ve been trying to build since ~2014. React, Rails, Clojure all failed. LLMs finally made it work.</p><p>Coeus: local-first desktop app for your Markdown notes. Point it at a folder, ask questions, get answers from what you wrote. <a href=\"https://mastodon.social/tags/pkm\" rel=\"noopener noreferrer\">#<span>pkm</span></a></p><p>Bring your own AI. Runs fully offline with Ollama or LM Studio.</p><p>Also captures URLs, YouTube transcripts, PDFs, and audio.</p><p>Tell me what breaks and what you wish it did.</p><p>Real beta. macOS + Linux. Free.</p><p><a href=\"https://usecoeus.com/\" rel=\"noopener noreferrer\"><span>https://</span><span>usecoeus.com</span><span></span></a></p>",
      "date_published": "2026-04-14T16:53:01.971Z",
      "tags": [
        "pkm"
      ]
    },
    {
      "id": "https://digitalknk.com/posts/2026/03/26/116292732849331410",
      "url": "https://digitalknk.com/posts/2026/03/26/116292732849331410",
      "content_html": "<p>I built a small tool to help me keep track of tasks, notes, and everything in my head while working on something else.<br>Somehow that tool ended up being more useful than the actual thing I was trying to build.<br>Didn’t expect that.</p>",
      "date_published": "2026-03-26T00:51:20.057Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/02/22/116111523694563646",
      "url": "https://digitalknk.com/posts/2026/02/22/116111523694563646",
      "content_html": "<p><span><a href=\"https://mastodon.social/@Tekchip\" rel=\"noopener noreferrer\">@<span>Tekchip</span></a></span> <span><a href=\"https://noc.social/@litchralee\" rel=\"noopener noreferrer\">@<span>litchralee</span></a></span> yeah that’s right the documentation shifted. It’s the freq that you will more than likely have to change over. For example if you check out the wcmesh.com website they will should you what to change. I don’t know your area but searching your area with mesh core in google could bring something up, but I might be stating the obvious to you there :-D</p>",
      "date_published": "2026-02-22T00:47:27.793Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/02/22/116111486819201440",
      "url": "https://digitalknk.com/posts/2026/02/22/116111486819201440",
      "content_html": "<p><span><a href=\"https://mastodon.social/@Tekchip\" rel=\"noopener noreferrer\">@<span>Tekchip</span></a></span> Have you checked if your area has a different configuration for the radio? I am in Southern California and they have a different config than the default US config for meshcore. Are you using any tools or sites to looks up the nodes or your device?</p><p>Also I think there is a bridge or there is one in develop but it’s kinda been frowned upon right now.</p>",
      "date_published": "2026-02-22T00:38:05.110Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/02/21/116111260495633829",
      "url": "https://digitalknk.com/posts/2026/02/21/116111260495633829",
      "content_html": "<p>I didn&#39;t know Eric Dane had ALS until today. He passed away on February 19th. Netflix released this video at his request. It is beautiful, sad, and inspiring. It will bring you to tears. Those tears prove you&#39;re listening. My question to myself and maybe to you: what will you do with what you just heard?</p><p><a href=\"https://www.youtube.com/watch?v=sEMpdwdVpng\" rel=\"noopener noreferrer\"><span>https://www.</span><span>youtube.com/watch?v=sEMpdwdVpng</span><span></span></a></p>",
      "date_published": "2026-02-21T23:40:31.687Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/02/18/116089122270294136",
      "url": "https://digitalknk.com/posts/2026/02/18/116089122270294136",
      "content_html": "<p>🧠 go burrr … after about 13 years I am finally working on a new project that could be life changing (for some). Feels like the good ol’ days 😄</p>",
      "date_published": "2026-02-18T01:50:29.175Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/02/09/116042503414542473",
      "url": "https://digitalknk.com/posts/2026/02/09/116042503414542473",
      "content_html": "<p>Really digging this track right now: <a href=\"https://link.deezer.com/s/32paBpqiYkoUM0l88WWhW\" rel=\"noopener noreferrer\"><span>https://</span><span>link.deezer.com/s/32paBpqiYkoU</span><span>M0l88WWhW</span></a></p>",
      "date_published": "2026-02-09T20:14:41.928Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/02/07/116031441677894922",
      "url": "https://digitalknk.com/posts/2026/02/07/116031441677894922",
      "content_html": "<p>I wrote up how I actually run OpenClaw after a few months of real use.</p><p>No hype, no magic. Just how I keep costs predictable, avoid loops, and make it useful day to day.</p><p>If you’re past the “wow” phase and trying to make it boring and reliable: <a href=\"https://gist.github.com/digitalknk/ec360aab27ca47cb4106a183b2c25a98\" rel=\"noopener noreferrer\"><span>https://</span><span>gist.github.com/digitalknk/ec3</span><span>60aab27ca47cb4106a183b2c25a98</span></a></p>",
      "date_published": "2026-02-07T21:21:33.184Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2026/01/15/115898607966122040",
      "url": "https://digitalknk.com/posts/2026/01/15/115898607966122040",
      "content_html": "<p>What is you favorite mastodon client on macOS and iOS?</p>",
      "date_published": "2026-01-15T10:20:11.596Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2023/06/04/110487655396992467",
      "url": "https://digitalknk.com/posts/2023/06/04/110487655396992467",
      "content_html": "<p>OH: Dipping fries in a milk shake/frosty is life changing.</p><p>IMHO I think it’s over rated. 🤷‍♂️ Never really understood the fascination with doing that and thought it was more of a “join the club” type of thing.</p>",
      "date_published": "2023-06-04T19:43:47.713Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2023/04/05/110144605238459940",
      "url": "https://digitalknk.com/posts/2023/04/05/110144605238459940",
      "content_html": "<p>Look what I got in the mail today 😊 🐬 <a href=\"https://mastodon.social/tags/FlipperZero\" rel=\"noopener noreferrer\">#<span>FlipperZero</span></a></p>",
      "date_published": "2023-04-05T05:41:37.708Z",
      "tags": [
        "FlipperZero"
      ]
    },
    {
      "id": "https://digitalknk.com/posts/2023/03/01/109949040672587640",
      "url": "https://digitalknk.com/posts/2023/03/01/109949040672587640",
      "content_html": "<p><span><a href=\"https://infosec.exchange/@code_munkee\" rel=\"noopener noreferrer\">@<span>code_munkee</span></a></span></p>",
      "date_published": "2023-03-01T16:46:59.252Z",
      "tags": []
    },
    {
      "id": "https://digitalknk.com/posts/2023/01/20/109723795638296857",
      "url": "https://digitalknk.com/posts/2023/01/20/109723795638296857",
      "content_html": "<p><a href=\"https://mastodon.social/tags/TIL\" rel=\"noopener noreferrer\">#<span>TIL</span></a> that GitHub supports subversion <a href=\"https://github.blog/2023-01-20-sunsetting-subversion-support/\" rel=\"noopener noreferrer\"><span>https://</span><span>github.blog/2023-01-20-sunsett</span><span>ing-subversion-support/</span></a></p>",
      "date_published": "2023-01-20T22:04:12.783Z",
      "tags": [
        "til"
      ]
    },
    {
      "id": "https://digitalknk.com/posts/2022/11/26/109411860288787159",
      "url": "https://digitalknk.com/posts/2022/11/26/109411860288787159",
      "content_html": "<p>Did my monthly updates to my servers, and somehow my Grafana dashboards disappeared. Did not expect that but hey thank goodness for backups 😜 that’s why it’s important to make them.</p>",
      "date_published": "2022-11-26T19:54:57.085Z",
      "tags": []
    }
  ]
}