@rigour-labs/core 5.2.6 → 5.2.8

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.
@@ -13,6 +13,23 @@ import yaml from 'yaml';
13
13
  import { ConfigSchema } from '../types/index.js';
14
14
  import { scanInputForCredentials } from './input-validator.js';
15
15
  const JS_TS_PATTERN = /\.(ts|tsx|js|jsx|mts|mjs)$/;
16
+ /**
17
+ * Check if a file matches any ignore pattern from rigour.yml.
18
+ */
19
+ function isIgnored(relPath, patterns) {
20
+ const normalized = relPath.replace(/\\/g, '/');
21
+ return patterns.some(pattern => {
22
+ const clean = pattern.replace(/\\/g, '/');
23
+ if (normalized === clean)
24
+ return true;
25
+ // Glob: foo/** matches foo/bar/baz
26
+ const prefix = clean.replace('/**', '').replace('/*', '');
27
+ if (prefix !== clean) {
28
+ return normalized.startsWith(prefix + '/') || normalized === prefix;
29
+ }
30
+ return false;
31
+ });
32
+ }
16
33
  /**
17
34
  * Load rigour config from cwd, falling back to defaults.
18
35
  */
@@ -42,7 +59,9 @@ async function resolveFile(filePath, cwd) {
42
59
  function checkFile(content, relPath, cwd, config) {
43
60
  const failures = [];
44
61
  const lines = content.split('\n');
45
- // Gate 0: Memory & Skills Governance block writes to agent-native memory paths
62
+ // Gate 0a: Protected pathsBLOCK writes to .github/, rigour.yml, etc.
63
+ checkProtectedPaths(relPath, config, failures);
64
+ // Gate 0b: Memory & Skills Governance — block writes to agent-native memory paths
46
65
  checkGovernance(content, relPath, config, failures);
47
66
  // Gate 1: File size
48
67
  const maxLines = config.gates.max_file_lines ?? 500;
@@ -78,6 +97,7 @@ export async function runHookChecker(options) {
78
97
  try {
79
98
  const config = await loadConfig(cwd);
80
99
  const deadline = start + timeout_ms;
100
+ const ignorePatterns = config.ignore ?? [];
81
101
  for (const filePath of files) {
82
102
  if (Date.now() > deadline) {
83
103
  break;
@@ -86,6 +106,10 @@ export async function runHookChecker(options) {
86
106
  if (!resolved) {
87
107
  continue;
88
108
  }
109
+ // Respect rigour.yml ignore patterns
110
+ if (isIgnored(resolved.relPath, ignorePatterns)) {
111
+ continue;
112
+ }
89
113
  const fileFailures = checkFile(resolved.content, resolved.relPath, cwd, config);
90
114
  failures.push(...fileFailures);
91
115
  }
@@ -222,6 +246,33 @@ function checkCommandInjection(line, i, relPath, failures) {
222
246
  });
223
247
  }
224
248
  }
249
+ // ── Protected Paths Enforcement (real-time) ───────────────────────
250
+ /**
251
+ * Block writes to protected paths defined in rigour.yml safety.protected_paths.
252
+ * This runs in real-time via hooks — BEFORE the agent commits the write.
253
+ */
254
+ function checkProtectedPaths(relPath, config, failures) {
255
+ const protectedPaths = config.gates.safety?.protected_paths ?? [];
256
+ if (protectedPaths.length === 0)
257
+ return;
258
+ const normalizedPath = relPath.replace(/\\/g, '/');
259
+ const matched = protectedPaths.find(pattern => {
260
+ const clean = pattern.replace('/**', '').replace('/*', '');
261
+ if (normalizedPath === clean)
262
+ return true;
263
+ if (clean.endsWith('/'))
264
+ return normalizedPath.startsWith(clean);
265
+ return normalizedPath.startsWith(clean + '/');
266
+ });
267
+ if (matched) {
268
+ failures.push({
269
+ gate: 'file-guard',
270
+ file: relPath,
271
+ message: `BLOCKED: Agent cannot write to protected path "${relPath}" (matches ${matched}). CI/CD, docs, and config files require human review.`,
272
+ severity: 'critical',
273
+ });
274
+ }
275
+ }
225
276
  // ── Memory & Skills Governance (v4.2+) ────────────────────────────
226
277
  /**
227
278
  * Simple glob matcher — handles exact paths, `*` (single segment),
@@ -17,7 +17,7 @@ export interface HookConfig {
17
17
  block_on_failure: boolean;
18
18
  }
19
19
  /** The fast gates that can run per-file in <200ms */
20
- export declare const FAST_GATE_IDS: readonly ["governance", "hallucinated-imports", "promise-safety", "security-patterns", "file-size"];
20
+ export declare const FAST_GATE_IDS: readonly ["file-guard", "governance", "hallucinated-imports", "promise-safety", "security-patterns", "file-size"];
21
21
  export declare const DEFAULT_HOOK_CONFIG: HookConfig;
22
22
  export type FastGateId = typeof FAST_GATE_IDS[number];
23
23
  export interface HookCheckerResult {
@@ -7,6 +7,7 @@
7
7
  */
8
8
  /** The fast gates that can run per-file in <200ms */
9
9
  export const FAST_GATE_IDS = [
10
+ 'file-guard',
10
11
  'governance',
11
12
  'hallucinated-imports',
12
13
  'promise-safety',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/core",
3
- "version": "5.2.6",
3
+ "version": "5.2.8",
4
4
  "description": "AI-native quality gate engine with local Bayesian learning. AST analysis, drift detection, Fix Packet generation, and agent self-healing across TypeScript, JavaScript, Python, Go, Ruby, and C#.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://rigour.run",
@@ -66,11 +66,11 @@
66
66
  "@xenova/transformers": "^2.17.2",
67
67
  "sqlite3": "^5.1.7",
68
68
  "openai": "^4.104.0",
69
- "@rigour-labs/brain-darwin-x64": "5.2.6",
70
- "@rigour-labs/brain-linux-x64": "5.2.6",
71
- "@rigour-labs/brain-darwin-arm64": "5.2.6",
72
- "@rigour-labs/brain-win-x64": "5.2.6",
73
- "@rigour-labs/brain-linux-arm64": "5.2.6"
69
+ "@rigour-labs/brain-darwin-arm64": "5.2.8",
70
+ "@rigour-labs/brain-darwin-x64": "5.2.8",
71
+ "@rigour-labs/brain-linux-x64": "5.2.8",
72
+ "@rigour-labs/brain-linux-arm64": "5.2.8",
73
+ "@rigour-labs/brain-win-x64": "5.2.8"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@types/fs-extra": "^11.0.4",