@rmyndharis/aimhooman 0.1.2 → 0.1.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.
@@ -67,9 +67,11 @@ export function scanEntries(repo, engine, entries, options = {}) {
67
67
  increment(stats.skipped, 'binary');
68
68
  // Binary classification only skips text-oriented policy rules. Secret
69
69
  // signatures are ASCII byte sequences, so latin1 preserves a
70
- // one-byte-to-one-code-unit view and prevents one NUL from hiding
71
- // credential material while keeping the existing byte limits.
72
- matched = engine.checkContent(entry.path, blob.toString('latin1'), {
70
+ // one-byte-to-one-code-unit view and keeps the existing byte limits.
71
+ // Stripping NULs is what defeats hiding credential material behind
72
+ // them: one injected NUL breaks a signature, and a multi-byte
73
+ // encoding like UTF-16 injects one per character.
74
+ matched = engine.checkContent(entry.path, blob.toString('latin1').replace(/\0/g, ''), {
73
75
  categories: ['secret'],
74
76
  });
75
77
  } else {
@@ -113,6 +115,10 @@ function readObjects(repo, objectIds, expectedBytes = 0) {
113
115
  encoding: 'buffer',
114
116
  maxBuffer: Math.max(2 * 1024 * 1024, expectedBytes + unique.length * 256 + 1024),
115
117
  timeout: GIT_TIMEOUT_MS,
118
+ // Same reason as gitBuf in gitx.mjs: without an explicit stdio,
119
+ // execFileSync echoes the child's stderr before it checks the exit
120
+ // status, so git's raw output reaches the terminal even on success.
121
+ stdio: ['pipe', 'pipe', 'pipe'],
116
122
  });
117
123
  const objects = new Map();
118
124
  const failures = [];
@@ -11,7 +11,16 @@ import { commitChanges, commitMessage, commitSnapshot, historyRange } from './hi
11
11
  import { DEFAULT_SCAN_LIMITS, scanEntries } from './scan-session.mjs';
12
12
  import { loadRulesWithDiagnostics } from './rules.mjs';
13
13
 
14
- const PROFILE_RANK = { clean: 0, compliance: 1, strict: 2 };
14
+ // A tiebreak for the one profile a range report has to name, not a strength
15
+ // lattice. Clean and compliance are not ordered against each other: compliance
16
+ // allows the six attribution rules clean blocks or reviews, no shipped rule runs
17
+ // the other way, and applyExplicitProfile refuses to move between them in either
18
+ // direction. No single profile is truthful for a mixed range, so this only
19
+ // settles which policy object gets reported — clean outranks compliance because
20
+ // a value read as the strongest must not name the profile that allows what the
21
+ // other blocks. Enforcement never reads this: each commit is scanned under its
22
+ // own policy and the exit code uses each finding's own scanProfile.
23
+ const PROFILE_RANK = { compliance: 0, clean: 1, strict: 2 };
15
24
  const REVIEW_REQUIRED_PATH_RULES = new Set([
16
25
  'generic.agent-instructions',
17
26
  'generic.project-policy',