@vyuhlabs/dxkit 2.5.2 → 2.6.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/CHANGELOG.md +164 -0
- package/README.md +102 -0
- package/dist/allowlist/categories.d.ts +120 -0
- package/dist/allowlist/categories.d.ts.map +1 -0
- package/dist/allowlist/categories.js +194 -0
- package/dist/allowlist/categories.js.map +1 -0
- package/dist/allowlist/cli.d.ts +95 -0
- package/dist/allowlist/cli.d.ts.map +1 -0
- package/dist/allowlist/cli.js +454 -0
- package/dist/allowlist/cli.js.map +1 -0
- package/dist/allowlist/diff.d.ts +67 -0
- package/dist/allowlist/diff.d.ts.map +1 -0
- package/dist/allowlist/diff.js +147 -0
- package/dist/allowlist/diff.js.map +1 -0
- package/dist/allowlist/file.d.ts +249 -0
- package/dist/allowlist/file.d.ts.map +1 -0
- package/dist/allowlist/file.js +497 -0
- package/dist/allowlist/file.js.map +1 -0
- package/dist/allowlist/gather.d.ts +61 -0
- package/dist/allowlist/gather.d.ts.map +1 -0
- package/dist/allowlist/gather.js +143 -0
- package/dist/allowlist/gather.js.map +1 -0
- package/dist/allowlist/hint.d.ts +80 -0
- package/dist/allowlist/hint.d.ts.map +1 -0
- package/dist/allowlist/hint.js +271 -0
- package/dist/allowlist/hint.js.map +1 -0
- package/dist/allowlist/inline.d.ts +149 -0
- package/dist/allowlist/inline.d.ts.map +1 -0
- package/dist/allowlist/inline.js +306 -0
- package/dist/allowlist/inline.js.map +1 -0
- package/dist/baseline/baseline-file.d.ts +7 -0
- package/dist/baseline/baseline-file.d.ts.map +1 -1
- package/dist/baseline/baseline-file.js +22 -1
- package/dist/baseline/baseline-file.js.map +1 -1
- package/dist/baseline/check-renderers.d.ts +13 -1
- package/dist/baseline/check-renderers.d.ts.map +1 -1
- package/dist/baseline/check-renderers.js +67 -1
- package/dist/baseline/check-renderers.js.map +1 -1
- package/dist/baseline/check.d.ts +33 -7
- package/dist/baseline/check.d.ts.map +1 -1
- package/dist/baseline/check.js +90 -64
- package/dist/baseline/check.js.map +1 -1
- package/dist/baseline/create.d.ts +35 -7
- package/dist/baseline/create.d.ts.map +1 -1
- package/dist/baseline/create.js +43 -5
- package/dist/baseline/create.js.map +1 -1
- package/dist/baseline/entry-to-located.d.ts +6 -1
- package/dist/baseline/entry-to-located.d.ts.map +1 -1
- package/dist/baseline/entry-to-located.js +20 -2
- package/dist/baseline/entry-to-located.js.map +1 -1
- package/dist/baseline/finding-identity.d.ts.map +1 -1
- package/dist/baseline/finding-identity.js +15 -13
- package/dist/baseline/finding-identity.js.map +1 -1
- package/dist/baseline/modes.d.ts +140 -0
- package/dist/baseline/modes.d.ts.map +1 -0
- package/dist/baseline/modes.js +179 -0
- package/dist/baseline/modes.js.map +1 -0
- package/dist/baseline/policy.d.ts +64 -0
- package/dist/baseline/policy.d.ts.map +1 -1
- package/dist/baseline/policy.js +102 -1
- package/dist/baseline/policy.js.map +1 -1
- package/dist/baseline/producers/health.d.ts +2 -2
- package/dist/baseline/producers/health.d.ts.map +1 -1
- package/dist/baseline/producers/health.js.map +1 -1
- package/dist/baseline/producers/index.d.ts +11 -5
- package/dist/baseline/producers/index.d.ts.map +1 -1
- package/dist/baseline/producers/index.js +12 -9
- package/dist/baseline/producers/index.js.map +1 -1
- package/dist/baseline/producers/quality.d.ts +3 -3
- package/dist/baseline/producers/quality.d.ts.map +1 -1
- package/dist/baseline/producers/quality.js.map +1 -1
- package/dist/baseline/producers/secret-hmac.d.ts +2 -2
- package/dist/baseline/producers/secret-hmac.d.ts.map +1 -1
- package/dist/baseline/producers/secret-hmac.js.map +1 -1
- package/dist/baseline/producers/security.d.ts +2 -2
- package/dist/baseline/producers/security.d.ts.map +1 -1
- package/dist/baseline/producers/security.js.map +1 -1
- package/dist/baseline/producers/stale-allow.d.ts +70 -0
- package/dist/baseline/producers/stale-allow.d.ts.map +1 -0
- package/dist/baseline/producers/stale-allow.js +111 -0
- package/dist/baseline/producers/stale-allow.js.map +1 -0
- package/dist/baseline/producers/tests.d.ts +2 -2
- package/dist/baseline/producers/tests.d.ts.map +1 -1
- package/dist/baseline/producers/tests.js.map +1 -1
- package/dist/baseline/ref-baseline.d.ts +114 -0
- package/dist/baseline/ref-baseline.d.ts.map +1 -0
- package/dist/baseline/ref-baseline.js +260 -0
- package/dist/baseline/ref-baseline.js.map +1 -0
- package/dist/baseline/sanitize.d.ts +80 -0
- package/dist/baseline/sanitize.d.ts.map +1 -0
- package/dist/baseline/sanitize.js +91 -0
- package/dist/baseline/sanitize.js.map +1 -0
- package/dist/baseline/show.d.ts.map +1 -1
- package/dist/baseline/show.js +9 -3
- package/dist/baseline/show.js.map +1 -1
- package/dist/baseline/types.d.ts +73 -26
- package/dist/baseline/types.d.ts.map +1 -1
- package/dist/baseline/types.js +7 -1
- package/dist/baseline/types.js.map +1 -1
- package/dist/baseline/visibility.d.ts +61 -0
- package/dist/baseline/visibility.d.ts.map +1 -0
- package/dist/baseline/visibility.js +121 -0
- package/dist/baseline/visibility.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +88 -3
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +106 -16
- package/dist/doctor.js.map +1 -1
- package/dist/issue-cli.d.ts +62 -0
- package/dist/issue-cli.d.ts.map +1 -0
- package/dist/issue-cli.js +252 -0
- package/dist/issue-cli.js.map +1 -0
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +1 -0
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +1 -0
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +1 -0
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +1 -0
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +1 -0
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +1 -0
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +1 -0
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +25 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +1 -0
- package/dist/languages/typescript.js.map +1 -1
- package/package.json +1 -1
- package/templates/.claude/skills/dxkit-action/SKILL.md +105 -11
- package/templates/.claude/skills/dxkit-onboard/SKILL.md +31 -3
- package/dist/baseline/producers/licenses.d.ts +0 -23
- package/dist/baseline/producers/licenses.d.ts.map +0 -1
- package/dist/baseline/producers/licenses.js +0 -46
- package/dist/baseline/producers/licenses.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,170 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.6.0] - 2026-05-23
|
|
11
|
+
|
|
12
|
+
The "per-finding suppression + public-repo-safe baselines" release.
|
|
13
|
+
Adds the typed-category allowlist surface for false-positive /
|
|
14
|
+
test-fixture / mitigated-externally / accepted-risk / deferred
|
|
15
|
+
suppression with inline + file-level modes; retires license
|
|
16
|
+
findings from the baseline (~73% size drop on real customer repos);
|
|
17
|
+
introduces three baseline modes with visibility-aware defaults so
|
|
18
|
+
public repos no longer leak file paths, package names, and
|
|
19
|
+
advisory IDs through a committed baseline.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Per-finding allowlist** — `vyuh-dxkit allowlist add/list/show/audit/prune`.
|
|
24
|
+
Typed-category suppression (`false-positive`, `test-fixture`,
|
|
25
|
+
`mitigated-externally`, `accepted-risk`, `deferred`) with required
|
|
26
|
+
reason + (where relevant) expiry. Two surfaces: inline
|
|
27
|
+
`// dxkit-allow:<category> reason="..."` annotations and a
|
|
28
|
+
file-level `.dxkit/allowlist.json`. `accepted-risk` and `deferred`
|
|
29
|
+
require expiry (default 90 days). See
|
|
30
|
+
[docs/commands/allowlist.md](docs/commands/allowlist.md).
|
|
31
|
+
- **Strict stale-annotation detection** — orphaned `dxkit-allow:`
|
|
32
|
+
annotations (where the underlying finding is now gone) emit a
|
|
33
|
+
new `stale-allow` baseline kind on the next scan. The
|
|
34
|
+
TypeScript `@ts-expect-error` pattern, applied to suppressions —
|
|
35
|
+
forces cleanup, prevents the annotation graveyard. Allowlisting
|
|
36
|
+
a `stale-allow` finding is forbidden; only remediation is to
|
|
37
|
+
remove the orphaned comment.
|
|
38
|
+
- **Allowlist activity in PR comments** — the
|
|
39
|
+
`dxkit-guardrails.yml` workflow's sticky PR comment now includes
|
|
40
|
+
an "Allowlist activity" section listing every entry added (or
|
|
41
|
+
removed) on this branch versus the baseline commit. Reviewers
|
|
42
|
+
see new suppressions being introduced and can sanity-check
|
|
43
|
+
category + reason + expiry before approving.
|
|
44
|
+
- **`vyuh-dxkit issue`** — pre-filled GitHub Issues for false
|
|
45
|
+
positives, missing findings, bugs, feature requests, and docs
|
|
46
|
+
gaps. Nothing submits automatically — the CLI opens the
|
|
47
|
+
customer's browser at a new-issue URL with env metadata
|
|
48
|
+
pre-populated, customer reviews + clicks "Submit." See
|
|
49
|
+
[docs/commands/issue.md](docs/commands/issue.md).
|
|
50
|
+
- **`commentSyntax` on language packs** — each pack declares its
|
|
51
|
+
line-comment marker (`#` for python/ruby; `//` for
|
|
52
|
+
typescript/go/rust/csharp/kotlin/java). Drives the inline
|
|
53
|
+
allowlist-annotation generator across every language uniformly.
|
|
54
|
+
Recipe-enforced: scaffolder ships an empty placeholder so
|
|
55
|
+
unfilled packs fail the contract test until populated.
|
|
56
|
+
- Three preemptive architecture rules in `scripts/check-architecture.sh`
|
|
57
|
+
lock down the allowlist canonical entry points: no `createHash`
|
|
58
|
+
inside `src/allowlist/`, no direct `allowlist.json` IO outside
|
|
59
|
+
the canonical loader, no language-comment fallback literals
|
|
60
|
+
(`?? '//'`) anywhere in the module.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **License findings retired from the baseline.** Per-package
|
|
65
|
+
license attributions no longer flow through the baseline
|
|
66
|
+
producer registry — they were informational, not regression
|
|
67
|
+
material, and dominated baselines on real customer repos
|
|
68
|
+
(~73% of entries). The canonical license inventory now lives
|
|
69
|
+
solely in `.dxkit/bom.json` (`vyuh-dxkit bom`), which already
|
|
70
|
+
carries richer per-package data (licenseType, licenseText,
|
|
71
|
+
sourceUrl, supplier, releaseDate). Lenient migration:
|
|
72
|
+
baselines written by older dxkit versions still load — the
|
|
73
|
+
reader silently filters retired `license` entries on the way
|
|
74
|
+
in (no file rewrite until the next `baseline create --force`).
|
|
75
|
+
Dependency vulnerability tracking is unchanged — `dep-vuln`
|
|
76
|
+
is a separate identity kind on a separate producer and still
|
|
77
|
+
blocks via the guardrail check.
|
|
78
|
+
- **Sanitization machinery for baseline entries.** New pure
|
|
79
|
+
module `src/baseline/sanitize.ts` introduces a stripped
|
|
80
|
+
`SanitizedBaselineEntry` variant (`{ id, kind, sanitized: true }`)
|
|
81
|
+
carrying identity + kind only. The `sanitizeEntry` /
|
|
82
|
+
`sanitizeFile` pass collapses every rich field; cross-run
|
|
83
|
+
matching still works at full confidence via the fingerprint
|
|
84
|
+
multiset pass. Producers now emit the rich
|
|
85
|
+
`RichBaselineEntry` shape (a `BaselineEntry` excluding the
|
|
86
|
+
sanitized variant); sanitization is a write-time
|
|
87
|
+
transformation, never a producer concern. Consumers walking
|
|
88
|
+
a baseline narrow via the `isSanitized` type guard before
|
|
89
|
+
switching on `entry.kind`. Write-path wiring + visibility-
|
|
90
|
+
aware mode selection ship in a follow-up commit.
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **Three baseline modes with visibility-aware defaults.**
|
|
95
|
+
`committed-full` (today's behavior, rich entries), `committed-
|
|
96
|
+
sanitized` (stripped per-entry payload via the sanitization
|
|
97
|
+
pass), and `ref-based` (no committed file; guardrail check
|
|
98
|
+
recomputes the prior side from a git ref via `git worktree
|
|
99
|
+
add`). The mode is picked by a single resolver
|
|
100
|
+
(`src/baseline/modes.ts`) with precedence: CLI flag →
|
|
101
|
+
`.dxkit/policy.json:baseline.mode` → visibility-derived default
|
|
102
|
+
(public repos auto-pick `ref-based`; everything else picks
|
|
103
|
+
`committed-full`). `committed-sanitized` is never auto-picked
|
|
104
|
+
— it's the explicit opt-in for compliance-conscious private
|
|
105
|
+
repos.
|
|
106
|
+
- `vyuh-dxkit baseline create [--mode <m>] [--ref <r>]` and
|
|
107
|
+
`vyuh-dxkit guardrail check [--mode <m>] [--ref <r>]` — flags
|
|
108
|
+
override `policy.json` for one-off runs.
|
|
109
|
+
- `gh repo view --json visibility` probe + per-process cache
|
|
110
|
+
in `src/baseline/visibility.ts`. Every failure path returns
|
|
111
|
+
`'unknown'`; the resolver treats unknown as private to avoid
|
|
112
|
+
surprise sanitization when `gh auth` lapses.
|
|
113
|
+
- Ref-based gather mechanics in `src/baseline/ref-baseline.ts` —
|
|
114
|
+
`withRefWorktree(opts, fn)` is the reusable primitive; tears
|
|
115
|
+
down the worktree on success + failure. Mirrors file-mode
|
|
116
|
+
`.dxkit/salt` into the worktree so secret-HMAC entries pair
|
|
117
|
+
across cwd + worktree.
|
|
118
|
+
|
|
119
|
+
### Architectural notes
|
|
120
|
+
|
|
121
|
+
- New CLAUDE.md rule 11: baseline mode resolution flows through
|
|
122
|
+
`resolveBaselineMode`. Two arch-check rules lock the contract:
|
|
123
|
+
no `gh repo view --json visibility` outside
|
|
124
|
+
`src/baseline/visibility.ts`; no `git worktree add` / `remove`
|
|
125
|
+
outside `src/baseline/ref-baseline.ts`.
|
|
126
|
+
- `resolvePolicy` lifted from `check.ts` to `policy.ts` so
|
|
127
|
+
`createBaseline` and `runGuardrailCheck` share one canonical
|
|
128
|
+
loader.
|
|
129
|
+
|
|
130
|
+
### Discovery surfaces
|
|
131
|
+
|
|
132
|
+
- **PR-comment markdown** now shows the resolved baseline mode in
|
|
133
|
+
the sticky footer (`_Mode_: \`ref-based\` (ref: \`origin/main\`)`).
|
|
134
|
+
Reviewers see WHY a guardrail run picked a given posture.
|
|
135
|
+
- **JSON renderer** carries `baseline.mode = { value, source,
|
|
136
|
+
explanation, ref? }` so agents + dashboards can read the audit
|
|
137
|
+
trail without re-deriving it.
|
|
138
|
+
- **`vyuh-dxkit doctor`** has two new operational checks:
|
|
139
|
+
- "baseline mode: ref-based" / "baseline captured (mode: ...)" —
|
|
140
|
+
the existing baseline-captured check now understands ref-based
|
|
141
|
+
mode (where no on-disk file is expected) so the doctor stops
|
|
142
|
+
reporting a false-negative on public repos.
|
|
143
|
+
- "baseline mode aligned with repo visibility" — warns when an
|
|
144
|
+
explicit `committed-full` pin is in use on a public repo (the
|
|
145
|
+
posture leaks file paths + package names; the auto-picker
|
|
146
|
+
would have chosen ref-based).
|
|
147
|
+
- **`dxkit-onboard` skill** — step 5 now ASKs about disclosure
|
|
148
|
+
posture before running `baseline create`, walks customers through
|
|
149
|
+
the three modes, and offers a one-shot `.dxkit/policy.json` snippet
|
|
150
|
+
for pinning the choice repo-wide.
|
|
151
|
+
- **`dxkit-action` skill** — new section explains how to act on a
|
|
152
|
+
blocked finding when the baseline is sanitized / ref-based
|
|
153
|
+
(locator stripped at write time; re-run the analyzer for full
|
|
154
|
+
context or allowlist by fingerprint).
|
|
155
|
+
- **README + getting-started.md** — call out the public-repo
|
|
156
|
+
posture explicitly so customers don't accidentally commit a
|
|
157
|
+
rich baseline to an open-source repo.
|
|
158
|
+
|
|
159
|
+
### Architectural notes
|
|
160
|
+
|
|
161
|
+
- Added `stale-allow` as a new `IdentityKind` (Rule 9 + Rule 10
|
|
162
|
+
compliant: identityFor case + producer + fixture row +
|
|
163
|
+
removed from `DEFERRED_KINDS` once the gather pass landed).
|
|
164
|
+
- The hint formatter (block-time guidance for blocked findings)
|
|
165
|
+
consumes the canonical `BaselineEntry` discriminated union
|
|
166
|
+
directly — no invented intermediate "BlockingFinding" shape.
|
|
167
|
+
TypeScript exhaustiveness across 6+ switches guarantees new
|
|
168
|
+
finding kinds can't ship without matching cases.
|
|
169
|
+
- `dxkit-action` skill extended with the typed-category +
|
|
170
|
+
surfaces description; SAST recipe redirects from semgrep's
|
|
171
|
+
`// nosemgrep:` to dxkit's `// dxkit-allow:` (single canonical
|
|
172
|
+
suppression surface across all scanners).
|
|
173
|
+
|
|
10
174
|
## [2.5.2] - 2026-05-22
|
|
11
175
|
|
|
12
176
|
The "scaffold UX + lifecycle skills + setup automation" release. Closes
|
package/README.md
CHANGED
|
@@ -234,6 +234,86 @@ The classifier distinguishes:
|
|
|
234
234
|
Customize via [`.dxkit/policy.json`](docs/configuration/policy.md) —
|
|
235
235
|
auto-discovered when present, compiled-in defaults otherwise.
|
|
236
236
|
|
|
237
|
+
### Baseline modes — public vs private repos
|
|
238
|
+
|
|
239
|
+
The baseline file is committed to git. On public repos that
|
|
240
|
+
disclosure surface matters: a `committed-full` baseline tells anyone
|
|
241
|
+
reading the repo which file/line each finding lives on, which
|
|
242
|
+
private packages you depend on, and which advisory IDs you're
|
|
243
|
+
sitting on unpatched. dxkit ships three modes:
|
|
244
|
+
|
|
245
|
+
| Mode | On-disk content | Auto-default for |
|
|
246
|
+
| --------------------- | -------------------------------------------------------- | ---------------- |
|
|
247
|
+
| `committed-full` | Rich entries (file/line/rule/package/advisory) | private repos |
|
|
248
|
+
| `committed-sanitized` | Stripped to `{ id, kind }` per finding | opt-in |
|
|
249
|
+
| `ref-based` | No file — guardrail recomputes prior side from a git ref | public repos |
|
|
250
|
+
|
|
251
|
+
`vyuh-dxkit baseline create` auto-picks via
|
|
252
|
+
`gh repo view --json visibility`. Pin the choice repo-wide in
|
|
253
|
+
`.dxkit/policy.json`:
|
|
254
|
+
|
|
255
|
+
```json
|
|
256
|
+
{ "baseline": { "mode": "ref-based", "ref": "origin/main" } }
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The cross-run matching contract (fingerprint identity) is identical
|
|
260
|
+
across all three modes — sanitization only strips human-readable
|
|
261
|
+
locators, it doesn't change which findings pair across runs. See
|
|
262
|
+
[docs/commands/baseline.md](docs/commands/baseline.md#modes) for the
|
|
263
|
+
full trade-off discussion.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Allowlist: per-finding suppression
|
|
268
|
+
|
|
269
|
+
The baseline handles codebase-wide brownfield acceptance ("today's
|
|
270
|
+
mess is grandfathered; tomorrow's must be net-new improvement").
|
|
271
|
+
For per-finding decisions — false positives, intentional test
|
|
272
|
+
fixtures, externally-mitigated risks, deliberately deferred work —
|
|
273
|
+
use the [allowlist](docs/commands/allowlist.md).
|
|
274
|
+
|
|
275
|
+
Five typed categories signal **why** a finding is suppressed:
|
|
276
|
+
|
|
277
|
+
| Category | Meaning | Expiry |
|
|
278
|
+
| ---------------------- | ------------------------------------------------- | ------------------------------ |
|
|
279
|
+
| `false-positive` | Scanner is wrong about this finding | Optional |
|
|
280
|
+
| `test-fixture` | Intentional pattern in fixture / test code | Optional |
|
|
281
|
+
| `mitigated-externally` | Real risk neutralized at runtime (WAF, env, etc.) | Optional |
|
|
282
|
+
| `accepted-risk` | Real risk, team accepts, signed off | **Required** (default 90 days) |
|
|
283
|
+
| `deferred` | Real, will fix later, tracked work | **Required** |
|
|
284
|
+
|
|
285
|
+
Two surfaces. Inline annotation for source-anchored findings:
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
api_key = "sk_test_xxxx" # dxkit-allow:test-fixture reason="placeholder in unit test"
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
File-level (`.dxkit/allowlist.json`) for cross-file findings or any
|
|
292
|
+
suppression that needs an expiry. New entries appear in the PR-
|
|
293
|
+
comment automation so reviewers see suppressions being introduced
|
|
294
|
+
and can sanity-check the rationale before approving. `audit` /
|
|
295
|
+
`prune` subcommands handle stale + soon-to-expire entries.
|
|
296
|
+
|
|
297
|
+
**Strict cleanup**: orphaned `dxkit-allow:` annotations become
|
|
298
|
+
`stale-allow` findings on the next scan. dxkit refuses to allowlist
|
|
299
|
+
those — the only remediation is to remove the annotation. This is
|
|
300
|
+
the TypeScript `@ts-expect-error` pattern: tools that surface their
|
|
301
|
+
own stale suppressions force cleanup, preventing the annotation
|
|
302
|
+
graveyard.
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# The block message from `guardrail check` prints the exact command
|
|
306
|
+
# to paste for any blocked finding — file:line for inline-compatible
|
|
307
|
+
# kinds, --fingerprint for everything else.
|
|
308
|
+
vyuh-dxkit allowlist add src/auth/oauth.ts:42 \
|
|
309
|
+
--category=test-fixture --reason="placeholder in unit test"
|
|
310
|
+
|
|
311
|
+
vyuh-dxkit allowlist audit # find stale + soon-to-expire entries
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
See [`vyuh-dxkit allowlist`](docs/commands/allowlist.md) for the
|
|
315
|
+
full surface.
|
|
316
|
+
|
|
237
317
|
---
|
|
238
318
|
|
|
239
319
|
## Git-aware identity matching
|
|
@@ -459,6 +539,28 @@ dxkit is local-first.
|
|
|
459
539
|
|
|
460
540
|
---
|
|
461
541
|
|
|
542
|
+
## Reporting issues
|
|
543
|
+
|
|
544
|
+
If a scanner is too noisy, a finding is missing, dxkit itself is
|
|
545
|
+
broken, or the docs are unclear, the fastest path to the dxkit team
|
|
546
|
+
is the built-in issue subcommand:
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
vyuh-dxkit issue --type=false-positive \
|
|
550
|
+
--fingerprint=<id> \
|
|
551
|
+
--about="the scanner flags my intentional X as a Y"
|
|
552
|
+
|
|
553
|
+
vyuh-dxkit issue --type=bug --about="vyuh-dxkit doctor crashes on macOS arm64"
|
|
554
|
+
|
|
555
|
+
vyuh-dxkit issue --type=feature-request --about="add SARIF export"
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
It opens a pre-filled [GitHub issue](https://github.com/vyuh-labs/dxkit/issues)
|
|
559
|
+
in your browser with dxkit version + platform info already populated.
|
|
560
|
+
Nothing is submitted until you click "Submit" — you review the
|
|
561
|
+
prefill first. See [`vyuh-dxkit issue`](docs/commands/issue.md) for
|
|
562
|
+
the full reference.
|
|
563
|
+
|
|
462
564
|
## Contributing
|
|
463
565
|
|
|
464
566
|
dxkit aims to be the standard agentic-development layer for any
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowlist category taxonomy. Single source of truth for:
|
|
3
|
+
* - Which categories exist
|
|
4
|
+
* - Which categories require an expiry date
|
|
5
|
+
* - Which categories may be expressed via inline source annotation
|
|
6
|
+
* - Which categories apply to each `IdentityKind`
|
|
7
|
+
* - Which finding kinds support inline annotations at all
|
|
8
|
+
*
|
|
9
|
+
* Pure module — no I/O, no analyzer dependencies. Consumed by the
|
|
10
|
+
* allowlist file reader/writer, the inline-annotation parser, the
|
|
11
|
+
* CLI, the block-time hint formatter, and the new `allowlistHits`
|
|
12
|
+
* baseline producer.
|
|
13
|
+
*
|
|
14
|
+
* See tmp/2.6-allowlist-design.md for the design discussion.
|
|
15
|
+
*/
|
|
16
|
+
import type { IdentityKind } from '../baseline/producers';
|
|
17
|
+
/**
|
|
18
|
+
* Single source of truth for category values. The `AllowlistCategory`
|
|
19
|
+
* union type is derived from this array via `(typeof ...)[number]`,
|
|
20
|
+
* so adding a new category means appending one string here and every
|
|
21
|
+
* type-level check (Record-keyed tables, switch exhaustiveness,
|
|
22
|
+
* function parameter types) auto-updates. No two-place drift.
|
|
23
|
+
*/
|
|
24
|
+
export declare const ALL_CATEGORIES: readonly ["false-positive", "test-fixture", "mitigated-externally", "accepted-risk", "deferred"];
|
|
25
|
+
export type AllowlistCategory = (typeof ALL_CATEGORIES)[number];
|
|
26
|
+
/**
|
|
27
|
+
* Categories that REQUIRE a finite expiry date. The file-level
|
|
28
|
+
* allowlist write-path rejects entries in these categories without
|
|
29
|
+
* an `expiresAt`. The CLI defaults `expiresAt` to 90 days out for
|
|
30
|
+
* these — see `defaultExpiryDate`.
|
|
31
|
+
*
|
|
32
|
+
* Categories OUTSIDE this set represent stable assertions about the
|
|
33
|
+
* code that don't naturally stale (a test fixture remains a test
|
|
34
|
+
* fixture; a false positive remains a false positive until the
|
|
35
|
+
* scanner rule changes). They may carry an `expiresAt` if the
|
|
36
|
+
* customer chooses, but it's not enforced.
|
|
37
|
+
*/
|
|
38
|
+
export declare const EXPIRING_CATEGORIES: ReadonlySet<AllowlistCategory>;
|
|
39
|
+
/**
|
|
40
|
+
* Categories that may be expressed via inline source annotation
|
|
41
|
+
* (`// dxkit-allow:<category> reason="..."`). The complement
|
|
42
|
+
* (`accepted-risk`, `deferred`) is file-only because those categories
|
|
43
|
+
* need fields (expiresAt, acknowledgedSeverity) that don't fit
|
|
44
|
+
* cleanly into a code comment.
|
|
45
|
+
*/
|
|
46
|
+
export declare const INLINE_COMPATIBLE_CATEGORIES: ReadonlySet<AllowlistCategory>;
|
|
47
|
+
/**
|
|
48
|
+
* Finding kinds that have a stable single-line attachment point and
|
|
49
|
+
* therefore support inline annotations. Kinds outside this set are
|
|
50
|
+
* file-only (whole-file findings, cross-file findings, gap findings).
|
|
51
|
+
*
|
|
52
|
+
* Inline-compatible:
|
|
53
|
+
* - `secret` / `secret-hmac`: the source line is the credential
|
|
54
|
+
* - `code` / `config`: the source line is the flagged pattern
|
|
55
|
+
* - `dep-vuln`: annotate the import or first-use line
|
|
56
|
+
* - `hygiene`: the source line carries the TODO/FIXME/HACK marker
|
|
57
|
+
*
|
|
58
|
+
* File-only (no single-line site):
|
|
59
|
+
* - `duplication`: two locations across files
|
|
60
|
+
* - `coverage-gap` / `test-gap` / `test-file-degradation`: file or
|
|
61
|
+
* symbol-range level, not single-line
|
|
62
|
+
* - `god-file` / `large-file` / `stale-file`: whole-file findings
|
|
63
|
+
*/
|
|
64
|
+
export declare const INLINE_COMPATIBLE_KINDS: ReadonlySet<IdentityKind>;
|
|
65
|
+
/**
|
|
66
|
+
* Categories applicable to each `IdentityKind`. Reflects what
|
|
67
|
+
* suppression rationales the kind can plausibly carry — a
|
|
68
|
+
* `coverage-gap` is rarely a "false positive" in the same way a
|
|
69
|
+
* scanner finding is; a `dep-vuln` is rarely a "test fixture."
|
|
70
|
+
*
|
|
71
|
+
* The CLI presents the applicable list as a multiple-choice prompt
|
|
72
|
+
* when the customer runs `vyuh-dxkit allowlist add` against a
|
|
73
|
+
* finding.
|
|
74
|
+
*
|
|
75
|
+
* The `Record<IdentityKind, ...>` ties this table to the canonical
|
|
76
|
+
* union: TypeScript fails the build when a new `IdentityKind`
|
|
77
|
+
* variant lands without a corresponding entry here.
|
|
78
|
+
*/
|
|
79
|
+
export declare const CATEGORIES_BY_KIND: Readonly<Record<IdentityKind, readonly AllowlistCategory[]>>;
|
|
80
|
+
/**
|
|
81
|
+
* Whether a (kind, category) tuple may be expressed as an inline
|
|
82
|
+
* annotation. Both the kind AND the category must be inline-compatible.
|
|
83
|
+
*
|
|
84
|
+
* Examples:
|
|
85
|
+
* canUseInline('secret', 'test-fixture') // true
|
|
86
|
+
* canUseInline('secret', 'accepted-risk') // false (category file-only)
|
|
87
|
+
* canUseInline('large-file', 'false-positive') // false (kind file-only)
|
|
88
|
+
* canUseInline('hygiene', 'accepted-risk') // false (category file-only)
|
|
89
|
+
*/
|
|
90
|
+
export declare function canUseInline(kind: IdentityKind, category: AllowlistCategory): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Whether a category requires `expiresAt` on the file-level entry.
|
|
93
|
+
* Source of truth for the write-path validation rule.
|
|
94
|
+
*/
|
|
95
|
+
export declare function requiresExpiry(category: AllowlistCategory): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Whether a (kind, category) tuple is semantically valid. The CLI
|
|
98
|
+
* uses this to reject incoherent combinations like
|
|
99
|
+
* `coverage-gap + false-positive` with a clear error pointing at
|
|
100
|
+
* the applicable categories for that kind.
|
|
101
|
+
*/
|
|
102
|
+
export declare function isCategoryValidForKind(kind: IdentityKind, category: AllowlistCategory): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Number of days into the future the CLI defaults `expiresAt` to
|
|
105
|
+
* when the customer doesn't specify one. Locked at 90 in Sprint 0
|
|
106
|
+
* (Snyk + Dependabot industry default). Per-category overrides will
|
|
107
|
+
* land in `.dxkit/policy.json` (`allowlist.defaultExpiryDays`) in a
|
|
108
|
+
* follow-up commit if real customer signal demands it.
|
|
109
|
+
*/
|
|
110
|
+
export declare const DEFAULT_EXPIRY_DAYS = 90;
|
|
111
|
+
/**
|
|
112
|
+
* Compute the default expiry date as an ISO `YYYY-MM-DD` string,
|
|
113
|
+
* `DEFAULT_EXPIRY_DAYS` from `now`. UTC-anchored to keep the date
|
|
114
|
+
* stable across timezone-different developers on the same team.
|
|
115
|
+
*
|
|
116
|
+
* `now` is injected for deterministic testing — production callers
|
|
117
|
+
* pass `new Date()` (the default).
|
|
118
|
+
*/
|
|
119
|
+
export declare function defaultExpiryDate(now?: Date): string;
|
|
120
|
+
//# sourceMappingURL=categories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/allowlist/categories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,kGAMjB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,iBAAiB,CAG7D,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,iBAAiB,CAItE,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,YAAY,CAO5D,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAAC,CA6C3F,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAErF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAE/F;AAED;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM,CAIhE"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Allowlist category taxonomy. Single source of truth for:
|
|
4
|
+
* - Which categories exist
|
|
5
|
+
* - Which categories require an expiry date
|
|
6
|
+
* - Which categories may be expressed via inline source annotation
|
|
7
|
+
* - Which categories apply to each `IdentityKind`
|
|
8
|
+
* - Which finding kinds support inline annotations at all
|
|
9
|
+
*
|
|
10
|
+
* Pure module — no I/O, no analyzer dependencies. Consumed by the
|
|
11
|
+
* allowlist file reader/writer, the inline-annotation parser, the
|
|
12
|
+
* CLI, the block-time hint formatter, and the new `allowlistHits`
|
|
13
|
+
* baseline producer.
|
|
14
|
+
*
|
|
15
|
+
* See tmp/2.6-allowlist-design.md for the design discussion.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.DEFAULT_EXPIRY_DAYS = exports.CATEGORIES_BY_KIND = exports.INLINE_COMPATIBLE_KINDS = exports.INLINE_COMPATIBLE_CATEGORIES = exports.EXPIRING_CATEGORIES = exports.ALL_CATEGORIES = void 0;
|
|
19
|
+
exports.canUseInline = canUseInline;
|
|
20
|
+
exports.requiresExpiry = requiresExpiry;
|
|
21
|
+
exports.isCategoryValidForKind = isCategoryValidForKind;
|
|
22
|
+
exports.defaultExpiryDate = defaultExpiryDate;
|
|
23
|
+
/**
|
|
24
|
+
* Single source of truth for category values. The `AllowlistCategory`
|
|
25
|
+
* union type is derived from this array via `(typeof ...)[number]`,
|
|
26
|
+
* so adding a new category means appending one string here and every
|
|
27
|
+
* type-level check (Record-keyed tables, switch exhaustiveness,
|
|
28
|
+
* function parameter types) auto-updates. No two-place drift.
|
|
29
|
+
*/
|
|
30
|
+
exports.ALL_CATEGORIES = [
|
|
31
|
+
'false-positive',
|
|
32
|
+
'test-fixture',
|
|
33
|
+
'mitigated-externally',
|
|
34
|
+
'accepted-risk',
|
|
35
|
+
'deferred',
|
|
36
|
+
];
|
|
37
|
+
/**
|
|
38
|
+
* Categories that REQUIRE a finite expiry date. The file-level
|
|
39
|
+
* allowlist write-path rejects entries in these categories without
|
|
40
|
+
* an `expiresAt`. The CLI defaults `expiresAt` to 90 days out for
|
|
41
|
+
* these — see `defaultExpiryDate`.
|
|
42
|
+
*
|
|
43
|
+
* Categories OUTSIDE this set represent stable assertions about the
|
|
44
|
+
* code that don't naturally stale (a test fixture remains a test
|
|
45
|
+
* fixture; a false positive remains a false positive until the
|
|
46
|
+
* scanner rule changes). They may carry an `expiresAt` if the
|
|
47
|
+
* customer chooses, but it's not enforced.
|
|
48
|
+
*/
|
|
49
|
+
exports.EXPIRING_CATEGORIES = new Set([
|
|
50
|
+
'accepted-risk',
|
|
51
|
+
'deferred',
|
|
52
|
+
]);
|
|
53
|
+
/**
|
|
54
|
+
* Categories that may be expressed via inline source annotation
|
|
55
|
+
* (`// dxkit-allow:<category> reason="..."`). The complement
|
|
56
|
+
* (`accepted-risk`, `deferred`) is file-only because those categories
|
|
57
|
+
* need fields (expiresAt, acknowledgedSeverity) that don't fit
|
|
58
|
+
* cleanly into a code comment.
|
|
59
|
+
*/
|
|
60
|
+
exports.INLINE_COMPATIBLE_CATEGORIES = new Set([
|
|
61
|
+
'false-positive',
|
|
62
|
+
'test-fixture',
|
|
63
|
+
'mitigated-externally',
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* Finding kinds that have a stable single-line attachment point and
|
|
67
|
+
* therefore support inline annotations. Kinds outside this set are
|
|
68
|
+
* file-only (whole-file findings, cross-file findings, gap findings).
|
|
69
|
+
*
|
|
70
|
+
* Inline-compatible:
|
|
71
|
+
* - `secret` / `secret-hmac`: the source line is the credential
|
|
72
|
+
* - `code` / `config`: the source line is the flagged pattern
|
|
73
|
+
* - `dep-vuln`: annotate the import or first-use line
|
|
74
|
+
* - `hygiene`: the source line carries the TODO/FIXME/HACK marker
|
|
75
|
+
*
|
|
76
|
+
* File-only (no single-line site):
|
|
77
|
+
* - `duplication`: two locations across files
|
|
78
|
+
* - `coverage-gap` / `test-gap` / `test-file-degradation`: file or
|
|
79
|
+
* symbol-range level, not single-line
|
|
80
|
+
* - `god-file` / `large-file` / `stale-file`: whole-file findings
|
|
81
|
+
*/
|
|
82
|
+
exports.INLINE_COMPATIBLE_KINDS = new Set([
|
|
83
|
+
'secret',
|
|
84
|
+
'secret-hmac',
|
|
85
|
+
'code',
|
|
86
|
+
'config',
|
|
87
|
+
'dep-vuln',
|
|
88
|
+
'hygiene',
|
|
89
|
+
]);
|
|
90
|
+
/**
|
|
91
|
+
* Categories applicable to each `IdentityKind`. Reflects what
|
|
92
|
+
* suppression rationales the kind can plausibly carry — a
|
|
93
|
+
* `coverage-gap` is rarely a "false positive" in the same way a
|
|
94
|
+
* scanner finding is; a `dep-vuln` is rarely a "test fixture."
|
|
95
|
+
*
|
|
96
|
+
* The CLI presents the applicable list as a multiple-choice prompt
|
|
97
|
+
* when the customer runs `vyuh-dxkit allowlist add` against a
|
|
98
|
+
* finding.
|
|
99
|
+
*
|
|
100
|
+
* The `Record<IdentityKind, ...>` ties this table to the canonical
|
|
101
|
+
* union: TypeScript fails the build when a new `IdentityKind`
|
|
102
|
+
* variant lands without a corresponding entry here.
|
|
103
|
+
*/
|
|
104
|
+
exports.CATEGORIES_BY_KIND = {
|
|
105
|
+
// Source-level security findings: every category applies
|
|
106
|
+
secret: ['false-positive', 'test-fixture', 'mitigated-externally', 'accepted-risk', 'deferred'],
|
|
107
|
+
'secret-hmac': [
|
|
108
|
+
'false-positive',
|
|
109
|
+
'test-fixture',
|
|
110
|
+
'mitigated-externally',
|
|
111
|
+
'accepted-risk',
|
|
112
|
+
'deferred',
|
|
113
|
+
],
|
|
114
|
+
code: ['false-positive', 'test-fixture', 'mitigated-externally', 'accepted-risk', 'deferred'],
|
|
115
|
+
config: ['false-positive', 'test-fixture', 'mitigated-externally', 'accepted-risk', 'deferred'],
|
|
116
|
+
// Dependency vulnerabilities: rarely a test fixture (the dep is real);
|
|
117
|
+
// every other category applies
|
|
118
|
+
'dep-vuln': ['false-positive', 'mitigated-externally', 'accepted-risk', 'deferred'],
|
|
119
|
+
// Duplicate blocks: occasionally a false positive (jscpd matched
|
|
120
|
+
// generated code); otherwise accepted-risk or deferred
|
|
121
|
+
duplication: ['false-positive', 'accepted-risk', 'deferred'],
|
|
122
|
+
// Coverage / test gaps: not "false-positive" in any practical sense;
|
|
123
|
+
// only accepted-risk or deferred
|
|
124
|
+
'coverage-gap': ['accepted-risk', 'deferred'],
|
|
125
|
+
'test-gap': ['accepted-risk', 'deferred'],
|
|
126
|
+
'test-file-degradation': ['accepted-risk', 'deferred'],
|
|
127
|
+
// Whole-file findings: false-positive (file IS not actually large /
|
|
128
|
+
// stale / god when reviewed); otherwise accepted-risk or deferred
|
|
129
|
+
'god-file': ['false-positive', 'accepted-risk', 'deferred'],
|
|
130
|
+
'large-file': ['false-positive', 'accepted-risk', 'deferred'],
|
|
131
|
+
'stale-file': ['false-positive', 'accepted-risk', 'deferred'],
|
|
132
|
+
// TODO / FIXME / HACK / console-log / any-type markers: only
|
|
133
|
+
// accepted-risk or deferred (the marker IS the hygiene issue)
|
|
134
|
+
hygiene: ['accepted-risk', 'deferred'],
|
|
135
|
+
// Stale-allow (orphaned inline allowlist annotation): never
|
|
136
|
+
// allowlisted. The right response is always "remove the stale
|
|
137
|
+
// annotation" — allowlisting the warning that an annotation is
|
|
138
|
+
// stale would defeat the entire strict-stale-detection model
|
|
139
|
+
// (TypeScript's @ts-expect-error pattern). Empty array means the
|
|
140
|
+
// CLI rejects with a hint pointing at the annotation's source
|
|
141
|
+
// location.
|
|
142
|
+
'stale-allow': [],
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Whether a (kind, category) tuple may be expressed as an inline
|
|
146
|
+
* annotation. Both the kind AND the category must be inline-compatible.
|
|
147
|
+
*
|
|
148
|
+
* Examples:
|
|
149
|
+
* canUseInline('secret', 'test-fixture') // true
|
|
150
|
+
* canUseInline('secret', 'accepted-risk') // false (category file-only)
|
|
151
|
+
* canUseInline('large-file', 'false-positive') // false (kind file-only)
|
|
152
|
+
* canUseInline('hygiene', 'accepted-risk') // false (category file-only)
|
|
153
|
+
*/
|
|
154
|
+
function canUseInline(kind, category) {
|
|
155
|
+
return exports.INLINE_COMPATIBLE_KINDS.has(kind) && exports.INLINE_COMPATIBLE_CATEGORIES.has(category);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Whether a category requires `expiresAt` on the file-level entry.
|
|
159
|
+
* Source of truth for the write-path validation rule.
|
|
160
|
+
*/
|
|
161
|
+
function requiresExpiry(category) {
|
|
162
|
+
return exports.EXPIRING_CATEGORIES.has(category);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Whether a (kind, category) tuple is semantically valid. The CLI
|
|
166
|
+
* uses this to reject incoherent combinations like
|
|
167
|
+
* `coverage-gap + false-positive` with a clear error pointing at
|
|
168
|
+
* the applicable categories for that kind.
|
|
169
|
+
*/
|
|
170
|
+
function isCategoryValidForKind(kind, category) {
|
|
171
|
+
return exports.CATEGORIES_BY_KIND[kind].includes(category);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Number of days into the future the CLI defaults `expiresAt` to
|
|
175
|
+
* when the customer doesn't specify one. Locked at 90 in Sprint 0
|
|
176
|
+
* (Snyk + Dependabot industry default). Per-category overrides will
|
|
177
|
+
* land in `.dxkit/policy.json` (`allowlist.defaultExpiryDays`) in a
|
|
178
|
+
* follow-up commit if real customer signal demands it.
|
|
179
|
+
*/
|
|
180
|
+
exports.DEFAULT_EXPIRY_DAYS = 90;
|
|
181
|
+
/**
|
|
182
|
+
* Compute the default expiry date as an ISO `YYYY-MM-DD` string,
|
|
183
|
+
* `DEFAULT_EXPIRY_DAYS` from `now`. UTC-anchored to keep the date
|
|
184
|
+
* stable across timezone-different developers on the same team.
|
|
185
|
+
*
|
|
186
|
+
* `now` is injected for deterministic testing — production callers
|
|
187
|
+
* pass `new Date()` (the default).
|
|
188
|
+
*/
|
|
189
|
+
function defaultExpiryDate(now = new Date()) {
|
|
190
|
+
const expires = new Date(now);
|
|
191
|
+
expires.setUTCDate(expires.getUTCDate() + exports.DEFAULT_EXPIRY_DAYS);
|
|
192
|
+
return expires.toISOString().slice(0, 10);
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=categories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"categories.js","sourceRoot":"","sources":["../../src/allowlist/categories.ts"],"names":[],"mappings":"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"}
|