agentleFS
derrickmehaffyderrickmehaffy/brain-template/.claude/skills/brain-write-script/SKILL.md

brain-write-script

Skill2 starsChanged 12 days agoMITView on GitHub

Write or change a script in this brain's scripts/ when a query or API call is worth keeping instead of regenerating, or a system needs probing, or connect a system through an MCP server in .mcp.json. Places it by the system it touches, keeps it read-only unless its name says otherwise, takes secrets from the environment, probes the system first and records what it can and cannot do in docs/CAPABILITIES.md, and adds tests. Use when you are about to write a query you have written before, when a system should be reached through an MCP server, or when the skill gate refuses a write under scripts/ or to .mcp.json. Does NOT write skills, which is brain-write-skill; does NOT record a fact, which is brain-write-practice; and does NOT change _meta/, which is brain-upstream.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

11 rules. About 0 are common, 2 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Look first in ./scripts/ and docs/CAPABILITIES.md: changing a script beats writing a second one.

    line 39
  2. Distinctive:

    When the system has an MCP server that already does the job, connecting it can beat a script: see "An MCP server" below.

    line 40
  3. Very specific:

    Read docs/CAPABILITIES.md: the answer may be there, dated.

    line 45
  4. Very specific:

    Read references/conventions.md.

    line 63
  5. Very specific:

    No absolute or home path. Find the brain root by walking up from __file__ to brain.json: the brain is cloned on more than one machine, and …

    line 67
  6. Very specific:

    Read-only unless the name says otherwise: no code path that writes, and every request through one function that refuses anything but a read.

    line 69
  7. Distinctive:

    Run another program with an argument list, never a shell string: a path with a space breaks it.

    line 85
  8. Very specific:

    Follow brain.json scripts.packages: stdlib-only means the standard library and nothing else.

    line 86
  9. Very specific:

    Add or update the system's row in docs/CAPABILITIES.md, in the format references/conventions.md gives: what it can do, what it cannot, the …

    line 102
  10. Very specific:

    When brain.json role is template, a harness change in _meta/ that template-intake accepted is written here, following the template's …

    line 128
  11. Very specific:

    No secret is in the script, its arguments or any output.

    line 140

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

brain-write-script

A query, probe or API call worth keeping becomes a file: placed by the system it touches, read-only unless its name says otherwise, secrets from the environment, tested, and backed by a dated row in docs/CAPABILITIES.md. Paths are from the brain root: ./scripts/ is the brain's, not this skill's.

Where this sits

<!-- where:begin — generated by _meta/brain routing sync; do not edit -->

Runs after: brain-setup · brain-write-mod · brain-write-skill

Hand to next: brain-sync

Reserved output: writing .mcp.json needs this skill to have run.

Reserved output: writing docs/CAPABILITIES.md needs this skill to have run.

