plan-forge security.instructions.md

Security rules for code that accepts input, runs commands, handles secrets, or changes a user's repository.

In plain words
What is it for?
They help developers validate inputs, run commands safely, protect credentials, and control how tools modify project files.
Why use it?
They reduce risks such as command injection, where crafted input causes an unintended shell command to run, and accidental exposure of secrets.

Instructions file for GitHub Copilot

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/srnichols/plan-forge/security
Clone the repo
git clone --depth 1 https://github.com/srnichols/plan-forge

Made for: GitHub Copilot.

Per session 2,080 This file is loaded in full into every session.
When invoked 2,080 The same file — it is already loaded in full.
Security scan B 2 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.02080 $0.02080
Opus 5 $0.01040 $0.01040
Sonnet 5 $0.00416 $0.00416
Haiku 4.5 $0.00208 $0.00208

Measured 2d ago against content hash a8a648b98822, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade B, and why

plan-forge security.instructions.md scanned grade B with 2 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Recursive force deletemediumDestructive command

rm -rf with a variable or a broad path is one typo away from removing the wrong tree.

`userTitle = '"; rm -rf ~ #'` exploits the `exec` form. The `spawn` form passes it as a literal title containing punctuation.

Downgraded: this mod is about security review, or the phrase is quoted, so it is likely naming the pattern rather than instructing it.

Runs shell commandslowCapability

Expected in a hook, worth knowing in a rule or an instructions file.

import { spawn } from 'node:child_process';
.github/instructions/security.instructions.md · 161 lines

How it starts

The opening of the file, as written. The whole thing — 161 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Security Instructions

Plan Forge runs with the user's full shell privileges and orchestrates writes into the user's repository. Every forge_* tool handler, every CLI command, every spawn, and every file write is a security boundary. This file rules the boundaries.


The 6 Rules

1. Use spawn(cmd, [arg, arg]) — never exec(stringWithInput)

exec parses its argument as a shell command. Any user-supplied substring becomes a shell injection vector. spawn with an args array passes each argument literally to the kernel, no shell involved.

// ✅ correct
import { spawn } from 'node:child_process';
const child = spawn('gh', ['issue', 'create', '--title', userTitle, '--body', userBody]);

// ❌ injection vector
import { exec } from 'node:child_process';
exec(`gh issue create --title "${userTitle}" --body "${userBody}"`);

userTitle = '"; rm -rf ~ #' exploits the exec form. The spawn form passes it as a literal title containing punctuation.

Same rule applies to spawnSync, execFile, and PowerShell Start-Process / Invoke-Expression. Use args arrays. If you need shell features (pipes, redirects), pipe the data in code, not via the shell.

2. No eval, no new Function(string), no dynamic require(userInput)

These accept code from a string and execute it. There is no input value sanitisation that makes this safe.

Common smells caught at review:

  • eval(json) — use JSON.parse(json)
  • new Function('return ' + expr) — use a parser library or a small DSL
  • require(path.join(userDir, file)) — use import() with a validated allowlist of paths

3. Validate input at the forge_* handler boundary

Every MCP tool handler is a system boundary. Validate before doing any work:

function handle_forge_thing({ projectPath, mode }) {
  if (typeof projectPath !== 'string' || !projectPath) {
    return { ok: false, error: 'projectPath required' };
  }
  if (mode !== 'fast' && mode !== 'thorough') {
    return { ok: false, error: 'mode must be "fast" or "thorough"' };
  }
  const resolved = path.resolve(projectPath);
  if (!resolved.startsWith(allowedRoot)) {
    return { ok: false, error: 'projectPath escapes allowed root' };
  }
  // ...real work below this line
}

Read the full file on GitHub · 161 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 161 lines · 2,080 tokens per session scan B a8a648b98822

Subscribe to this mod's changes

plan-forge security.instructions.md is an instructions file published in the GitHub repository srnichols/plan-forge (5 stars, last pushed 21d ago), licensed MIT. It adds 2,080 tokens to every session, about $0.0104 per session on Opus 5. A static security scan graded it B with 2 findings (recursive force delete, runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other instructions, from other repositories

dotnet-skills AGENTS.md

Instructions for managedcode/dotnet-skills, covering agents.md, purpose, solution topology, rule precedence and path and linking rules.

managedcode/dotnet-skills · 13,592 tokens

dotnet-skills copilot-instructions.md

Instructions for managedcode/dotnet-skills: Use AGENTS.md as the repository-wide source of truth for workflow, catalog structure, release policy, and skill maintenance rules.

managedcode/dotnet-skills · 97 tokens

Perigon.CLI copilot-instructions.md

Instructions for AterDev/Perigon.CLI, covering github copilot instructions, general guidelines, 技术栈, 项目结构与分层 and 代码风格约定.

AterDev/Perigon.CLI · 1,254 tokens

copilot-instructions copilot-instructions.md

Instructions for SebastienDegodez/copilot-instructions, covering copilot instructions, language policy, development code generation and workflow implementation.

SebastienDegodez/copilot-instructions · 364 tokens

maf-doctor maf-deployment.instructions.md

Always-loaded production-deployment patterns for MAF 1.3.0. Auto-applies to Program.cs, DI registration files, and infra config. Covers ManagedIdentityCredential, MaxTokens caps, secret handling, OpenTelemetry wiring, and the analyzer rules that catch regressions at write time.

joslat/maf-doctor · 1,884 tokens

maf-doctor copilot-instructions.md

Instructions for joslat/maf-doctor, covering maf 1.3.0 migration — auto-loaded constraints, maf 1.3.0 — constraints & breaking changes reference, hard constraints (never violate), fan-out / fan-in rules (silent failure risk) and key breaking changes.

joslat/maf-doctor · 1,604 tokens