@node9/policy-engine 1.61.1 → 1.62.1

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/dist/index.d.mts CHANGED
@@ -712,6 +712,13 @@ declare function computeSecurityScore(opts: {
712
712
  */
713
713
  declare function classifyScanSignal(key: keyof ScanSignals): Severity;
714
714
  /**
715
+ * @deprecated Score-1 redesign (2026-07): the Report score is now LIVE +
716
+ * POSTURE via {@link computeAgentDeviceScore}; session-scan findings moved to
717
+ * the onboarding forecast and no longer feed a "current risk" number (they
718
+ * are lifetime data — blending them inflated the score with pre-install
719
+ * history). Kept exported for npm back-compat (removal = breaking major);
720
+ * do not add new callers.
721
+ *
715
722
  * Compute a 0-100 risk-posture score that blends audit-log severity counts
716
723
  * with forward-only scan signal counts.
717
724
  *
@@ -752,6 +759,44 @@ declare function computeBlendedSecurityScore(opts: {
752
759
  score: number;
753
760
  tier: ScoreTier;
754
761
  };
762
+ /**
763
+ * The Report's "how at-risk am I RIGHT NOW?" score: a 0.5/0.5 blend of
764
+ *
765
+ * runtime = computeSecurityScore(live audit counts) — what node9 CAUGHT
766
+ * in the window (rate-based, unchanged math);
767
+ * posture = the fleet-average machine posture score — how exposed the
768
+ * machines are NOW (already includes disk/secret exposure via
769
+ * the posture scorecard's secrets check).
770
+ *
771
+ * Session-scan (lifetime) findings deliberately do NOT feed this score —
772
+ * they are pre-install history, not current risk (they surface in the
773
+ * onboarding forecast instead).
774
+ *
775
+ * Missing-data semantics (the day-1 false-100 fix):
776
+ * - no activity AND no posture → { score: null, tier: null } — the caller
777
+ * renders "not enough data", NEVER an invented 100/healthy;
778
+ * - no activity, posture known → posture IS the risk (a fresh machine that
779
+ * can read ~/.aws scores badly regardless of activity);
780
+ * - activity, no posture yet → the pure runtime score;
781
+ * - both → round(0.5·runtime + 0.5·posture).
782
+ *
783
+ * An EARNED 100 (real activity, nothing caught) blends normally — only the
784
+ * no-data 100 is suppressed. Pure; posture defensively clamped to [0,100].
785
+ */
786
+ declare function computeAgentDeviceScore(opts: {
787
+ /** LIVE audit-window severity counts — scan never feeds this score. */
788
+ audit: {
789
+ critical: number;
790
+ high: number;
791
+ medium: number;
792
+ total: number;
793
+ };
794
+ /** Fleet-average machine posture score, or null when no machine reports. */
795
+ posture: number | null;
796
+ }): {
797
+ score: number | null;
798
+ tier: ScoreTier | null;
799
+ };
755
800
 
756
801
  /**
757
802
  * One sensitive path that the blast walker found readable on disk.
@@ -1055,4 +1100,4 @@ declare function previewArgs(input: Record<string, unknown>, max: number): strin
1055
1100
  /** Engine version stamped on audit entries for future drift detection. */
1056
1101
  declare const ENGINE_VERSION = "1.4.0";
1057
1102
 
1058
- export { AST_FS_REGEX_RULES, type AuditEntryForClassify, BASH_TOOL_NAMES, BUILTIN_SHIELDS, type BlastEnvFinding, type BlastFinding, type BlastResult, type BlastSummary, CANONICAL_EXTRACTOR_HASH, CANONICAL_EXTRACTOR_VERSION, COST_PER_LOOP_ITER_USD, type CanonicalAgent, type CanonicalFinding, type CanonicalFindingType, type CanonicalSourceType, DEFAULT_EGRESS_ALLOWLIST, DESTRUCTIVE_OP_RE, DLP_PATTERNS, type DlpMatch, ENGINE_VERSION, type EgressPolicy, type EgressVerdict, type ExtractContext, FILE_TOOLS, FLAGS_WITH_VALUES, type FsOpVerdict, type InjectionConfidence, type InjectionContext, type InjectionMatch, LONG_OUTPUT_THRESHOLD_BYTES, LOOP_MAX_RECORDS, LOOP_THRESHOLD_FOR_WASTE, type LoopWindowEvaluation, PRIVILEGE_ESCALATION_RE, type PiiPattern, type PipeChainAnalysis, type PolicyConfig, type PolicyContext, type PolicyHostHooks, type PolicyVerdict, type ProvenanceLookup, type ProvenanceTrust, REALTIME_PII_PATTERNS, type RiskMetadata, SCAN_SIGNAL_WEIGHTS, SENSITIVE_PATH_RE, SENSITIVE_PATH_REGEXES, type ScanFinding, type ScanSignals, type ScanSummary, type ScoreTier, type SessionExtractContext, type SessionToolCall, type Severity, type ShellCommandAnalysis, type ShellDestination, type ShieldDefinition, type ShieldOverrides, type ShieldVerdict, type SmartCondition, type SmartRule, type ToolCallEntry, type ToolCallRecord, analyzeFsOperation, analyzePipeChain, analyzeShellCommand, checkDangerousSql, classifyAuditEntry, classifyRuleSeverity, classifyScanSignal, computeArgsHash, computeBlendedSecurityScore, computeScanScore, computeSecurityScore, dedupeCanonicalFindings, detectArgsPii, detectDangerousEval, detectDangerousShellExec, detectPii, evaluateEgress, evaluateLoopWindow, evaluatePolicy, evaluateSmartConditions, extractAllSshHosts, extractCanonicalFindings, extractNetworkTargets, extractPositionalArgs, extractSessionLevelFindings, extractShellDestinations, getCompiledRegex, getNestedValue, hostMatches, isBashTool, isIgnoredTool, isPrivateHost, isProtectedHomePath, isShieldVerdict, matchSensitivePath, matchesPattern, narrativeRuleLabel, normalizeCommandForPolicy, parseAllSshHostsFromCommand, parseDestHost, previewArgs, redactText, resolvePinned, scanArgs, scanInjection, scanText, sensitivePathMatch, summarizeBlast, summarizeScan, toScanFinding, truncateBlastPath, validateOverrides, validateRegex, validateShieldDefinition };
1103
+ export { AST_FS_REGEX_RULES, type AuditEntryForClassify, BASH_TOOL_NAMES, BUILTIN_SHIELDS, type BlastEnvFinding, type BlastFinding, type BlastResult, type BlastSummary, CANONICAL_EXTRACTOR_HASH, CANONICAL_EXTRACTOR_VERSION, COST_PER_LOOP_ITER_USD, type CanonicalAgent, type CanonicalFinding, type CanonicalFindingType, type CanonicalSourceType, DEFAULT_EGRESS_ALLOWLIST, DESTRUCTIVE_OP_RE, DLP_PATTERNS, type DlpMatch, ENGINE_VERSION, type EgressPolicy, type EgressVerdict, type ExtractContext, FILE_TOOLS, FLAGS_WITH_VALUES, type FsOpVerdict, type InjectionConfidence, type InjectionContext, type InjectionMatch, LONG_OUTPUT_THRESHOLD_BYTES, LOOP_MAX_RECORDS, LOOP_THRESHOLD_FOR_WASTE, type LoopWindowEvaluation, PRIVILEGE_ESCALATION_RE, type PiiPattern, type PipeChainAnalysis, type PolicyConfig, type PolicyContext, type PolicyHostHooks, type PolicyVerdict, type ProvenanceLookup, type ProvenanceTrust, REALTIME_PII_PATTERNS, type RiskMetadata, SCAN_SIGNAL_WEIGHTS, SENSITIVE_PATH_RE, SENSITIVE_PATH_REGEXES, type ScanFinding, type ScanSignals, type ScanSummary, type ScoreTier, type SessionExtractContext, type SessionToolCall, type Severity, type ShellCommandAnalysis, type ShellDestination, type ShieldDefinition, type ShieldOverrides, type ShieldVerdict, type SmartCondition, type SmartRule, type ToolCallEntry, type ToolCallRecord, analyzeFsOperation, analyzePipeChain, analyzeShellCommand, checkDangerousSql, classifyAuditEntry, classifyRuleSeverity, classifyScanSignal, computeAgentDeviceScore, computeArgsHash, computeBlendedSecurityScore, computeScanScore, computeSecurityScore, dedupeCanonicalFindings, detectArgsPii, detectDangerousEval, detectDangerousShellExec, detectPii, evaluateEgress, evaluateLoopWindow, evaluatePolicy, evaluateSmartConditions, extractAllSshHosts, extractCanonicalFindings, extractNetworkTargets, extractPositionalArgs, extractSessionLevelFindings, extractShellDestinations, getCompiledRegex, getNestedValue, hostMatches, isBashTool, isIgnoredTool, isPrivateHost, isProtectedHomePath, isShieldVerdict, matchSensitivePath, matchesPattern, narrativeRuleLabel, normalizeCommandForPolicy, parseAllSshHostsFromCommand, parseDestHost, previewArgs, redactText, resolvePinned, scanArgs, scanInjection, scanText, sensitivePathMatch, summarizeBlast, summarizeScan, toScanFinding, truncateBlastPath, validateOverrides, validateRegex, validateShieldDefinition };
package/dist/index.d.ts CHANGED
@@ -712,6 +712,13 @@ declare function computeSecurityScore(opts: {
712
712
  */
713
713
  declare function classifyScanSignal(key: keyof ScanSignals): Severity;
714
714
  /**
715
+ * @deprecated Score-1 redesign (2026-07): the Report score is now LIVE +
716
+ * POSTURE via {@link computeAgentDeviceScore}; session-scan findings moved to
717
+ * the onboarding forecast and no longer feed a "current risk" number (they
718
+ * are lifetime data — blending them inflated the score with pre-install
719
+ * history). Kept exported for npm back-compat (removal = breaking major);
720
+ * do not add new callers.
721
+ *
715
722
  * Compute a 0-100 risk-posture score that blends audit-log severity counts
716
723
  * with forward-only scan signal counts.
717
724
  *
@@ -752,6 +759,44 @@ declare function computeBlendedSecurityScore(opts: {
752
759
  score: number;
753
760
  tier: ScoreTier;
754
761
  };
762
+ /**
763
+ * The Report's "how at-risk am I RIGHT NOW?" score: a 0.5/0.5 blend of
764
+ *
765
+ * runtime = computeSecurityScore(live audit counts) — what node9 CAUGHT
766
+ * in the window (rate-based, unchanged math);
767
+ * posture = the fleet-average machine posture score — how exposed the
768
+ * machines are NOW (already includes disk/secret exposure via
769
+ * the posture scorecard's secrets check).
770
+ *
771
+ * Session-scan (lifetime) findings deliberately do NOT feed this score —
772
+ * they are pre-install history, not current risk (they surface in the
773
+ * onboarding forecast instead).
774
+ *
775
+ * Missing-data semantics (the day-1 false-100 fix):
776
+ * - no activity AND no posture → { score: null, tier: null } — the caller
777
+ * renders "not enough data", NEVER an invented 100/healthy;
778
+ * - no activity, posture known → posture IS the risk (a fresh machine that
779
+ * can read ~/.aws scores badly regardless of activity);
780
+ * - activity, no posture yet → the pure runtime score;
781
+ * - both → round(0.5·runtime + 0.5·posture).
782
+ *
783
+ * An EARNED 100 (real activity, nothing caught) blends normally — only the
784
+ * no-data 100 is suppressed. Pure; posture defensively clamped to [0,100].
785
+ */
786
+ declare function computeAgentDeviceScore(opts: {
787
+ /** LIVE audit-window severity counts — scan never feeds this score. */
788
+ audit: {
789
+ critical: number;
790
+ high: number;
791
+ medium: number;
792
+ total: number;
793
+ };
794
+ /** Fleet-average machine posture score, or null when no machine reports. */
795
+ posture: number | null;
796
+ }): {
797
+ score: number | null;
798
+ tier: ScoreTier | null;
799
+ };
755
800
 
756
801
  /**
757
802
  * One sensitive path that the blast walker found readable on disk.
@@ -1055,4 +1100,4 @@ declare function previewArgs(input: Record<string, unknown>, max: number): strin
1055
1100
  /** Engine version stamped on audit entries for future drift detection. */
1056
1101
  declare const ENGINE_VERSION = "1.4.0";
1057
1102
 
1058
- export { AST_FS_REGEX_RULES, type AuditEntryForClassify, BASH_TOOL_NAMES, BUILTIN_SHIELDS, type BlastEnvFinding, type BlastFinding, type BlastResult, type BlastSummary, CANONICAL_EXTRACTOR_HASH, CANONICAL_EXTRACTOR_VERSION, COST_PER_LOOP_ITER_USD, type CanonicalAgent, type CanonicalFinding, type CanonicalFindingType, type CanonicalSourceType, DEFAULT_EGRESS_ALLOWLIST, DESTRUCTIVE_OP_RE, DLP_PATTERNS, type DlpMatch, ENGINE_VERSION, type EgressPolicy, type EgressVerdict, type ExtractContext, FILE_TOOLS, FLAGS_WITH_VALUES, type FsOpVerdict, type InjectionConfidence, type InjectionContext, type InjectionMatch, LONG_OUTPUT_THRESHOLD_BYTES, LOOP_MAX_RECORDS, LOOP_THRESHOLD_FOR_WASTE, type LoopWindowEvaluation, PRIVILEGE_ESCALATION_RE, type PiiPattern, type PipeChainAnalysis, type PolicyConfig, type PolicyContext, type PolicyHostHooks, type PolicyVerdict, type ProvenanceLookup, type ProvenanceTrust, REALTIME_PII_PATTERNS, type RiskMetadata, SCAN_SIGNAL_WEIGHTS, SENSITIVE_PATH_RE, SENSITIVE_PATH_REGEXES, type ScanFinding, type ScanSignals, type ScanSummary, type ScoreTier, type SessionExtractContext, type SessionToolCall, type Severity, type ShellCommandAnalysis, type ShellDestination, type ShieldDefinition, type ShieldOverrides, type ShieldVerdict, type SmartCondition, type SmartRule, type ToolCallEntry, type ToolCallRecord, analyzeFsOperation, analyzePipeChain, analyzeShellCommand, checkDangerousSql, classifyAuditEntry, classifyRuleSeverity, classifyScanSignal, computeArgsHash, computeBlendedSecurityScore, computeScanScore, computeSecurityScore, dedupeCanonicalFindings, detectArgsPii, detectDangerousEval, detectDangerousShellExec, detectPii, evaluateEgress, evaluateLoopWindow, evaluatePolicy, evaluateSmartConditions, extractAllSshHosts, extractCanonicalFindings, extractNetworkTargets, extractPositionalArgs, extractSessionLevelFindings, extractShellDestinations, getCompiledRegex, getNestedValue, hostMatches, isBashTool, isIgnoredTool, isPrivateHost, isProtectedHomePath, isShieldVerdict, matchSensitivePath, matchesPattern, narrativeRuleLabel, normalizeCommandForPolicy, parseAllSshHostsFromCommand, parseDestHost, previewArgs, redactText, resolvePinned, scanArgs, scanInjection, scanText, sensitivePathMatch, summarizeBlast, summarizeScan, toScanFinding, truncateBlastPath, validateOverrides, validateRegex, validateShieldDefinition };
1103
+ export { AST_FS_REGEX_RULES, type AuditEntryForClassify, BASH_TOOL_NAMES, BUILTIN_SHIELDS, type BlastEnvFinding, type BlastFinding, type BlastResult, type BlastSummary, CANONICAL_EXTRACTOR_HASH, CANONICAL_EXTRACTOR_VERSION, COST_PER_LOOP_ITER_USD, type CanonicalAgent, type CanonicalFinding, type CanonicalFindingType, type CanonicalSourceType, DEFAULT_EGRESS_ALLOWLIST, DESTRUCTIVE_OP_RE, DLP_PATTERNS, type DlpMatch, ENGINE_VERSION, type EgressPolicy, type EgressVerdict, type ExtractContext, FILE_TOOLS, FLAGS_WITH_VALUES, type FsOpVerdict, type InjectionConfidence, type InjectionContext, type InjectionMatch, LONG_OUTPUT_THRESHOLD_BYTES, LOOP_MAX_RECORDS, LOOP_THRESHOLD_FOR_WASTE, type LoopWindowEvaluation, PRIVILEGE_ESCALATION_RE, type PiiPattern, type PipeChainAnalysis, type PolicyConfig, type PolicyContext, type PolicyHostHooks, type PolicyVerdict, type ProvenanceLookup, type ProvenanceTrust, REALTIME_PII_PATTERNS, type RiskMetadata, SCAN_SIGNAL_WEIGHTS, SENSITIVE_PATH_RE, SENSITIVE_PATH_REGEXES, type ScanFinding, type ScanSignals, type ScanSummary, type ScoreTier, type SessionExtractContext, type SessionToolCall, type Severity, type ShellCommandAnalysis, type ShellDestination, type ShieldDefinition, type ShieldOverrides, type ShieldVerdict, type SmartCondition, type SmartRule, type ToolCallEntry, type ToolCallRecord, analyzeFsOperation, analyzePipeChain, analyzeShellCommand, checkDangerousSql, classifyAuditEntry, classifyRuleSeverity, classifyScanSignal, computeAgentDeviceScore, computeArgsHash, computeBlendedSecurityScore, computeScanScore, computeSecurityScore, dedupeCanonicalFindings, detectArgsPii, detectDangerousEval, detectDangerousShellExec, detectPii, evaluateEgress, evaluateLoopWindow, evaluatePolicy, evaluateSmartConditions, extractAllSshHosts, extractCanonicalFindings, extractNetworkTargets, extractPositionalArgs, extractSessionLevelFindings, extractShellDestinations, getCompiledRegex, getNestedValue, hostMatches, isBashTool, isIgnoredTool, isPrivateHost, isProtectedHomePath, isShieldVerdict, matchSensitivePath, matchesPattern, narrativeRuleLabel, normalizeCommandForPolicy, parseAllSshHostsFromCommand, parseDestHost, previewArgs, redactText, resolvePinned, scanArgs, scanInjection, scanText, sensitivePathMatch, summarizeBlast, summarizeScan, toScanFinding, truncateBlastPath, validateOverrides, validateRegex, validateShieldDefinition };
package/dist/index.js CHANGED
@@ -57,6 +57,7 @@ __export(src_exports, {
57
57
  classifyAuditEntry: () => classifyAuditEntry,
58
58
  classifyRuleSeverity: () => classifyRuleSeverity,
59
59
  classifyScanSignal: () => classifyScanSignal,
60
+ computeAgentDeviceScore: () => computeAgentDeviceScore,
60
61
  computeArgsHash: () => computeArgsHash,
61
62
  computeBlendedSecurityScore: () => computeBlendedSecurityScore,
62
63
  computeScanScore: () => computeScanScore,
@@ -3548,6 +3549,17 @@ function computeBlendedSecurityScore(opts) {
3548
3549
  }
3549
3550
  return computeSecurityScore({ critical, high, medium, total });
3550
3551
  }
3552
+ function computeAgentDeviceScore(opts) {
3553
+ const { audit } = opts;
3554
+ const posture = Number.isFinite(opts.posture) ? Math.max(0, Math.min(100, opts.posture)) : null;
3555
+ const tierOf = (s) => s >= 80 ? "good" : s >= 50 ? "at-risk" : "critical";
3556
+ if (audit.total === 0 && posture === null) return { score: null, tier: null };
3557
+ if (audit.total === 0) return { score: posture, tier: tierOf(posture) };
3558
+ const runtime = computeSecurityScore(audit);
3559
+ if (posture === null) return runtime;
3560
+ const score = Math.round(0.5 * runtime.score + 0.5 * posture);
3561
+ return { score, tier: tierOf(score) };
3562
+ }
3551
3563
 
3552
3564
  // src/blast/index.ts
3553
3565
  function truncateBlastPath(full) {
@@ -4001,6 +4013,7 @@ var ENGINE_VERSION = "1.4.0";
4001
4013
  classifyAuditEntry,
4002
4014
  classifyRuleSeverity,
4003
4015
  classifyScanSignal,
4016
+ computeAgentDeviceScore,
4004
4017
  computeArgsHash,
4005
4018
  computeBlendedSecurityScore,
4006
4019
  computeScanScore,
package/dist/index.mjs CHANGED
@@ -3439,6 +3439,17 @@ function computeBlendedSecurityScore(opts) {
3439
3439
  }
3440
3440
  return computeSecurityScore({ critical, high, medium, total });
3441
3441
  }
3442
+ function computeAgentDeviceScore(opts) {
3443
+ const { audit } = opts;
3444
+ const posture = Number.isFinite(opts.posture) ? Math.max(0, Math.min(100, opts.posture)) : null;
3445
+ const tierOf = (s) => s >= 80 ? "good" : s >= 50 ? "at-risk" : "critical";
3446
+ if (audit.total === 0 && posture === null) return { score: null, tier: null };
3447
+ if (audit.total === 0) return { score: posture, tier: tierOf(posture) };
3448
+ const runtime = computeSecurityScore(audit);
3449
+ if (posture === null) return runtime;
3450
+ const score = Math.round(0.5 * runtime.score + 0.5 * posture);
3451
+ return { score, tier: tierOf(score) };
3452
+ }
3442
3453
 
3443
3454
  // src/blast/index.ts
3444
3455
  function truncateBlastPath(full) {
@@ -3891,6 +3902,7 @@ export {
3891
3902
  classifyAuditEntry,
3892
3903
  classifyRuleSeverity,
3893
3904
  classifyScanSignal,
3905
+ computeAgentDeviceScore,
3894
3906
  computeArgsHash,
3895
3907
  computeBlendedSecurityScore,
3896
3908
  computeScanScore,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/policy-engine",
3
- "version": "1.61.1",
3
+ "version": "1.62.1",
4
4
  "description": "Shared policy evaluation engine for node9 — DLP, smart rules, AST shell parsing, shields, loop detection. Pure functions, no I/O. Used by both node9-proxy and the node9 SaaS firewall.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://node9.ai",