Reserved output: writing scripts/** needs this skill to have run.

<!-- where:end -->

Call it directly when: you are about to write a query or API call you have written before, a system should be reached through an MCP server, or the gate refused a write under ./scripts/, to docs/CAPABILITIES.md or to .mcp.json; nothing has to run first.

1. Does it earn a file?

Make it a file when any one of these holds; otherwise run it inline and carry on:

  • you have written it, or something close to it, before;
  • it encodes a non-obvious fact about a system (a paging quirk, a field's real units);
  • it touches data that matters (a live config, save files, a release, someone else's data);
  • it took minutes to work out.

Look first in ./scripts/ and docs/CAPABILITIES.md: changing a script beats writing a second one. When the system has an MCP server that already does the job, connecting it can beat a script: see "An MCP server" below.

2. Probe before writing logic

Read docs/CAPABILITIES.md: the answer may be there, dated. Otherwise find out what the system really does, with reads only (its version, its --help, one request with the script's own access), after reading the rules that bite in CLAUDE.md. Note what failed or is missing as carefully as what worked: a dated negative stops the next session walking into the same wall. If finding out would need a write, do not try it; record it as not tried, and why.

3. Place and name it

  • ./scripts/<system>/: one folder per system it touches, named as a Python identifier (hypervisor, mod_loader, files) that no imported module already has, with an __init__.py.
  • ./scripts/common/: code that two or more systems share, starting with the .env loader.
  • A skill's own scripts/ folder only when that skill is the sole caller (the gate then also wants brain-write-skill).
  • Name it for what it does (list_vms.py), and start the name apply_, write_ or delete_ exactly when it changes something, so the name alone says whether running it is safe.

4. Write it

Read references/conventions.md; copy its docstring, root finding, .env loader and read-only guard.

  • The docstring opens WHY THIS EXISTS: with the question it answers or the fact it encodes: that line is how the next session decides to reuse the script instead of writing another.
  • No absolute or home path. Find the brain root by walking up from __file__ to brain.json: the brain is cloned on more than one machine, and a home path leaks a username into git.
  • Read-only unless the name says otherwise: no code path that writes, and every request through one function that refuses anything but a read. A script that does change things shows what it would change and changes nothing without --apply. Never run it, or anything destructive, unless the person asked for that run.
  • Secrets come from the environment through the loader in ./scripts/common/env.py, which reads .env itself: you are denied reading .env, deliberately. A value there may be an op:// 1Password reference, which the loader reads with op read. Never take a secret as an argument (argv shows in ps, shell history and this transcript), never print one, and pass any output that could echo one (an error body, a URL, an exception) through env.redact first.
  • A private endpoint (hostname, internal address) is configuration: take it from the environment too.
  • Anything that is not one of these scripts (a CLI tool, an MCP server, a one-off command) gets its secrets through _meta/brain secret run KEY[,KEY] COMMAND [ARG...]: the loader's rules, and the values go only into that command's environment.
  • A new secret name: _meta/brain env-sync --add KEY, then _meta/brain env-sync --open, which opens .env in the person's text editor to paste the value after the =. Never ask for a value in the chat. _meta/brain env-sync --list shows which are set; never read, write or print a value.
  • Run another program with an argument list, never a shell string: a path with a space breaks it.
  • Follow brain.json scripts.packages: stdlib-only means the standard library and nothing else; allowed means a third-party package that earns its place, named in the docstring.

5. Test it

Tests go in ./scripts/tests/test_<system>_<name>.py. Cover the logic (parsing, paging, the decision the script makes) and the refusal paths (a missing secret, a write refused, a secret kept out of the output), never the network: fake the reply. Every read-only script has a test asserting it only reads. Run them from the brain root under the interpreter brain.json scripts.python names:

<scripts.python> -m unittest discover -s ./scripts/tests -t ./scripts

6. Record and hand on

Add or update the system's row in docs/CAPABILITIES.md, in the format references/conventions.md gives: what it can do, what it cannot, the day the probe ran (today if you probed; never move the date without a check), and how you checked; never a secret or a hostname. Then hand to brain-sync, which runs the checks and commits.

An MCP server

A system with a usable MCP server can be connected instead of scripted. A server only this brain needs goes in the brain's .mcp.json, never in the person's user settings, where every session in every folder would load its tools. Probe it as in step 2: list its tools, call only ones that read, and note which of them write. Declare it with its secrets through secret run, because ${VAR} in .mcp.json reads the environment Claude Code started in, never .env:

{"mcpServers": {"<system>": {"command": "sh", "args": ["-c",
  "exec \"$CLAUDE_PROJECT_DIR/_meta/brain\" secret run SYSTEM_TOKEN <server command> <arg>"]}}}

sh -c because Claude Code sets CLAUDE_PROJECT_DIR in the server's environment but does not expand it in .mcp.json, and does not promise the server's working directory. A remote server that needs a token runs the same way through a local bridge command. Then record its docs/CAPABILITIES.md row as in step 6, its tools that write under Can, and hand to brain-sync. The person approves a project server the first time Claude Code starts it.

In the template

When brain.json role is template, a harness change in _meta/ that template-intake accepted is written here, following the template's CLAUDE.md. Steps 3 and 6 and their Done-when lines do not apply; the template's tests pass.

Done when

  • The script is in ./scripts/<system>/, ./scripts/common/ or its sole caller's scripts/, and its name starts apply_, write_ or delete_ if and only if it changes something.
  • Its docstring opens WHY THIS EXISTS:, and it names no absolute or home path.
  • Tests for its logic and refusal paths, including one asserting it only reads when it is read-only, pass under scripts.python.
  • docs/CAPABILITIES.md has the system's row, dated the day the probe ran, with what it cannot do.
  • No secret is in the script, its arguments or any output; new names went in through env-sync --add.
  • An MCP server is in .mcp.json with its secrets through secret run, and its CAPABILITIES row names the tools that write.
  • Handed to brain-sync.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.