@mstar-harness/engine 3.2.6 → 3.4.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.
package/dist/audit.d.ts CHANGED
@@ -8,6 +8,11 @@ export type AuditEffort = (typeof AUDIT_EFFORTS)[number];
8
8
  /** Risk values. */
9
9
  export declare const AUDIT_RISKS: readonly ["LOW", "MED", "HIGH"];
10
10
  export type AuditRisk = (typeof AUDIT_RISKS)[number];
11
+ /** Confidence values (finding-format.md § Template — Confidence: HIGH
12
+ * (certain, read the code) / MED (strong signal, verify) / LOW (smell,
13
+ * investigate)). Enum SSOT for finding-doc lint + AuditFinding. */
14
+ export declare const AUDIT_CONFIDENCES: readonly ["HIGH", "MED", "LOW"];
15
+ export type AuditConfidence = (typeof AUDIT_CONFIDENCES)[number];
11
16
  /** Category codes (finding-format.md § Category codes + mstar-audit SKILL.md § Plan output (all variants) Status block). */
12
17
  export declare const AUDIT_CATEGORIES: readonly ["bug", "security", "perf", "tests", "tech-debt", "migration", "dx", "docs", "direction"];
13
18
  export type AuditCategory = (typeof AUDIT_CATEGORIES)[number];
@@ -42,6 +47,55 @@ export type RedactResult = {
42
47
  text: string;
43
48
  findings: SecretFinding[];
44
49
  };
50
+ /**
51
+ * Whole-match credential patterns — the match is fully replaced. Patterns
52
+ * are deliberately conservative (prefixed signatures + minimum lengths) to
53
+ * avoid false positives (mstar-audit Hard Rule 4: reference file:line and
54
+ * credential type only, never the value). Exported as the D-2 SSOT: both
55
+ * `redactSecrets` and `scanSecrets` share this one table, so reviewers can
56
+ * reconcile against exactly what the engine scans. Extending it only ever
57
+ * ADDS detections for consumers of either reader — existing-pattern
58
+ * behavior of the dsh audit seam (`validateAuditDoc`) stays byte-identical.
59
+ */
60
+ export declare const WHOLE_MATCH_PATTERNS: readonly {
61
+ type: string;
62
+ re: RegExp;
63
+ }[];
64
+ /**
65
+ * Key-value assignment patterns — for redaction the key name is preserved
66
+ * and only the value is replaced. Value minimum lengths (8 quoted / 16
67
+ * unquoted) keep the scan conservative (`token: x` and `password: 1234`
68
+ * are not flagged). Keys may carry optional quotes (JSON/YAML
69
+ * `"password": "..."`), which are preserved in the replacement: group 1 =
70
+ * optional open quote, group 3 = optional close quote, group 4 = separator,
71
+ * group 5 = value (dropped). Exported as part of the D-2 SSOT — shared by
72
+ * `redactSecrets` and `scanSecrets`.
73
+ */
74
+ export declare const VALUE_PATTERNS: readonly {
75
+ typeOf: (key: string) => string;
76
+ re: RegExp;
77
+ }[];
78
+ /**
79
+ * Never-commit filename patterns (security-review.md §6): a file whose name
80
+ * matches should not be committed regardless of content — `.env*`, `*.pem`,
81
+ * `*.key`, `id_rsa`-family, plus named credential stores. All patterns are
82
+ * matched against the path BASENAME, never the full path.
83
+ */
84
+ export declare const NEVER_COMMIT_FILENAMES: readonly {
85
+ type: string;
86
+ re: RegExp;
87
+ }[];
88
+ /**
89
+ * CI/IaC credential-leak shapes (security-review.md §6). Each entry is one
90
+ * deterministic line shape; match groups feed the finding message. All
91
+ * shapes are additive on top of the pattern tables above and never capture
92
+ * secret VALUES into findings (Hard Rule 4) — only file:line + type.
93
+ */
94
+ export declare const CI_IAC_LEAK_SHAPES: readonly {
95
+ kind: string;
96
+ description: string;
97
+ re: RegExp;
98
+ }[];
45
99
  /**
46
100
  * Scan text for credential patterns and replace every occurrence with a
47
101
  * `[REDACTED <type>@<line> in <file>]` marker (file omitted when `filePath`
@@ -50,6 +104,61 @@ export type RedactResult = {
50
104
  * line-sorted findings summary (`{ line, type }`).
51
105
  */
52
106
  export declare function redactSecrets(text: string, filePath?: string): RedactResult;
