guardrails-ref 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/cli.js +14 -7
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +59 -1
- package/dist/templates.d.ts +0 -3
- package/dist/templates.js +53 -164
- package/examples/database-migrations/GUARDRAIL.md +33 -0
- package/examples/no-console-in-production/GUARDRAIL.md +34 -0
- package/examples/no-destructive-commands/GUARDRAIL.md +37 -0
- package/examples/no-hardcoded-urls/GUARDRAIL.md +32 -0
- package/examples/no-new-deps-without-approval/GUARDRAIL.md +35 -0
- package/examples/no-plaintext-secrets/GUARDRAIL.md +33 -0
- package/examples/no-sudo-commands/GUARDRAIL.md +34 -0
- package/examples/rate-limiting/GUARDRAIL.md +33 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -17,8 +17,8 @@ No global install needed. Or: `npm install -g guardrails-ref`
|
|
|
17
17
|
| `npx guardrails-ref init [path]` | Create `.agents/guardrails/`, add no-plaintext-secrets, configure Cursor and Claude Code |
|
|
18
18
|
| `npx guardrails-ref add <name> [path]` | Add an example guardrail (e.g. no-destructive-commands, database-migrations) |
|
|
19
19
|
| `npx guardrails-ref remove <name> [path]` | Remove a guardrail from .agents/guardrails/ |
|
|
20
|
-
| `npx guardrails-ref setup [path]` | Add the guardrail rule to Cursor rules and Claude instructions |
|
|
21
|
-
| `npx guardrails-ref validate [path]` | Validate GUARDRAIL.md files (use `--json` for JSON
|
|
20
|
+
| `npx guardrails-ref setup [path]` | Add the guardrail rule to Cursor rules and Claude instructions (use `--remove` to undo) |
|
|
21
|
+
| `npx guardrails-ref validate [path]` | Validate GUARDRAIL.md files (use `--json` for JSON, `--strict` to fail on warnings) |
|
|
22
22
|
| `npx guardrails-ref list [path]` | List discovered guardrails (use `--json` for JSON output) |
|
|
23
23
|
|
|
24
24
|
## Examples
|
|
@@ -37,6 +37,8 @@ npx guardrails-ref list .
|
|
|
37
37
|
- `database-migrations` — Always use migration files
|
|
38
38
|
- `no-destructive-commands` — No rm -rf, DROP, TRUNCATE without approval
|
|
39
39
|
- `no-new-deps-without-approval` — No new packages without approval
|
|
40
|
+
- `no-hardcoded-urls` — No hardcoded API URLs, base URLs, endpoints
|
|
41
|
+
- `no-sudo-commands` — No sudo/su/root commands without approval
|
|
40
42
|
- `rate-limiting` — Limit tool calls and API loops
|
|
41
43
|
- `no-console-in-production` — No console.log in production code
|
|
42
44
|
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { program } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { validatePath, listGuardrails } from "./validate.js";
|
|
5
|
-
import { runSetup } from "./setup.js";
|
|
5
|
+
import { runSetup, runSetupRemove } from "./setup.js";
|
|
6
6
|
import { runInit } from "./init.js";
|
|
7
7
|
import { runAdd } from "./add.js";
|
|
8
8
|
import { runRemove } from "./remove.js";
|
|
@@ -14,8 +14,10 @@ program
|
|
|
14
14
|
.command("validate [path]")
|
|
15
15
|
.description("Validate GUARDRAIL.md files in a directory or a single file")
|
|
16
16
|
.option("-j, --json", "Output as JSON")
|
|
17
|
-
.
|
|
17
|
+
.option("-s, --strict", "Fail on warnings (CI mode)")
|
|
18
|
+
.action((path = ".", options = {}) => {
|
|
18
19
|
const result = validatePath(path);
|
|
20
|
+
const hasWarnings = result.results.some((r) => r.warnings.length > 0);
|
|
19
21
|
if (options.json) {
|
|
20
22
|
const json = {
|
|
21
23
|
valid: result.valid,
|
|
@@ -29,7 +31,8 @@ program
|
|
|
29
31
|
})),
|
|
30
32
|
};
|
|
31
33
|
console.log(JSON.stringify(json, null, 2));
|
|
32
|
-
|
|
34
|
+
const exitCode = result.invalid > 0 || (options.strict && hasWarnings) ? 1 : 0;
|
|
35
|
+
process.exit(exitCode);
|
|
33
36
|
return;
|
|
34
37
|
}
|
|
35
38
|
let hasErrors = false;
|
|
@@ -59,7 +62,8 @@ program
|
|
|
59
62
|
console.log();
|
|
60
63
|
console.log(`Valid: ${result.valid}/${result.total} Invalid: ${result.invalid}/${result.total}`);
|
|
61
64
|
}
|
|
62
|
-
|
|
65
|
+
const strictFail = options.strict && hasWarnings;
|
|
66
|
+
process.exit(hasErrors || strictFail ? 1 : 0);
|
|
63
67
|
});
|
|
64
68
|
program
|
|
65
69
|
.command("init [path]")
|
|
@@ -69,7 +73,7 @@ program
|
|
|
69
73
|
});
|
|
70
74
|
program
|
|
71
75
|
.command("add <name> [path]")
|
|
72
|
-
.description("Add an example guardrail by name (e.g. no-destructive-commands, no-
|
|
76
|
+
.description("Add an example guardrail by name (e.g. no-destructive-commands, no-hardcoded-urls, no-sudo-commands)")
|
|
73
77
|
.action((name, path = ".") => {
|
|
74
78
|
const ok = runAdd(name, path);
|
|
75
79
|
process.exit(ok ? 0 : 1);
|
|
@@ -84,8 +88,11 @@ program
|
|
|
84
88
|
program
|
|
85
89
|
.command("setup [path]")
|
|
86
90
|
.description("Add the guardrail one-liner to Cursor rules and Claude instructions (required until IDEs support guardrails natively)")
|
|
87
|
-
.
|
|
88
|
-
|
|
91
|
+
.option("-r, --remove", "Remove the guardrail rule from Cursor and Claude config")
|
|
92
|
+
.action((path, cmd) => {
|
|
93
|
+
const p = path ?? ".";
|
|
94
|
+
const opts = cmd?.opts?.() ?? {};
|
|
95
|
+
const result = opts.remove ? runSetupRemove(p) : runSetup(p);
|
|
89
96
|
console.log(result.message);
|
|
90
97
|
});
|
|
91
98
|
program
|
package/dist/setup.d.ts
CHANGED
package/dist/setup.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from "fs";
|
|
2
2
|
import { resolve } from "path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
const GUARDRAIL_RULE = "You MUST read and follow all constraints in .agents/guardrails/. Never violate a guardrail without explicit human approval.";
|
|
5
5
|
const GUARDRAIL_RULE_MARKER = "read and follow all constraints in .agents/guardrails";
|
|
6
|
+
function removeRuleFromContent(content) {
|
|
7
|
+
const lines = content.split("\n").filter((line) => !line.includes(GUARDRAIL_RULE_MARKER));
|
|
8
|
+
return lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
9
|
+
}
|
|
6
10
|
function hasRule(content) {
|
|
7
11
|
return content.includes(GUARDRAIL_RULE_MARKER);
|
|
8
12
|
}
|
|
@@ -79,3 +83,57 @@ ${GUARDRAIL_RULE}
|
|
|
79
83
|
message: messages.join("\n"),
|
|
80
84
|
};
|
|
81
85
|
}
|
|
86
|
+
export function runSetupRemove(projectPath = ".") {
|
|
87
|
+
const root = resolve(projectPath);
|
|
88
|
+
let cursorDone = false;
|
|
89
|
+
let claudeDone = false;
|
|
90
|
+
const cursorRulesDir = resolve(root, ".cursor", "rules");
|
|
91
|
+
const cursorRuleFile = resolve(cursorRulesDir, "agent-guardrails.md");
|
|
92
|
+
const cursorrulesPath = resolve(root, ".cursorrules");
|
|
93
|
+
const claudeInstructions = resolve(root, ".claude", "instructions.md");
|
|
94
|
+
if (existsSync(cursorRuleFile)) {
|
|
95
|
+
rmSync(cursorRuleFile);
|
|
96
|
+
cursorDone = true;
|
|
97
|
+
}
|
|
98
|
+
if (existsSync(cursorrulesPath)) {
|
|
99
|
+
const existing = readFileSync(cursorrulesPath, "utf-8");
|
|
100
|
+
if (hasRule(existing)) {
|
|
101
|
+
const cleaned = removeRuleFromContent(existing);
|
|
102
|
+
if (cleaned) {
|
|
103
|
+
writeFileSync(cursorrulesPath, cleaned + "\n");
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
rmSync(cursorrulesPath);
|
|
107
|
+
}
|
|
108
|
+
cursorDone = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (existsSync(claudeInstructions)) {
|
|
112
|
+
const existing = readFileSync(claudeInstructions, "utf-8");
|
|
113
|
+
if (hasRule(existing)) {
|
|
114
|
+
const cleaned = removeRuleFromContent(existing);
|
|
115
|
+
if (cleaned) {
|
|
116
|
+
writeFileSync(claudeInstructions, cleaned + "\n");
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
rmSync(claudeInstructions);
|
|
120
|
+
}
|
|
121
|
+
claudeDone = true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const messages = [];
|
|
125
|
+
if (cursorDone) {
|
|
126
|
+
messages.push(chalk.green("✓") + " Removed guardrail rule from Cursor");
|
|
127
|
+
}
|
|
128
|
+
if (claudeDone) {
|
|
129
|
+
messages.push(chalk.green("✓") + " Removed guardrail rule from Claude Code");
|
|
130
|
+
}
|
|
131
|
+
if (messages.length === 0) {
|
|
132
|
+
messages.push(chalk.yellow("Guardrail rule not found in any config files."));
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
cursor: cursorDone,
|
|
136
|
+
claude: claudeDone,
|
|
137
|
+
message: messages.join("\n"),
|
|
138
|
+
};
|
|
139
|
+
}
|
package/dist/templates.d.ts
CHANGED
package/dist/templates.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Load templates from examples/ at runtime. Falls back to bundled templates
|
|
3
|
+
* when examples directory is not available (e.g. edge cases).
|
|
4
|
+
* Single source of truth: agent-guardrails/examples/
|
|
3
5
|
*/
|
|
4
|
-
|
|
6
|
+
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
7
|
+
import { dirname, join } from "path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { parseGuardrailFile } from "./parse.js";
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
/** Bundled fallback when examples/ is not available */
|
|
12
|
+
const BUNDLED = {
|
|
5
13
|
"no-plaintext-secrets": `---
|
|
6
14
|
name: no-plaintext-secrets
|
|
7
15
|
description: Never log, commit, or expose API keys, passwords, or tokens. Use environment variables or secrets managers. Apply when adding logging, implementing auth, or integrating third-party APIs.
|
|
@@ -32,168 +40,49 @@ Implementing authentication endpoints, adding logging, integrating third-party A
|
|
|
32
40
|
|
|
33
41
|
## Reason
|
|
34
42
|
API keys were exposed in git during a 2025 security audit. Plaintext credentials in logs led to emergency key rotation.
|
|
35
|
-
`,
|
|
36
|
-
"database-migrations": `---
|
|
37
|
-
name: database-migrations
|
|
38
|
-
description: Always use migration files for schema changes. Never modify production schema directly. Apply when modifying database schema, adding tables, or changing columns.
|
|
39
|
-
scope: project
|
|
40
|
-
severity: critical
|
|
41
|
-
triggers:
|
|
42
|
-
- "Modifying database schema"
|
|
43
|
-
- "Adding or changing tables"
|
|
44
|
-
- "Database migrations"
|
|
45
|
-
- "Prisma schema"
|
|
46
|
-
- "SQL migrations"
|
|
47
|
-
license: MIT
|
|
48
|
-
metadata:
|
|
49
|
-
author: agent-guardrails
|
|
50
|
-
version: "1.0"
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
# Database Migrations
|
|
54
|
-
|
|
55
|
-
## Trigger
|
|
56
|
-
Modifying database schema, adding tables, changing columns, or optimizing queries that affect schema.
|
|
57
|
-
|
|
58
|
-
## Instruction
|
|
59
|
-
- Always create a migration file (e.g. \`prisma migrate dev\`, \`rails db:migrate\`, or equivalent)
|
|
60
|
-
- Never modify production schema directly without a migration
|
|
61
|
-
- Test migrations in staging before applying to production
|
|
62
|
-
- Require explicit human approval before running migrations in production
|
|
63
|
-
|
|
64
|
-
## Reason
|
|
65
|
-
Direct schema changes caused 4-hour downtime and data inconsistencies. Migrations provide rollback capability and audit trail.
|
|
66
|
-
`,
|
|
67
|
-
"no-destructive-commands": `---
|
|
68
|
-
name: no-destructive-commands
|
|
69
|
-
description: Never run destructive shell commands or SQL without explicit human approval. Apply when deleting files, dropping tables, truncating data, or modifying production.
|
|
70
|
-
scope: project
|
|
71
|
-
severity: critical
|
|
72
|
-
triggers:
|
|
73
|
-
- "Deleting files"
|
|
74
|
-
- "Cleaning up"
|
|
75
|
-
- "Dropping tables"
|
|
76
|
-
- "Truncating data"
|
|
77
|
-
- "Database cleanup"
|
|
78
|
-
- "rm -rf"
|
|
79
|
-
- "DROP TABLE"
|
|
80
|
-
- "TRUNCATE"
|
|
81
|
-
license: MIT
|
|
82
|
-
metadata:
|
|
83
|
-
author: agent-guardrails
|
|
84
|
-
version: "1.0"
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
# No Destructive Commands
|
|
88
|
-
|
|
89
|
-
## Trigger
|
|
90
|
-
Running shell commands that delete files, database commands that drop or truncate data, or any operation that irreversibly removes content.
|
|
91
|
-
|
|
92
|
-
## Instruction
|
|
93
|
-
- Never run \`rm -rf\`, \`rm -r\`, or recursive deletes without explicit human approval
|
|
94
|
-
- Never run \`DROP TABLE\`, \`DROP DATABASE\`, \`TRUNCATE\`, or \`DELETE\` without a WHERE clause on production data without explicit approval
|
|
95
|
-
- For cleanup tasks: propose the command, explain the impact, and wait for confirmation before executing
|
|
96
|
-
- Prefer moving to trash or using \`--dry-run\` when available
|
|
97
|
-
- If the user asks to "delete everything" or "clean slate": stop and confirm scope before proceeding
|
|
98
|
-
|
|
99
|
-
## Reason
|
|
100
|
-
Agents have run \`rm -rf\` on wrong directories and \`DROP TABLE\` in production. Destructive operations must never execute without explicit human confirmation.
|
|
101
|
-
`,
|
|
102
|
-
"no-new-deps-without-approval": `---
|
|
103
|
-
name: no-new-deps-without-approval
|
|
104
|
-
description: Do not add new npm, pip, or other package dependencies without explicit human approval. Apply when installing packages, adding imports, or suggesting new libraries.
|
|
105
|
-
scope: project
|
|
106
|
-
severity: warning
|
|
107
|
-
triggers:
|
|
108
|
-
- "Installing packages"
|
|
109
|
-
- "Adding dependencies"
|
|
110
|
-
- "npm install"
|
|
111
|
-
- "pip install"
|
|
112
|
-
- "New library"
|
|
113
|
-
- "Use package X"
|
|
114
|
-
license: MIT
|
|
115
|
-
metadata:
|
|
116
|
-
author: agent-guardrails
|
|
117
|
-
version: "1.0"
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
# No New Dependencies Without Approval
|
|
121
|
-
|
|
122
|
-
## Trigger
|
|
123
|
-
Adding a new package to package.json, requirements.txt, pyproject.toml, Cargo.toml, or any dependency manifest.
|
|
124
|
-
|
|
125
|
-
## Instruction
|
|
126
|
-
- Before running \`npm install <pkg>\`, \`pip install <pkg>\`, or equivalent: list the package and why it's needed, then ask for approval
|
|
127
|
-
- Prefer using existing project dependencies over adding new ones
|
|
128
|
-
- If a built-in or stdlib solution exists, use it instead of a new dependency
|
|
129
|
-
- When suggesting a new dependency: include package name, purpose, and alternative (e.g. "or we could use the built-in X")
|
|
130
|
-
- Never add dependencies "to fix" a problem without confirming the user wants new packages in the project
|
|
131
|
-
|
|
132
|
-
## Reason
|
|
133
|
-
Uncontrolled dependency growth leads to security risk, bundle bloat, and maintenance burden. Teams want to review what gets added to their lockfile.
|
|
134
|
-
`,
|
|
135
|
-
"rate-limiting": `---
|
|
136
|
-
name: rate-limiting
|
|
137
|
-
description: Limit tool calls and API requests to prevent runaway loops. Max 50 tool calls per session, max 10 per iteration. Stop after 3 consecutive errors.
|
|
138
|
-
scope: session
|
|
139
|
-
severity: warning
|
|
140
|
-
triggers:
|
|
141
|
-
- "Debugging API integrations"
|
|
142
|
-
- "Stripe or payment API calls"
|
|
143
|
-
- "External API calls in loops"
|
|
144
|
-
- "Context window approaching capacity"
|
|
145
|
-
license: MIT
|
|
146
|
-
metadata:
|
|
147
|
-
author: agent-guardrails
|
|
148
|
-
version: "1.0"
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
# Rate Limiting
|
|
152
|
-
|
|
153
|
-
## Trigger
|
|
154
|
-
Debugging API integrations, making repeated external API calls, or when context exceeds 80% capacity or 10+ consecutive errors.
|
|
155
|
-
|
|
156
|
-
## Instruction
|
|
157
|
-
- Max 50 tool calls per session
|
|
158
|
-
- Max 10 tool calls per iteration
|
|
159
|
-
- Stop after 3 consecutive errors and request context rotation
|
|
160
|
-
- For payment APIs (Stripe, etc.): always use test mode when debugging
|
|
161
|
-
- When context exceeds 80% capacity: re-inject GUARDRAILS.md + summary + objective, then reset context
|
|
162
|
-
|
|
163
|
-
## Reason
|
|
164
|
-
Agent debugging Stripe entered an infinite loop of test calls, resulting in 2000+ requests in 30 minutes, $200 API costs, and account suspension.
|
|
165
|
-
`,
|
|
166
|
-
"no-console-in-production": `---
|
|
167
|
-
name: no-console-in-production
|
|
168
|
-
description: Never add console.log, console.debug, or console.info in production code. Use a proper logging library. Apply when adding debugging, logging, or trace statements.
|
|
169
|
-
scope: project
|
|
170
|
-
severity: warning
|
|
171
|
-
triggers:
|
|
172
|
-
- "Adding logging"
|
|
173
|
-
- "Debugging"
|
|
174
|
-
- "console.log"
|
|
175
|
-
- "console.debug"
|
|
176
|
-
- "Trace statements"
|
|
177
|
-
license: MIT
|
|
178
|
-
metadata:
|
|
179
|
-
author: agent-guardrails
|
|
180
|
-
version: "1.0"
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
# No Console in Production
|
|
184
|
-
|
|
185
|
-
## Trigger
|
|
186
|
-
Adding logging, debugging statements, or trace output to application code that ships to production.
|
|
187
|
-
|
|
188
|
-
## Instruction
|
|
189
|
-
- Never add \`console.log\`, \`console.debug\`, or \`console.info\` in production code paths
|
|
190
|
-
- Use a structured logging library (e.g. pino, winston, log4j) with log levels
|
|
191
|
-
- For temporary debugging: use \`console.warn\` or \`console.error\` and add a TODO to remove before merge
|
|
192
|
-
- Strip or gate console calls in production builds when a logger is not available
|
|
193
|
-
- Prefer environment-based log levels (e.g. DEBUG=true) over hardcoded console statements
|
|
194
|
-
|
|
195
|
-
## Reason
|
|
196
|
-
console.log in production leaks sensitive data, clutters logs, and impacts performance. Structured loggers support levels, formatting, and safe redaction.
|
|
197
43
|
`,
|
|
198
44
|
};
|
|
45
|
+
function loadTemplatesFromDir(examplesDir) {
|
|
46
|
+
const templates = {};
|
|
47
|
+
if (!existsSync(examplesDir))
|
|
48
|
+
return templates;
|
|
49
|
+
const entries = readdirSync(examplesDir, { withFileTypes: true });
|
|
50
|
+
for (const ent of entries) {
|
|
51
|
+
if (!ent.isDirectory())
|
|
52
|
+
continue;
|
|
53
|
+
const file = join(examplesDir, ent.name, "GUARDRAIL.md");
|
|
54
|
+
if (!existsSync(file))
|
|
55
|
+
continue;
|
|
56
|
+
try {
|
|
57
|
+
const result = parseGuardrailFile(file);
|
|
58
|
+
if (result.success && result.guardrail) {
|
|
59
|
+
const key = ent.name.toLowerCase().replace(/\s+/g, "-");
|
|
60
|
+
const content = readFileSync(file, "utf-8");
|
|
61
|
+
templates[key] = content;
|
|
62
|
+
}
|
|
63
|
+
else if (result.errors.length > 0) {
|
|
64
|
+
console.warn(`guardrails-ref: skipped ${file}: ${result.errors.join("; ")}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.warn(`guardrails-ref: skipped ${file}: ${err.message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return templates;
|
|
72
|
+
}
|
|
73
|
+
function getTemplates() {
|
|
74
|
+
// Try: 1) guardrails-ref/examples (published pkg), 2) ../examples (repo root when developing)
|
|
75
|
+
const candidates = [
|
|
76
|
+
join(__dirname, "..", "examples"),
|
|
77
|
+
join(__dirname, "..", "..", "examples"),
|
|
78
|
+
];
|
|
79
|
+
for (const examplesDir of candidates) {
|
|
80
|
+
const fromDisk = loadTemplatesFromDir(examplesDir);
|
|
81
|
+
if (Object.keys(fromDisk).length > 0) {
|
|
82
|
+
return fromDisk;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return BUNDLED;
|
|
86
|
+
}
|
|
87
|
+
export const TEMPLATES = getTemplates();
|
|
199
88
|
export const TEMPLATE_NAMES = Object.keys(TEMPLATES);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-migrations
|
|
3
|
+
description: Always use migration files for schema changes. Never modify production schema directly. Apply when modifying database schema, adding tables, or changing columns.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: critical
|
|
6
|
+
triggers:
|
|
7
|
+
- "Modifying database schema"
|
|
8
|
+
- "Adding or changing tables"
|
|
9
|
+
- "Database migrations"
|
|
10
|
+
- "Prisma schema"
|
|
11
|
+
- "SQL migrations"
|
|
12
|
+
license: MIT
|
|
13
|
+
metadata:
|
|
14
|
+
author: agent-guardrails
|
|
15
|
+
version: "1.0"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Database Migrations
|
|
19
|
+
|
|
20
|
+
## Trigger
|
|
21
|
+
Modifying database schema, adding tables, changing columns, or optimizing queries that affect schema.
|
|
22
|
+
|
|
23
|
+
## Instruction
|
|
24
|
+
- Always create a migration file (e.g. `prisma migrate dev`, `rails db:migrate`, or equivalent)
|
|
25
|
+
- Never modify production schema directly without a migration
|
|
26
|
+
- Test migrations in staging before applying to production
|
|
27
|
+
- Require explicit human approval before running migrations in production
|
|
28
|
+
|
|
29
|
+
## Reason
|
|
30
|
+
Direct schema changes caused 4-hour downtime and data inconsistencies. Migrations provide rollback capability and audit trail.
|
|
31
|
+
|
|
32
|
+
## Provenance
|
|
33
|
+
Manual addition, based on guardrails.md case study.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-console-in-production
|
|
3
|
+
description: Never add console.log, console.debug, or console.info in production code. Use a proper logging library. Apply when adding debugging, logging, or trace statements.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: warning
|
|
6
|
+
triggers:
|
|
7
|
+
- "Adding logging"
|
|
8
|
+
- "Debugging"
|
|
9
|
+
- "console.log"
|
|
10
|
+
- "console.debug"
|
|
11
|
+
- "Trace statements"
|
|
12
|
+
license: MIT
|
|
13
|
+
metadata:
|
|
14
|
+
author: agent-guardrails
|
|
15
|
+
version: "1.0"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# No Console in Production
|
|
19
|
+
|
|
20
|
+
## Trigger
|
|
21
|
+
Adding logging, debugging statements, or trace output to application code that ships to production.
|
|
22
|
+
|
|
23
|
+
## Instruction
|
|
24
|
+
- Never add `console.log`, `console.debug`, or `console.info` in production code paths
|
|
25
|
+
- Use a structured logging library (e.g. pino, winston, log4j) with log levels
|
|
26
|
+
- For temporary debugging: use `console.warn` or `console.error` and add a TODO to remove before merge
|
|
27
|
+
- Strip or gate console calls in production builds when a logger is not available
|
|
28
|
+
- Prefer environment-based log levels (e.g. DEBUG=true) over hardcoded console statements
|
|
29
|
+
|
|
30
|
+
## Reason
|
|
31
|
+
console.log in production leaks sensitive data, clutters logs, and impacts performance. Structured loggers support levels, formatting, and safe redaction.
|
|
32
|
+
|
|
33
|
+
## Provenance
|
|
34
|
+
Manual addition, common code quality concern for production applications.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-destructive-commands
|
|
3
|
+
description: Never run destructive shell commands or SQL without explicit human approval. Apply when deleting files, dropping tables, truncating data, or modifying production.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: critical
|
|
6
|
+
triggers:
|
|
7
|
+
- "Deleting files"
|
|
8
|
+
- "Cleaning up"
|
|
9
|
+
- "Dropping tables"
|
|
10
|
+
- "Truncating data"
|
|
11
|
+
- "Database cleanup"
|
|
12
|
+
- "rm -rf"
|
|
13
|
+
- "DROP TABLE"
|
|
14
|
+
- "TRUNCATE"
|
|
15
|
+
license: MIT
|
|
16
|
+
metadata:
|
|
17
|
+
author: agent-guardrails
|
|
18
|
+
version: "1.0"
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# No Destructive Commands
|
|
22
|
+
|
|
23
|
+
## Trigger
|
|
24
|
+
Running shell commands that delete files, database commands that drop or truncate data, or any operation that irreversibly removes content.
|
|
25
|
+
|
|
26
|
+
## Instruction
|
|
27
|
+
- Never run `rm -rf`, `rm -r`, or recursive deletes without explicit human approval
|
|
28
|
+
- Never run `DROP TABLE`, `DROP DATABASE`, `TRUNCATE`, or `DELETE` without a WHERE clause on production data without explicit approval
|
|
29
|
+
- For cleanup tasks: propose the command, explain the impact, and wait for confirmation before executing
|
|
30
|
+
- Prefer moving to trash or using `--dry-run` when available
|
|
31
|
+
- If the user asks to "delete everything" or "clean slate": stop and confirm scope before proceeding
|
|
32
|
+
|
|
33
|
+
## Reason
|
|
34
|
+
Agents have run `rm -rf` on wrong directories and `DROP TABLE` in production. Destructive operations must never execute without explicit human confirmation.
|
|
35
|
+
|
|
36
|
+
## Provenance
|
|
37
|
+
Manual addition, common failure mode in autonomous coding agents.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-hardcoded-urls
|
|
3
|
+
description: Never hardcode API URLs, base URLs, or endpoints. Use environment variables or config. Apply when adding API calls, integrations, or external service URLs.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: warning
|
|
6
|
+
triggers:
|
|
7
|
+
- "API integration"
|
|
8
|
+
- "Adding API calls"
|
|
9
|
+
- "Base URL"
|
|
10
|
+
- "Endpoint"
|
|
11
|
+
- "http://"
|
|
12
|
+
- "https://"
|
|
13
|
+
license: MIT
|
|
14
|
+
metadata:
|
|
15
|
+
author: agent-guardrails
|
|
16
|
+
version: "1.0"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# No Hardcoded URLs
|
|
20
|
+
|
|
21
|
+
## Trigger
|
|
22
|
+
Adding API calls, integrating external services, or referencing URLs (base URLs, endpoints, webhook URLs) in code.
|
|
23
|
+
|
|
24
|
+
## Instruction
|
|
25
|
+
- Never hardcode API base URLs, endpoints, or webhook URLs in source code
|
|
26
|
+
- Use environment variables (e.g. `API_BASE_URL`, `WEBHOOK_URL`) or config files
|
|
27
|
+
- Document required env vars in README or .env.example
|
|
28
|
+
- For tests: use localhost, mock servers, or env-based URLs
|
|
29
|
+
- Prefer relative paths for same-origin requests when applicable
|
|
30
|
+
|
|
31
|
+
## Reason
|
|
32
|
+
Hardcoded URLs break across environments (dev/staging/prod), leak internal endpoints, and block easy configuration. Environment-based config is standard practice.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-new-deps-without-approval
|
|
3
|
+
description: Do not add new npm, pip, or other package dependencies without explicit human approval. Apply when installing packages, adding imports, or suggesting new libraries.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: warning
|
|
6
|
+
triggers:
|
|
7
|
+
- "Installing packages"
|
|
8
|
+
- "Adding dependencies"
|
|
9
|
+
- "npm install"
|
|
10
|
+
- "pip install"
|
|
11
|
+
- "New library"
|
|
12
|
+
- "Use package X"
|
|
13
|
+
license: MIT
|
|
14
|
+
metadata:
|
|
15
|
+
author: agent-guardrails
|
|
16
|
+
version: "1.0"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# No New Dependencies Without Approval
|
|
20
|
+
|
|
21
|
+
## Trigger
|
|
22
|
+
Adding a new package to package.json, requirements.txt, pyproject.toml, Cargo.toml, or any dependency manifest.
|
|
23
|
+
|
|
24
|
+
## Instruction
|
|
25
|
+
- Before running `npm install <pkg>`, `pip install <pkg>`, or equivalent: list the package and why it's needed, then ask for approval
|
|
26
|
+
- Prefer using existing project dependencies over adding new ones
|
|
27
|
+
- If a built-in or stdlib solution exists, use it instead of a new dependency
|
|
28
|
+
- When suggesting a new dependency: include package name, purpose, and alternative (e.g. "or we could use the built-in X")
|
|
29
|
+
- Never add dependencies "to fix" a problem without confirming the user wants new packages in the project
|
|
30
|
+
|
|
31
|
+
## Reason
|
|
32
|
+
Uncontrolled dependency growth leads to security risk, bundle bloat, and maintenance burden. Teams want to review what gets added to their lockfile.
|
|
33
|
+
|
|
34
|
+
## Provenance
|
|
35
|
+
Manual addition, common team preference for dependency hygiene.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-plaintext-secrets
|
|
3
|
+
description: Never log, commit, or expose API keys, passwords, or tokens. Use environment variables or secrets managers. Apply when adding logging, implementing auth, or integrating third-party APIs.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: critical
|
|
6
|
+
triggers:
|
|
7
|
+
- "Adding logging"
|
|
8
|
+
- "Implementing authentication"
|
|
9
|
+
- "API integration"
|
|
10
|
+
- "Handling credentials"
|
|
11
|
+
license: MIT
|
|
12
|
+
metadata:
|
|
13
|
+
author: agent-guardrails
|
|
14
|
+
version: "1.0"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# No Plaintext Secrets
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
Implementing authentication endpoints, adding logging, integrating third-party APIs, or handling any user credentials or API keys.
|
|
21
|
+
|
|
22
|
+
## Instruction
|
|
23
|
+
- Never store, log, or commit plaintext credentials (API keys, passwords, tokens, sessions)
|
|
24
|
+
- Always use environment variables or secrets managers (e.g. 1Password, Vault)
|
|
25
|
+
- Use bcrypt with 12 salt rounds for password hashing
|
|
26
|
+
- Always require HTTPS for authentication endpoints
|
|
27
|
+
- Use a `redactSensitive()` helper when logging objects that may contain secrets
|
|
28
|
+
|
|
29
|
+
## Reason
|
|
30
|
+
API keys were exposed in git during a 2025 security audit. Plaintext credentials in logs led to emergency key rotation.
|
|
31
|
+
|
|
32
|
+
## Provenance
|
|
33
|
+
Manual addition, based on guardrails.md case study.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: no-sudo-commands
|
|
3
|
+
description: Never run sudo, su, or root-elevated commands without explicit human approval. Apply when suggesting shell commands that modify system files or require elevated privileges.
|
|
4
|
+
scope: project
|
|
5
|
+
severity: critical
|
|
6
|
+
triggers:
|
|
7
|
+
- "Installing system packages"
|
|
8
|
+
- "apt install"
|
|
9
|
+
- "yum install"
|
|
10
|
+
- "brew install"
|
|
11
|
+
- "Modifying system files"
|
|
12
|
+
- "sudo"
|
|
13
|
+
- "su "
|
|
14
|
+
- "root"
|
|
15
|
+
license: MIT
|
|
16
|
+
metadata:
|
|
17
|
+
author: agent-guardrails
|
|
18
|
+
version: "1.0"
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# No Sudo Commands
|
|
22
|
+
|
|
23
|
+
## Trigger
|
|
24
|
+
Suggesting or running shell commands that require elevated privileges (sudo, su, root) or that modify system-wide files.
|
|
25
|
+
|
|
26
|
+
## Instruction
|
|
27
|
+
- Never run `sudo`, `su`, or root-elevated commands without explicit human approval
|
|
28
|
+
- For package installation: prefer user-space tools (nvm, pyenv, user-local npm) over system-wide installs
|
|
29
|
+
- If system packages are needed: propose the command, explain the impact, and wait for confirmation
|
|
30
|
+
- Never modify /etc, /usr (outside user installs), or other system directories without approval
|
|
31
|
+
- When the user asks to "install" something: clarify scope (project vs system) before suggesting commands
|
|
32
|
+
|
|
33
|
+
## Reason
|
|
34
|
+
Agents have run sudo commands that overwrote system configs or installed conflicting packages. Elevated privileges require explicit human confirmation.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rate-limiting
|
|
3
|
+
description: Limit tool calls and API requests to prevent runaway loops. Max 50 tool calls per session, max 10 per iteration. Stop after 3 consecutive errors.
|
|
4
|
+
scope: session
|
|
5
|
+
severity: warning
|
|
6
|
+
triggers:
|
|
7
|
+
- "Debugging API integrations"
|
|
8
|
+
- "Stripe or payment API calls"
|
|
9
|
+
- "External API calls in loops"
|
|
10
|
+
- "Context window approaching capacity"
|
|
11
|
+
license: MIT
|
|
12
|
+
metadata:
|
|
13
|
+
author: agent-guardrails
|
|
14
|
+
version: "1.0"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Rate Limiting
|
|
18
|
+
|
|
19
|
+
## Trigger
|
|
20
|
+
Debugging API integrations, making repeated external API calls, or when context exceeds 80% capacity or 10+ consecutive errors.
|
|
21
|
+
|
|
22
|
+
## Instruction
|
|
23
|
+
- Max 50 tool calls per session
|
|
24
|
+
- Max 10 tool calls per iteration
|
|
25
|
+
- Stop after 3 consecutive errors and request context rotation
|
|
26
|
+
- For payment APIs (Stripe, etc.): always use test mode when debugging
|
|
27
|
+
- When context exceeds 80% capacity: re-inject GUARDRAILS.md + summary + objective, then reset context
|
|
28
|
+
|
|
29
|
+
## Reason
|
|
30
|
+
Agent debugging Stripe entered an infinite loop of test calls, resulting in 2000+ requests in 30 minutes, $200 API costs, and account suspension.
|
|
31
|
+
|
|
32
|
+
## Provenance
|
|
33
|
+
Manual addition, based on guardrails.md case study.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guardrails-ref",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Validate and manage Agent Guardrails (GUARDRAIL.md) — init, add, remove, setup, validate, list",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/validate.js",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"guardrails-ref": "dist/cli.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
11
|
+
"build": "node scripts/copy-examples.js && tsc",
|
|
12
12
|
"test": "npm run build && node --test test/*.test.js",
|
|
13
13
|
"validate": "node dist/cli.js validate",
|
|
14
14
|
"list": "node dist/cli.js list",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"node": ">=18"
|
|
43
43
|
},
|
|
44
44
|
"files": [
|
|
45
|
-
"dist"
|
|
45
|
+
"dist",
|
|
46
|
+
"examples"
|
|
46
47
|
]
|
|
47
48
|
}
|