@nanocollective/sentinel 0.1.0-alpha.0

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.
Files changed (163) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +66 -0
  3. package/dist/cli.d.ts +12 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +254 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config/parse.d.ts +13 -0
  8. package/dist/config/parse.d.ts.map +1 -0
  9. package/dist/config/parse.js +271 -0
  10. package/dist/config/parse.js.map +1 -0
  11. package/dist/config/repo-override.d.ts +13 -0
  12. package/dist/config/repo-override.d.ts.map +1 -0
  13. package/dist/config/repo-override.js +128 -0
  14. package/dist/config/repo-override.js.map +1 -0
  15. package/dist/config/types.d.ts +86 -0
  16. package/dist/config/types.d.ts.map +1 -0
  17. package/dist/config/types.js +8 -0
  18. package/dist/config/types.js.map +1 -0
  19. package/dist/dedup/hash.d.ts +10 -0
  20. package/dist/dedup/hash.d.ts.map +1 -0
  21. package/dist/dedup/hash.js +18 -0
  22. package/dist/dedup/hash.js.map +1 -0
  23. package/dist/dedup/markers.d.ts +13 -0
  24. package/dist/dedup/markers.d.ts.map +1 -0
  25. package/dist/dedup/markers.js +42 -0
  26. package/dist/dedup/markers.js.map +1 -0
  27. package/dist/dedup/plan.d.ts +45 -0
  28. package/dist/dedup/plan.d.ts.map +1 -0
  29. package/dist/dedup/plan.js +83 -0
  30. package/dist/dedup/plan.js.map +1 -0
  31. package/dist/dedup/reconcile.d.ts +29 -0
  32. package/dist/dedup/reconcile.d.ts.map +1 -0
  33. package/dist/dedup/reconcile.js +73 -0
  34. package/dist/dedup/reconcile.js.map +1 -0
  35. package/dist/findings/types.d.ts +53 -0
  36. package/dist/findings/types.d.ts.map +1 -0
  37. package/dist/findings/types.js +28 -0
  38. package/dist/findings/types.js.map +1 -0
  39. package/dist/findings/validate.d.ts +36 -0
  40. package/dist/findings/validate.d.ts.map +1 -0
  41. package/dist/findings/validate.js +178 -0
  42. package/dist/findings/validate.js.map +1 -0
  43. package/dist/index.d.ts +48 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +39 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/init/args.d.ts +20 -0
  48. package/dist/init/args.d.ts.map +1 -0
  49. package/dist/init/args.js +80 -0
  50. package/dist/init/args.js.map +1 -0
  51. package/dist/init/plan.d.ts +9 -0
  52. package/dist/init/plan.d.ts.map +1 -0
  53. package/dist/init/plan.js +17 -0
  54. package/dist/init/plan.js.map +1 -0
  55. package/dist/init/scaffold.d.ts +17 -0
  56. package/dist/init/scaffold.d.ts.map +1 -0
  57. package/dist/init/scaffold.js +27 -0
  58. package/dist/init/scaffold.js.map +1 -0
  59. package/dist/init/templates.d.ts +28 -0
  60. package/dist/init/templates.d.ts.map +1 -0
  61. package/dist/init/templates.js +187 -0
  62. package/dist/init/templates.js.map +1 -0
  63. package/dist/init/types.d.ts +29 -0
  64. package/dist/init/types.d.ts.map +1 -0
  65. package/dist/init/types.js +15 -0
  66. package/dist/init/types.js.map +1 -0
  67. package/dist/issues/body.d.ts +12 -0
  68. package/dist/issues/body.d.ts.map +1 -0
  69. package/dist/issues/body.js +53 -0
  70. package/dist/issues/body.js.map +1 -0
  71. package/dist/issues/file.d.ts +24 -0
  72. package/dist/issues/file.d.ts.map +1 -0
  73. package/dist/issues/file.js +61 -0
  74. package/dist/issues/file.js.map +1 -0
  75. package/dist/issues/gh-client.d.ts +21 -0
  76. package/dist/issues/gh-client.d.ts.map +1 -0
  77. package/dist/issues/gh-client.js +133 -0
  78. package/dist/issues/gh-client.js.map +1 -0
  79. package/dist/issues/types.d.ts +85 -0
  80. package/dist/issues/types.d.ts.map +1 -0
  81. package/dist/issues/types.js +8 -0
  82. package/dist/issues/types.js.map +1 -0
  83. package/dist/orchestrator/audit.d.ts +14 -0
  84. package/dist/orchestrator/audit.d.ts.map +1 -0
  85. package/dist/orchestrator/audit.js +47 -0
  86. package/dist/orchestrator/audit.js.map +1 -0
  87. package/dist/orchestrator/auto-fix.d.ts +31 -0
  88. package/dist/orchestrator/auto-fix.d.ts.map +1 -0
  89. package/dist/orchestrator/auto-fix.js +59 -0
  90. package/dist/orchestrator/auto-fix.js.map +1 -0
  91. package/dist/orchestrator/extract.d.ts +14 -0
  92. package/dist/orchestrator/extract.d.ts.map +1 -0
  93. package/dist/orchestrator/extract.js +70 -0
  94. package/dist/orchestrator/extract.js.map +1 -0
  95. package/dist/orchestrator/nanocoder-runner.d.ts +33 -0
  96. package/dist/orchestrator/nanocoder-runner.d.ts.map +1 -0
  97. package/dist/orchestrator/nanocoder-runner.js +125 -0
  98. package/dist/orchestrator/nanocoder-runner.js.map +1 -0
  99. package/dist/orchestrator/types.d.ts +51 -0
  100. package/dist/orchestrator/types.d.ts.map +1 -0
  101. package/dist/orchestrator/types.js +8 -0
  102. package/dist/orchestrator/types.js.map +1 -0
  103. package/dist/prompt/build.d.ts +14 -0
  104. package/dist/prompt/build.d.ts.map +1 -0
  105. package/dist/prompt/build.js +123 -0
  106. package/dist/prompt/build.js.map +1 -0
  107. package/dist/prompt/types.d.ts +34 -0
  108. package/dist/prompt/types.d.ts.map +1 -0
  109. package/dist/prompt/types.js +8 -0
  110. package/dist/prompt/types.js.map +1 -0
  111. package/dist/rule-packs/dependencies.d.ts +20 -0
  112. package/dist/rule-packs/dependencies.d.ts.map +1 -0
  113. package/dist/rule-packs/dependencies.js +58 -0
  114. package/dist/rule-packs/dependencies.js.map +1 -0
  115. package/dist/rule-packs/glob.d.ts +23 -0
  116. package/dist/rule-packs/glob.d.ts.map +1 -0
  117. package/dist/rule-packs/glob.js +66 -0
  118. package/dist/rule-packs/glob.js.map +1 -0
  119. package/dist/rule-packs/parse.d.ts +21 -0
  120. package/dist/rule-packs/parse.d.ts.map +1 -0
  121. package/dist/rule-packs/parse.js +230 -0
  122. package/dist/rule-packs/parse.js.map +1 -0
  123. package/dist/rule-packs/types.d.ts +55 -0
  124. package/dist/rule-packs/types.d.ts.map +1 -0
  125. package/dist/rule-packs/types.js +10 -0
  126. package/dist/rule-packs/types.js.map +1 -0
  127. package/dist/run/audit.d.ts +20 -0
  128. package/dist/run/audit.d.ts.map +1 -0
  129. package/dist/run/audit.js +28 -0
  130. package/dist/run/audit.js.map +1 -0
  131. package/dist/run/clone.d.ts +23 -0
  132. package/dist/run/clone.d.ts.map +1 -0
  133. package/dist/run/clone.js +51 -0
  134. package/dist/run/clone.js.map +1 -0
  135. package/dist/run/preview.d.ts +34 -0
  136. package/dist/run/preview.d.ts.map +1 -0
  137. package/dist/run/preview.js +68 -0
  138. package/dist/run/preview.js.map +1 -0
  139. package/dist/run/report.d.ts +10 -0
  140. package/dist/run/report.d.ts.map +1 -0
  141. package/dist/run/report.js +73 -0
  142. package/dist/run/report.js.map +1 -0
  143. package/dist/run/run.d.ts +74 -0
  144. package/dist/run/run.d.ts.map +1 -0
  145. package/dist/run/run.js +131 -0
  146. package/dist/run/run.js.map +1 -0
  147. package/dist/run/select.d.ts +14 -0
  148. package/dist/run/select.d.ts.map +1 -0
  149. package/dist/run/select.js +31 -0
  150. package/dist/run/select.js.map +1 -0
  151. package/dist/run/sources.d.ts +11 -0
  152. package/dist/run/sources.d.ts.map +1 -0
  153. package/dist/run/sources.js +106 -0
  154. package/dist/run/sources.js.map +1 -0
  155. package/dist/run/types.d.ts +55 -0
  156. package/dist/run/types.d.ts.map +1 -0
  157. package/dist/run/types.js +7 -0
  158. package/dist/run/types.js.map +1 -0
  159. package/dist/suppression/apply.d.ts +33 -0
  160. package/dist/suppression/apply.d.ts.map +1 -0
  161. package/dist/suppression/apply.js +55 -0
  162. package/dist/suppression/apply.js.map +1 -0
  163. package/package.json +118 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../source/config/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Parse the opt-in `sentinel.yaml` placed in an audited repo — the most
