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 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 output) |
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
- .action((path = ".", options) => {
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
- process.exit(result.invalid > 0 ? 1 : 0);
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
- process.exit(hasErrors ? 1 : 0);
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-new-deps-without-approval)")
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
- .action((path = ".") => {
88
- const result = runSetup(path);
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
@@ -4,3 +4,4 @@ export interface SetupResult {
4
4
  message: string;
5
5
  }
6
6
  export declare function runSetup(projectPath?: string): SetupResult;
7
+ export declare function runSetupRemove(projectPath?: string): SetupResult;
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
+ }
@@ -1,5 +1,2 @@
1
- /**
2
- * Bundled example guardrails. Used by init and add commands.
3
- */
4
1
  export declare const TEMPLATES: Record<string, string>;
5
2
  export declare const TEMPLATE_NAMES: string[];
package/dist/templates.js CHANGED
@@ -1,7 +1,15 @@
1
1
  /**
2
- * Bundled example guardrails. Used by init and add commands.
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
- export const TEMPLATES = {
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",
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
  }