107
+ /** One `scanSecrets` finding: file + 1-based line + credential type ONLY —
108
+ * never the secret value (mstar-audit Hard Rule 4). */
109
+ export type ScannedSecret = {
110
+ file: string;
111
+ line: number;
112
+ type: string;
113
+ };
114
+ /**
115
+ * Read-only per-line secret scan over the given files. Report-only by
116
+ * design — it never redacts, never writes, and its findings carry
117
+ * `file:line` + credential type only (Hard Rule 4). Patterns come from the
118
+ * D-2 SSOT tables above (`WHOLE_MATCH_PATTERNS`, `VALUE_PATTERNS`) plus the
119
+ * never-commit filename list (`NEVER_COMMIT_FILENAMES`) and CI/IaC leak
120
+ * shapes (`CI_IAC_LEAK_SHAPES`). Safe-placeholder spans are masked before
121
+ * pattern evaluation (only the span — a key beside it still fires). Files
122
+ * that cannot be read are counted in `unreadableFiles` instead of being
123
+ * silently skipped: a security gate must never report clean over input it
124
+ * could not inspect (qc1 W-002).
125
+ */
126
+ /** Result of {@link scanSecrets}: findings plus how many selected files
127
+ * could not be read (fail-closed signal for CLI gates). */
128
+ export type ScanSecretsResult = {
129
+ findings: ScannedSecret[];
130
+ unreadableFiles: number;
131
+ };
132
+ export declare function scanSecrets(files: readonly string[]): ScanSecretsResult;
133
+ /** Kinds of supply-chain findings (B-11): lockfile presence/duplication at
134
+ * install boundaries and GitHub Actions pin/exposure shapes. */
135
+ export type SupplyChainFindingKind = "lockfile-missing" | "lockfile-duplicate" | "action-unpinned" | "pull_request_target-head";
136
+ export type SupplyChainFinding = {
137
+ kind: SupplyChainFindingKind;
138
+ file: string;
139
+ line?: number;
140
+ };
141
+ /** Result of {@link supplyChainChecks}: gate verdict + machine findings. */
142
+ export type SupplyChainResult = GateResult & {
143
+ findings: SupplyChainFinding[];
144
+ };
145
+ /**
146
+ * Deterministic supply-chain checks over `repoRoot` (read-only):
147
+ * - `lockfile-missing`: no recognized lockfile at the repo root
148
+ * (package-lock.json / pnpm-lock.yaml / yarn.lock / bun.lock[b] /
149
+ * Cargo.lock / poetry.lock / uv.lock / Gemfile.lock / composer.lock).
150
+ * - `lockfile-duplicate`: two or more distinct lockfiles at the root —
151
+ * ambiguous install boundaries.
152
+ * - `action-unpinned`: `.github/workflows/*.yml` steps using mutable refs
153
+ * (`@main`, `@master`, `@latest` or any non-SHA ref).
154
+ * - `pull_request_target-head`: a workflow triggers on `pull_request_target`
155
+ * AND checks out the PR head — untrusted code with secrets access.
156
+ *
157
+ * Tri-age judgment (reachable / runtime-relevant) is deliberately left to
158
+ * the reviewer (C-class). Violation codes mirror finding kinds with the
159
+ * `audit.supply.` prefix; `ok` is false iff any finding exists.
160
+ */
161
+ export declare function supplyChainChecks(repoRoot: string): SupplyChainResult;
53
162
  /** One audit finding, shaped after finding-format.md. */
54
163
  export type AuditFinding = {
55
164
  title: string;
@@ -57,7 +166,7 @@ export type AuditFinding = {
57
166
  impact: string;
58
167
  effort: AuditEffort;
59
168
  risk: AuditRisk;
60
- confidence: "HIGH" | "MED" | "LOW";
169
+ confidence: AuditConfidence;
61
170
  evidence: readonly string[];
62
171
  priority: AuditPriority;
63
172
  fixSketch?: string;
@@ -78,6 +187,15 @@ export type ScaffoldAuditPlanOptions = {
78
187
  title: string;
79
188
  reason: string;
80
189
  }[];
190
+ needsVerification?: readonly {
191
+ lead: string;
192
+ how: string;
193
+ evidence?: string;
194
+ }[];
195
+ hardeningChecked?: readonly {
196
+ kind: "Hardening" | "Checked and clean";
197
+ text: string;
198
+ }[];
81
199
  };
82
200
  /** Result of `scaffoldAuditPlan`. `nextNumber` is the next free plan number
83
201
  * (monotonic continuation vs. any pre-existing `NNN-*.md` files). */
@@ -94,7 +212,12 @@ export type ScaffoldAuditPlanResult = {
94
212
  * directory already contains `NNN-*.md` files (same-date re-run), the new
95
213
  * batch continues after the highest existing number instead of restarting
96
214
  * at 001, and the rebuilt index includes the pre-existing plans. Rejected
97
- * findings render in the "considered and rejected" section.
215
+ * findings render in the "considered and rejected" section. Security
216
+ * dispositions (`needsVerification` / `hardeningChecked`) render in their
217
+ * documented index sections. Policy: a SUPPLIED option is the authoritative
218
+ * current set and replaces the section (resolved leads can be removed,
219
+ * revised entries updated); an OMITTED option carries the previous section
220
+ * over from the existing README so hand-added entries survive the rebuild.
98
221
  */
99
222
  export declare function scaffoldAuditPlan(outDir: string, findings: readonly AuditFinding[], options?: ScaffoldAuditPlanOptions): ScaffoldAuditPlanResult;
100
223
  /** Options for `promoteAuditPlans`. `harnessDir` is required — the snapshot