3
+ * specific suppression layer (see docs/findings/index.md#suppression). It can
4
+ * override the org severity threshold for this repo and declare systematic-
5
+ * noise exemptions.
6
+ */
7
+ import type { RepoOverrideResult } from './types.js';
8
+ /**
9
+ * Parse a per-repo override. An empty or absent file is valid and yields an
10
+ * override with no threshold change and no suppressions.
11
+ */
12
+ export declare function parseRepoOverride(raw: string): RepoOverrideResult;
13
+ //# sourceMappingURL=repo-override.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-override.d.ts","sourceRoot":"","sources":["../../source/config/repo-override.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAGX,kBAAkB,EAElB,MAAM,YAAY,CAAC;AAuEpB;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CA+DjE"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Parse the opt-in `sentinel.yaml` placed in an audited repo — the most
3
+ * specific suppression layer (see docs/findings/index.md#suppression). It can
4
+ * override the org severity threshold for this repo and declare systematic-
5
+ * noise exemptions.
6
+ */
7
+ import { parse as parseYaml } from 'yaml';
8
+ import { isSeverity } from '../findings/types.js';
9
+ function isObject(value) {
10
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
11
+ }
12
+ function isNonEmptyString(value) {
13
+ return typeof value === 'string' && value.trim().length > 0;
14
+ }
15
+ function isStringArray(value) {
16
+ return Array.isArray(value) && value.every(item => typeof item === 'string');
17
+ }
18
+ function validateSuppression(value, index, errors) {
19
+ const field = `suppress[${index}]`;
20
+ if (!isObject(value)) {
21
+ errors.push({ field, message: 'each suppression must be a mapping' });
22
+ return null;
23
+ }
24
+ const hasRule = value.rule !== undefined;
25
+ const hasPaths = value.paths !== undefined;
26
+ if (!hasRule && !hasPaths) {
27
+ errors.push({
28
+ field,
29
+ message: 'a suppression must set at least one of rule or paths',
30
+ });
31
+ }
32
+ if (hasRule && !isNonEmptyString(value.rule)) {
33
+ errors.push({
34
+ field: `${field}.rule`,
35
+ message: 'rule must be a non-empty string',
36
+ });
37
+ }
38
+ let paths = [];
39
+ if (hasPaths) {
40
+ if (isStringArray(value.paths) && value.paths.length > 0) {
41
+ paths = value.paths;
42
+ }
43
+ else {
44
+ errors.push({
45
+ field: `${field}.paths`,
46
+ message: 'paths must be a non-empty list of glob strings',
47
+ });
48
+ }
49
+ }
50
+ if (value.reason !== undefined && typeof value.reason !== 'string') {
51
+ errors.push({ field: `${field}.reason`, message: 'reason must be a string' });
52
+ }
53
+ if (errors.some(e => e.field.startsWith(field))) {
54
+ return null;
55
+ }
56
+ const suppression = {
57
+ paths,
58
+ reason: typeof value.reason === 'string' ? value.reason : '',
59
+ };
60
+ if (isNonEmptyString(value.rule)) {
61
+ suppression.rule = value.rule;
62
+ }
63
+ return suppression;
64
+ }
65
+ /**
66
+ * Parse a per-repo override. An empty or absent file is valid and yields an
67
+ * override with no threshold change and no suppressions.
68
+ */
69
+ export function parseRepoOverride(raw) {
70
+ let data;
71
+ try {
72
+ data = raw.trim().length === 0 ? {} : parseYaml(raw);
73
+ }
74
+ catch (error) {
75
+ const message = error instanceof Error ? error.message : String(error);
76
+ return {
77
+ valid: false,
78
+ override: null,
79
+ errors: [{ field: 'document', message: `invalid YAML: ${message}` }],
80
+ };
81
+ }
82
+ if (data === null) {
83
+ return { valid: true, override: { suppress: [] }, errors: [] };
84
+ }
85
+ if (!isObject(data)) {
86
+ return {
87
+ valid: false,
88
+ override: null,
89
+ errors: [
90
+ {
91
+ field: 'document',
92
+ message: 'per-repo sentinel.yaml must be a mapping',
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ const errors = [];
98
+ const override = { suppress: [] };
99
+ if (data.severity_threshold !== undefined) {
100
+ if (isSeverity(data.severity_threshold)) {
101
+ override.severityThreshold = data.severity_threshold;
102
+ }
103
+ else {
104
+ errors.push({
105
+ field: 'severity_threshold',
106
+ message: 'severity_threshold must be one of: low, medium, high, critical',
107
+ });
108
+ }
109
+ }
110
+ if (data.suppress !== undefined) {
111
+ if (!Array.isArray(data.suppress)) {
112
+ errors.push({ field: 'suppress', message: 'suppress must be a list' });
113
+ }
114
+ else {
115
+ for (const [index, entry] of data.suppress.entries()) {
116
+ const suppression = validateSuppression(entry, index, errors);
117
+ if (suppression) {
118
+ override.suppress.push(suppression);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ if (errors.length > 0) {
124
+ return { valid: false, override: null, errors };
125
+ }
126
+ return { valid: true, override, errors: [] };
127
+ }
128
+ //# sourceMappingURL=repo-override.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-override.js","sourceRoot":"","sources":["../../source/config/repo-override.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The `sentinel.yaml` configuration model. There is one configuration per
3
+ * install: one file, one workflow, one schedule (see
4
+ * docs/configuration/index.md). Keys are snake_case on disk and normalised to
5
+ * camelCase here.
6
+ */
7
+ import type { Severity } from '../findings/types.js';
8
+ /** A repository (or pattern) to audit, with the packs assigned to it. */
9
+ export interface Target {
10
+ /** A single `owner/name` repository. Mutually exclusive with `pattern`. */
11
+ repo?: string;
12
+ /** A glob over `owner/name` repositories. Mutually exclusive with `repo`. */
13
+ pattern?: string;
14
+ /** The rule pack names to run against this target. */
15
+ rulePacks: string[];
16
+ }
17
+ /** An optional cloud fallback, used only when the primary model struggles. */
18
+ export interface ModelFallback {
19
+ provider: string;
20
+ model: string;
21
+ /** Name of the Actions secret holding the endpoint key. */
22
+ endpointSecret?: string;
23
+ }
24
+ /** Which Nanocoder provider and model to run. Local-first by default. */
25
+ export interface ModelConfig {
26
+ provider: string;
27
+ model: string;
28
+ fallback?: ModelFallback;
29
+ }
30
+ /** Controls how findings are filed as issues. */
31
+ export interface IssuesConfig {
32
+ /** Label applied to every filed issue. */
33
+ label: string;
34
+ /** GitHub login to assign filed issues to, or null. */
35
+ assignee: string | null;
36
+ /** File on the config repo instead of the audited repo. */
37
+ aggregateToConfigRepo: boolean;
38
+ }
39
+ /** The validated, normalised `sentinel.yaml`. */
40
+ export interface SentinelConfig {
41
+ targets: Target[];
42
+ /** Cron expression (UTC) for the scheduled run. */
43
+ schedule: string;
44
+ /** The filing floor: findings below this severity do not open issues. */
45
+ severityThreshold: Severity;
46
+ model: ModelConfig;
47
+ issues: IssuesConfig;
48
+ }
49
+ /** One systematic-noise exemption in a per-repo override. */
50
+ export interface Suppression {
51
+ /** The rule (pack/pattern) to suppress. Optional if `paths` is given. */
52
+ rule?: string;
53
+ /** Glob patterns the suppression applies to. Optional if `rule` is given. */
54
+ paths: string[];
55
+ /** Why the exemption exists. */
56
+ reason: string;
57
+ }
58
+ /**
59
+ * The opt-in `sentinel.yaml` placed in an audited repo — the most specific
60
+ * suppression layer (see docs/findings/index.md#suppression).
61
+ */
62
+ export interface RepoOverride {
63
+ /** Optional per-repo override of the org severity threshold. */
64
+ severityThreshold?: Severity;
65
+ /** Systematic-noise exemptions for this repo. */
66
+ suppress: Suppression[];
67
+ }
68
+ /** A single reason a config file failed to parse or validate. */
69
+ export interface ConfigError {
70
+ /** The offending field path, or 'document' for structural errors. */
71
+ field: string;
72
+ message: string;
73
+ }
74
+ /** The outcome of parsing `sentinel.yaml`. */
75
+ export interface ConfigResult {
76
+ valid: boolean;
77
+ config: SentinelConfig | null;
78
+ errors: ConfigError[];
79
+ }
80
+ /** The outcome of parsing a per-repo override. */
81
+ export interface RepoOverrideResult {
82
+ valid: boolean;
83
+ override: RepoOverride | null;
84
+ errors: ConfigError[];
85
+ }
86
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/config/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAEnD,yEAAyE;AACzE,MAAM,WAAW,MAAM;IACtB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC5B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,qBAAqB,EAAE,OAAO,CAAC;CAC/B;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,iBAAiB,EAAE,QAAQ,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;CACrB;AAED,6DAA6D;AAC7D,MAAM,WAAW,WAAW;IAC3B,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAC7B,iDAAiD;IACjD,QAAQ,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC3B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The `sentinel.yaml` configuration model. There is one configuration per
3
+ * install: one file, one workflow, one schedule (see
4
+ * docs/configuration/index.md). Keys are snake_case on disk and normalised to
5
+ * camelCase here.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../source/config/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The content hash that identifies a finding across runs. Computed over the
3
+ * salient fields (rule, file, line range, category) so the same finding on a
4
+ * later run produces the same hash and is not filed twice
5
+ * (see docs/findings/index.md#dedup).
6
+ */
7
+ import type { Finding } from '../findings/types.js';
8
+ /** A stable 16-hex-char content hash for a finding. */
9
+ export declare function findingHash(finding: Finding): string;
10
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../source/dedup/hash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,sBAAsB,CAAC;AAElD,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAQpD"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The content hash that identifies a finding across runs. Computed over the
3
+ * salient fields (rule, file, line range, category) so the same finding on a
4
+ * later run produces the same hash and is not filed twice
5
+ * (see docs/findings/index.md#dedup).
6
+ */
7
+ import { createHash } from 'node:crypto';
8
+ /** A stable 16-hex-char content hash for a finding. */
9
+ export function findingHash(finding) {
10
+ const salient = [
11
+ finding.rule,
12
+ finding.file,
13
+ `${finding.lineRange.start}-${finding.lineRange.end}`,
14
+ finding.category,
15
+ ].join('\n');
16
+ return createHash('sha256').update(salient).digest('hex').slice(0, 16);
17
+ }
18
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../source/dedup/hash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAGvC,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC3C,MAAM,OAAO,GAAG;QACf,OAAO,CAAC,IAAI;QACZ,OAAO,CAAC,IAAI;QACZ,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;QACrD,OAAO,CAAC,QAAQ;KAChB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Hidden HTML-comment markers embedded in an issue body. They carry the
3
+ * machine state dedup needs across runs — the finding's content hash, the
4
+ * last-seen timestamp, and the consecutive-miss counter — without a database.
5
+ * Implemented with plain string search (no dynamic RegExp) so values are opaque.
6
+ */
7
+ /** Read a marker's value from a body, or null if absent. */
8
+ export declare function readMarker(body: string, key: string): string | null;
9
+ /** Add or replace a marker, returning the updated body. */
10
+ export declare function upsertMarker(body: string, key: string, value: string): string;
11
+ /** Read the consecutive-miss counter, defaulting to 0. */
12
+ export declare function readMisses(body: string): number;
13
+ //# sourceMappingURL=markers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers.d.ts","sourceRoot":"","sources":["../../source/dedup/markers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWnE;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Hidden HTML-comment markers embedded in an issue body. They carry the
3
+ * machine state dedup needs across runs — the finding's content hash, the
4
+ * last-seen timestamp, and the consecutive-miss counter — without a database.
5
+ * Implemented with plain string search (no dynamic RegExp) so values are opaque.
6
+ */
7
+ const PREFIX = 'sentinel';
8
+ const CLOSE = ' -->';
9
+ function open(key) {
10
+ return `<!-- ${PREFIX}:${key}=`;
11
+ }
12
+ /** Read a marker's value from a body, or null if absent. */
13
+ export function readMarker(body, key) {
14
+ const start = body.indexOf(open(key));
15
+ if (start === -1) {
16
+ return null;
17
+ }
18
+ const valueStart = start + open(key).length;
19
+ const valueEnd = body.indexOf(CLOSE, valueStart);
20
+ if (valueEnd === -1) {
21
+ return null;
22
+ }
23
+ return body.slice(valueStart, valueEnd);
24
+ }
25
+ /** Add or replace a marker, returning the updated body. */
26
+ export function upsertMarker(body, key, value) {
27
+ const marker = `${open(key)}${value}${CLOSE}`;
28
+ const start = body.indexOf(open(key));
29
+ if (start === -1) {
30
+ return `${body}\n${marker}`;
31
+ }
32
+ const valueEnd = body.indexOf(CLOSE, start);
33
+ const end = valueEnd + CLOSE.length;
34
+ return body.slice(0, start) + marker + body.slice(end);
35
+ }
36
+ /** Read the consecutive-miss counter, defaulting to 0. */
37
+ export function readMisses(body) {
38
+ const raw = readMarker(body, 'misses');
39
+ const parsed = raw === null ? 0 : Number.parseInt(raw, 10);
40
+ return Number.isNaN(parsed) ? 0 : parsed;
41
+ }
42
+ //# sourceMappingURL=markers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers.js","sourceRoot":"","sources":["../../source/dedup/markers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,KAAK,GAAG,MAAM,CAAC;AAErB,SAAS,IAAI,CAAC,GAAW;IACxB,OAAO,QAAQ,MAAM,IAAI,GAAG,GAAG,CAAC;AACjC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,GAAW;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,GAAW,EAAE,KAAa;IACpE,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,KAAK,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;QAClB,OAAO,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC;IAC7B,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The dedup planner. Given this run's findings and the issues that already
3
+ * exist on the target repo, decide what to do with each: file a new issue,
4
+ * touch (reset) an existing one, suppress it (a maintainer closed it with a
5
+ * suppression label), or resolve a stale issue whose finding has been absent
6
+ * for enough consecutive runs. Pure and fully tested; the executor
7
+ * (reconcile.ts) applies the plan.
8
+ */
9
+ import type { Finding } from '../findings/types.js';
10
+ import type { ExistingIssue } from '../issues/types.js';
11
+ /** Closing an issue with one of these labels means "do not refile". */
12
+ export declare const SUPPRESSION_LABELS: readonly ["sentinel:false-positive", "sentinel:wontfix", "sentinel:accepted"];
13
+ /** Options for planning. */
14
+ export interface ReconcileOptions {
15
+ /** Consecutive absent runs before an open issue is auto-resolved. Min 1. */
16
+ resolveAfterMisses?: number;
17
+ }
18
+ /** An open issue matched by a finding this run: reset its miss counter. */
19
+ export interface TouchOp {
20
+ issue: ExistingIssue;
21
+ finding: Finding;
22
+ }
23
+ /** An open issue absent this run but not yet stale: bump its miss counter. */
24
+ export interface MissOp {
25
+ issue: ExistingIssue;
26
+ misses: number;
27
+ }
28
+ /** What reconcile should do this run. */
29
+ export interface ReconcilePlan {
30
+ /** Findings with no existing issue: file them. */
31
+ toCreate: Finding[];
32
+ /** Findings matching an open issue: touch it. */
33
+ toTouch: TouchOp[];
34
+ /** Findings matching a suppression-closed issue: skip. */
35
+ suppressed: Finding[];
36
+ /** Open issues absent long enough to auto-resolve. */
37
+ toResolve: ExistingIssue[];
38
+ /** Open issues absent this run but below the resolve threshold. */
39
+ toIncrementMiss: MissOp[];
40
+ }
41
+ /**
42
+ * Plan the reconciliation of this run's findings against existing issues.
43
+ */
44
+ export declare function planReconciliation(findings: Finding[], existing: ExistingIssue[], options?: ReconcileOptions): ReconcilePlan;
45
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../source/dedup/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAItD,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,+EAIrB,CAAC;AAEX,4BAA4B;AAC5B,MAAM,WAAW,gBAAgB;IAChC,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,8EAA8E;AAC9E,MAAM,WAAW,MAAM;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,kDAAkD;IAClD,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,0DAA0D;IAC1D,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB,sDAAsD;IACtD,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,mEAAmE;IACnE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC1B;AAQD;;GAEG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,OAAO,EAAE,EACnB,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,GAAE,gBAAqB,GAC5B,aAAa,CA8Df"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The dedup planner. Given this run's findings and the issues that already
3
+ * exist on the target repo, decide what to do with each: file a new issue,
4
+ * touch (reset) an existing one, suppress it (a maintainer closed it with a
5
+ * suppression label), or resolve a stale issue whose finding has been absent
6
+ * for enough consecutive runs. Pure and fully tested; the executor
7
+ * (reconcile.ts) applies the plan.
8
+ */
9
+ import { findingHash } from './hash.js';
10
+ import { readMarker, readMisses } from './markers.js';
11
+ /** Closing an issue with one of these labels means "do not refile". */
12
+ export const SUPPRESSION_LABELS = [
13
+ 'sentinel:false-positive',
14
+ 'sentinel:wontfix',
15
+ 'sentinel:accepted',
16
+ ];
17
+ function hasSuppressionLabel(issue) {
18
+ return issue.labels.some(label => SUPPRESSION_LABELS.includes(label));
19
+ }
20
+ /**
21
+ * Plan the reconciliation of this run's findings against existing issues.
22
+ */
23
+ export function planReconciliation(findings, existing, options = {}) {
24
+ const resolveAfterMisses = Math.max(1, options.resolveAfterMisses ?? 3);
25
+ // Deduplicate findings within this run by hash; first occurrence wins.
26
+ const findingByHash = new Map();
27
+ for (const finding of findings) {
28
+ const hash = findingHash(finding);
29
+ if (!findingByHash.has(hash)) {
30
+ findingByHash.set(hash, finding);
31
+ }
32
+ }
33
+ // Index existing issues by their embedded hash.
34
+ const suppressedHashes = new Set();
35
+ const openByHash = new Map();
36
+ for (const issue of existing) {
37
+ const hash = readMarker(issue.body, 'hash');
38
+ if (hash === null) {
39
+ continue;
40
+ }
41
+ if (hasSuppressionLabel(issue)) {
42
+ suppressedHashes.add(hash);
43
+ }
44
+ else if (issue.state === 'open') {
45
+ openByHash.set(hash, issue);
46
+ }
47
+ }
48
+ const plan = {
49
+ toCreate: [],
50
+ toTouch: [],
51
+ suppressed: [],
52
+ toResolve: [],
53
+ toIncrementMiss: [],
54
+ };
55
+ for (const [hash, finding] of findingByHash) {
56
+ if (suppressedHashes.has(hash)) {
57
+ plan.suppressed.push(finding);
58
+ continue;
59
+ }
60
+ const openIssue = openByHash.get(hash);
61
+ if (openIssue) {
62
+ plan.toTouch.push({ issue: openIssue, finding });
63
+ }
64
+ else {
65
+ plan.toCreate.push(finding);
66
+ }
67
+ }
68
+ // Open issues whose finding did not recur this run: age them out.
69
+ for (const [hash, issue] of openByHash) {
70
+ if (findingByHash.has(hash)) {
71
+ continue;
72
+ }
73
+ const misses = readMisses(issue.body) + 1;
74
+ if (misses >= resolveAfterMisses) {
75
+ plan.toResolve.push(issue);
76
+ }
77
+ else {
78
+ plan.toIncrementMiss.push({ issue, misses });
79
+ }
80
+ }
81
+ return plan;
82
+ }
83
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../source/dedup/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The dedup executor. Fetches existing Sentinel issues on the target repo,
3
+ * plans the reconciliation, then applies it: file new findings, touch matched
4
+ * issues (reset misses + last-seen), age out absent ones, and auto-resolve the
5
+ * stale. Below-threshold findings are filtered out before planning, so they
6
+ * neither create nor touch.
7
+ */
8
+ import type { RepoOverride, SentinelConfig } from '../config/types.js';
9
+ import { type Finding } from '../findings/types.js';
10
+ import type { CreatedIssue, FilingContext, ReconcileClient } from '../issues/types.js';
11
+ import { type ReconcileOptions } from './plan.js';
12
+ /** A summary of what one reconcile run did. */
13
+ export interface ReconcileResult {
14
+ targetRepo: string;
15
+ created: CreatedIssue[];
16
+ touched: number;
17
+ incremented: number;
18
+ resolved: number;
19
+ /** Findings suppressed by a label-closed issue (dedup layer). */
20
+ suppressed: number;
21
+ /** Findings removed by the per-repo override's suppress rules. */
22
+ suppressedByOverride: number;
23
+ }
24
+ /**
25
+ * Reconcile this run's findings against the issues already on the target repo.
26
+ * `now` is passed in (ISO string) so the executor stays deterministic.
27
+ */
28
+ export declare function reconcileFindings(findings: Finding[], config: SentinelConfig, client: ReconcileClient, context: FilingContext, now: string, options?: ReconcileOptions, override?: RepoOverride): Promise<ReconcileResult>;
29
+ //# sourceMappingURL=reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../source/dedup/reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAC,KAAK,OAAO,EAAyB,MAAM,sBAAsB,CAAC;AAE1E,OAAO,KAAK,EACX,YAAY,EACZ,aAAa,EACb,eAAe,EACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAqB,KAAK,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAEpE,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAMD;;;GAGG;AACH,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,gBAAqB,EAC9B,QAAQ,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,eAAe,CAAC,CAiE1B"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The dedup executor. Fetches existing Sentinel issues on the target repo,
3
+ * plans the reconciliation, then applies it: file new findings, touch matched
4
+ * issues (reset misses + last-seen), age out absent ones, and auto-resolve the
5
+ * stale. Below-threshold findings are filtered out before planning, so they
6
+ * neither create nor touch.
7
+ */
8
+ import { meetsSeverityThreshold } from '../findings/types.js';
9
+ import { buildIssueContent, targetRepoFor } from '../issues/file.js';
10
+ import { applyRepoOverride } from '../suppression/apply.js';
11
+ import { upsertMarker } from './markers.js';
12
+ import { planReconciliation } from './plan.js';
13
+ function trackedBody(body, now) {
14
+ return upsertMarker(upsertMarker(body, 'last-seen', now), 'misses', '0');
15
+ }
16
+ /**
17
+ * Reconcile this run's findings against the issues already on the target repo.
18
+ * `now` is passed in (ISO string) so the executor stays deterministic.
19
+ */
20
+ export async function reconcileFindings(findings, config, client, context, now, options = {}, override) {
21
+ const targetRepo = targetRepoFor(config, context);
22
+ const existing = await client.listIssues({
23
+ repo: targetRepo,
24
+ label: config.issues.label,
25
+ });
26
+ // Layer 3: apply the per-repo override (threshold + suppress rules), then
27
+ // gate by the effective threshold before planning.
28
+ const { kept, suppressed: overrideSuppressed, threshold, } = applyRepoOverride(findings, config, override);
29
+ const qualifying = kept.filter(finding => meetsSeverityThreshold(finding.severity, threshold));
30
+ const plan = planReconciliation(qualifying, existing, options);
31
+ const created = [];
32
+ for (const finding of plan.toCreate) {
33
+ const content = buildIssueContent(finding, config, context);
34
+ const issue = await client.createIssue({
35
+ repo: targetRepo,
36
+ ...content,
37
+ body: trackedBody(content.body, now),
38
+ });
39
+ created.push(issue);
40
+ }
41
+ for (const { issue } of plan.toTouch) {
42
+ await client.updateIssue({
43
+ repo: targetRepo,
44
+ number: issue.number,
45
+ body: trackedBody(issue.body, now),
46
+ });
47
+ }
48
+ for (const { issue, misses } of plan.toIncrementMiss) {
49
+ await client.updateIssue({
50
+ repo: targetRepo,
51
+ number: issue.number,
52
+ body: upsertMarker(issue.body, 'misses', String(misses)),
53
+ });
54
+ }
55
+ for (const issue of plan.toResolve) {
56
+ await client.closeIssue({
57
+ repo: targetRepo,
58
+ number: issue.number,
59
+ reason: 'completed',
60
+ comment: 'Sentinel is auto-resolving this finding: it has not recurred across recent audit runs.',
61
+ });
62
+ }
63
+ return {
64
+ targetRepo,
65
+ created,
66
+ touched: plan.toTouch.length,
67
+ incremented: plan.toIncrementMiss.length,
68
+ resolved: plan.toResolve.length,
69
+ suppressed: plan.suppressed.length,
70
+ suppressedByOverride: overrideSuppressed.length,
71
+ };
72
+ }
73
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../source/dedup/reconcile.ts"],"names":[],"mappings":"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"}