When an agent skill runs a helper script, keep filenames and other supplied values separate from the command’s executable structure. Prefer the runner’s documented argument interface when it provides one, then verify how the helper interprets those arguments and which files it can access. “Put the filename into this command” leaves several decisions unresolved.
For a team maintaining a reusable SKILL.md workflow, the practical question is what happens when the next input contains spaces, punctuation or a leading dash. A command example that works for report.csv may conceal assumptions that fail with ordinary business filenames. This guide proposes a review method using a fictional reporting skill. We have not installed the skill, executed its helper or tested an assistant product.
Follow the value through each interpreter
The Agent Skills script-authoring guide describes workflows that reference bundled scripts and explains how to design their interfaces. It supports making the invocation explicit. It does not establish that every assistant exposes the same execution API, shell or working directory.
Trace a supplied value through the actual path: conversation, instruction substitution, command runner, optional shell, helper argument parser and file operation. A value can be preserved at one boundary and reinterpreted at the next. A visible command preview does not necessarily show what argument values the child process received.
Our recommendation is to identify the executable, helper location, supported options and data values separately in the skill’s invocation contract. Ask the developer to document which layer parses each part. Do not assume that a quoted placeholder in Markdown remains correctly quoted after an assistant or wrapper constructs the final command.
The existing guide to giving skill scripts a clear contract covers what a helper accepts and returns. Here the additional question is how those values reach the helper without changing the operation the workflow intended.
Distinguish an argument vector from command text
Python’s subprocess documentation describes argument sequences and explains that the library does not implicitly select a system shell. If a shell is explicitly invoked, quoting and escaping become the caller’s responsibility. It also identifies a Windows batch-file exception, where operating-system behavior can introduce shell parsing.
For the fictional example, imagine a reviewed Python helper that reads one approved CSV and writes a local summary. The following JSON notation describes an intended argument vector, not a shell command to paste or a tested implementation:
[
"python3",
"scripts/summarize.py",
"--input",
"Team data/April [draft].csv",
"--output",
"Results/April summary.json"
]
The interpreter must be the approved runtime in the target environment, and the helper path must resolve to the reviewed package file. The input path is one value, despite its space and brackets. It is not a request to split words or expand a filename pattern.
A runner that accepts an executable and separate arguments can preserve that structure. A runner accepting only shell text requires a different implementation and platform-specific review. Serializing the array as JSON and inserting that text into a shell is not equivalent to using an argument-vector interface. JSON string escaping serves a different parser.
Keep this distinction in SKILL.md. State the supported invocation route and required environment rather than presenting a command as portable across every assistant. If the available runner cannot meet the required contract, report the limitation instead of improvising a new command structure.
Check program options as well as shell interpretation
OWASP’s command-injection guidance recommends avoiding OS commands where a suitable library API exists. Where commands are needed, it discusses separation of command and data alongside validation. It also distinguishes argument injection: a supplied argument can change the called program’s behavior even without starting an additional shell command.
For example, a filename beginning with a dash may be interpreted as an option by the helper’s parser. Keeping it in one argument does not decide whether the parser treats it as a filename. Inspect the actual interface. Depending on the tool, a documented end-of-options marker, an explicit option-value form or a validated resolved path may be appropriate. Do not assume one technique works for every parser or wrapper.
Keep supported flags fixed for the fictional reporting task. A request to summarize an input file should not cause the assistant to append unrelated mode switches, choose a different executable or add a remote destination. Any legitimate expansion of the workflow needs its own defined behavior and authority.
Use harmless filenames to expose the assumptions
The following are proposed test cases for the fictional skill. They are not executed results or a security certification. Use synthetic files and an isolated test area rather than sensitive business data.
| Supplied value or condition | What to inspect | Expected contract decision |
|---|---|---|
April.csv | Baseline input received by the helper | One intended input file |
Team data/April [draft].csv | Spaces and brackets at each parsing layer | One literal path, without pattern expansion |
April's notes.csv | Quote handling by the actual runner | Preserve the filename or reject clearly under a documented policy |
April;notes.csv | Punctuation in the received argument | Treat as filename data, not an extra operation |
-notes.csv | Helper option parsing | Use its supported filename mechanism or return a defined rejection |
| Empty value | Missing-input handling | No substitution of a convenient default file |
| Path outside the approved input area | File-access enforcement | Reject under the task’s access policy |
| Existing output file | Overwrite behavior | Follow the explicit output policy rather than silently replacing it |
Observe the arguments arriving at a harmless test helper and then test the real helper’s parser and permitted file effects. A test double can show that a launcher preserved one string; it cannot establish that the production helper subsequently used that value correctly.
Avoid silently renaming inputs to make a command pass. Removing punctuation can change identity or create collisions with another file. If a workflow requires restricted names, state that requirement and return a clear error. Otherwise, support the legitimate names the business process actually uses.
Keep file access separate from argument handling
Correct argument delivery is not a filesystem sandbox. A path can arrive unchanged and still point to a file the task was never authorized to read. Likewise, a permitted input does not authorize overwriting an unrelated output.
Define the approved input and output scope at the layer that performs file access. The implementation needs to account for its real filesystem behavior, including links and changes during execution where relevant; a simplistic path-string prefix check is not a complete access-control design. Review that mechanism with the developer responsible for the environment.
Inspect the helper too. A launcher can avoid a shell while a helper later constructs a shell command internally. Follow the value to the final operation rather than stopping the review at the first process boundary. The skill’s instructions should describe what happens on an invalid path, parser rejection or denied write without encouraging the assistant to bypass that failure.
Preserve the wider security boundary
Skill-Inject, in its February 2026 revision, evaluates agents following malicious instructions embedded in skill files while measuring legitimate task completion. Its threat model is broader than accidental filename interpretation. The authors note limits from the finite skills, tasks and agent implementations evaluated.
That research does not validate an argument-passing pattern or show that escaping makes an arbitrary skill trustworthy. A malicious instruction can request an unwanted operation directly. Review skill provenance, executable code and action authority separately; our third-party skill installation guide covers that earlier decision.
For a real deployment, keep a small invocation record: skill and helper versions, runner API, operating system, approved runtime, parser behavior and tests actually performed. Record whether checks covered argument delivery only or the complete helper operation. Product compatibility and security remain unverified wherever execution evidence is missing.
Start with one helper that processes local, non-sensitive fixtures. Verify that the intended file remains one data value, the parser cannot silently select another operation, and file access stays within the agreed task. Those are distinct checks worth preserving when the skill’s command example changes.