| name | dxkit-config |
| description | Edit dxkit configuration — add/remove paths in .dxkit-ignore, tune .npx vyuh-dxkit.json, adjust .dxkit/policy.json guardrail severity. Use when the user wants to exclude a directory from scanning, change scoring thresholds, or modify what blocks a PR. |
dxkit-config
This skill modifies the three configuration files dxkit reads. Reach for it when the user asks to "ignore this vendored directory," "stop flagging X," "make the guardrail stricter/laxer," or "what controls Y."
The three config files
| File | Purpose | When to edit |
|---|
.dxkit-ignore | Extra paths dxkit's analyzers should skip (gitignore-style format) | Vendored code, generated code, test fixtures, large data files |
.npx vyuh-dxkit.json | Manifest of detected stack + custom settings (regenerated by init / update) | Rare — usually let dxkit update regenerate. Override version pins or framework detection here. |
.dxkit/policy.json | Severity policy for guardrail check | Customize what blocks a PR (e.g., demote medium to warning) |
.dxkit/tools.json | Where dxkit looks for / installs scanner binaries | Tools live in a non-standard or corp-managed directory, or PATH detection misses them (common on Windows / locked-down machines) |
Adding a path to .dxkit-ignore
Format mirrors .gitignore: directory/, file-glob, multi-segment paths.
echo 'vendor/' >> .dxkit-ignore
echo 'src/generated/' >> .dxkit-ignore
echo '*.generated.ts' >> .dxkit-ignore
Or use Edit to add multiple entries cleanly. The file accepts comments (#).
After editing, the next baseline create picks up the change. Existing baselines stay valid (the file's content hash is recorded in the baseline envelope, so a mismatch surfaces as a "baseline regenerated against newer .dxkit-ignore" note rather than an error).
Common exclusions
# Vendored third-party code committed to git
vendor/
third_party/
# Generated code
generated/
*.generated.ts
*.designer.cs
*.pb.go
src/proto-types/
# Legacy code you don't want to track findings against
legacy/
deprecated/
# Test fixtures that inflate metrics
fixtures/large/
test/fixtures/
# Build artifacts (most are gitignored already, but defensive)
dist/
build/
target/
Tuning .npx vyuh-dxkit.json
This file is mostly auto-generated. Common manual edits:
{
"framework": "express",
"languages": {
"typescript": true,
"python": false
},
"testRunner": {
"framework": "vitest",
"command": "npm test"
}
}
When you edit this file, run npx vyuh-dxkit update to propagate changes through the rest of the scaffold (per-language rules, devcontainer features, etc.). Use --force only if you've also edited evolving files — otherwise update preserves customer changes.
Customizing .dxkit/policy.json
The policy file controls what severity counts as "blocking" for the guardrail. Default:
{
"code": { "block": ["critical", "high"], "warn": ["medium"] },
"dependency": { "block": ["critical", "high"], "warn": ["medium"] },
"secret": { "block": ["critical", "high", "medium", "low"] },
"test-gap": { "block": ["critical"], "warn": ["high"] },
"duplicate": { "warn": ["all"] }
}
Each finding-kind has block (exit 1) and warn (log only) lists. Adjust to your team's tolerance:
{ "code": { "block": ["critical", "high", "medium"] } }
{ "secret": { "block": ["critical", "high"] } }
Run npx vyuh-dxkit guardrail check --policy=.dxkit/policy.json to test the new policy. If no policy.json exists, dxkit uses the built-in defaults.
Switching the loop posture (loop.preset)
A repo running autonomous coding loops behind the dxkit Stop-gate has a loop-only blocking posture under loop.preset in the same file:
{
"loop": { "preset": "security-only" }
}
| Preset | Loop blocks on |
|---|
security-only (default) | net-new secrets + crit/high security + crit/high reachable dependency vulns; test-gap + quality only warn |
full-debt | every net-new finding, including test-gap + quality |
This key is read only by the Stop-gate (vyuh-dxkit hook stop-gate) — your CI / PR guardrail always uses the full policy above, so changing the loop posture never weakens your CI gate. Edit it here, or run npx vyuh-dxkit init --claude-loop --loop-preset full-debt. Use full-debt only when you deliberately want an unattended loop to also close test/quality gaps (it can drive a long repair). For setting up or operating the loop, hand off to the dxkit-loop skill.
Switching the flow-gate posture (flow.mode)
The UI→API integration gate has its own posture under flow.mode in the same file:
{ "flow": { "mode": "warn" } }
warn — surface net-new broken integrations as warnings, never fail a build.
block — fail the check on an exact break (confidence-gated: only fully-specified bindings block).
off — the gate does not run.
The gate is additive and fail-open: it only fires when a change touches a client call / route / spec, and self-skips when there is no served-side truth to check against. Set it up with npx vyuh-dxkit init --flow, or hand off to the dxkit-flow skill for setup / diagnosis / repair.
Switching the schema-gate posture (schema.mode)
The model-schema drift gate (breaking data-model changes) has its own posture under schema.mode:
{ "schema": { "mode": "warn", "specs": ["api/openapi.json"] } }
off — the gate does not run (the capability is opt-in).
warn — net-new breaking drift (field removed, type changed, optional → required) warns, never fails a build.
block — breaking drift fails the check (confidence-gated: an unknown-degraded finding can only warn).
schema.specs — OpenAPI / JSON Schema files whose models gate alongside code extraction (the any-language bridge).
Set it up via npx vyuh-dxkit configure (it plans warn when a data-model framework is detected), or hand off to the dxkit-schema skill for inventory / preview / shipping a deliberate breaking change.
Keeping the code graph fresh in CI (graph.refresh)
The code graph (.dxkit/reports/graph.json) is a gitignored, rebuilt-on-demand artifact. On a large repo, rebuilding it in CI is slow. Opt into a cache transport that keeps it warm:
{ "graph": { "refresh": "cache" } }
cache — installs dxkit-graph-refresh.yml, which rebuilds the graph on merge to the default branch (+ weekly + on demand) and stores it in the GitHub Actions cache keyed by commit SHA. Never committed to git — no repo bloat, no bot commits; caches evict after ~7 idle days. The guardrail run restores it so graph consumers skip a cold rebuild.
off / absent — every consumer rebuilds the graph on demand (the default).
Two ways to enable it: npx vyuh-dxkit init --with-graph-refresh (installs the workflow directly), or set the graph.refresh knob above and run npx vyuh-dxkit update (which lays the workflow down). Either way, update refreshes it and uninstall removes it. Rebuild the graph locally any time with npx vyuh-dxkit explore refresh. It's a CI-performance optimization, not a correctness gate — leave it off unless graph rebuilds are slow.
Publishing report snapshots on merge (reports.onMerge)
Opt into a score-over-time trend: publish a health snapshot on every merge to the default branch, so you can see each dimension's score move release over release.
{ "reports": { "onMerge": true } }
true — installs dxkit-reports-refresh.yml, which renders the full audit on merge (+ weekly + on demand) and publishes a snapshot to a dedicated dxkit-reports side ref via git plumbing. It appends one line to report-history.jsonl and refreshes a browsable latest/ dashboard on that ref — without committing anything to the default branch's tree (same transport the baseline anchor uses, just a distinct ref, so its churn never touches the baseline). Read the trend back with npx vyuh-dxkit report history. Retention is reports.retain (how many snapshots to keep).
- The merge workflow also writes a "score moved X→Y" job summary (per dimension) into the run —
report history --markdown renders that block, so you can drop it into a PR comment too. And npx vyuh-dxkit metrics shows the score-over-time trend alongside the gate's interception ROI, so one command answers both "what did the gate stop" and "how is the score trending".
false / absent — no snapshots are published (the default).
Two ways to enable it: npx vyuh-dxkit init --with-reports-refresh (installs the workflow directly), or set the reports.onMerge knob above and run npx vyuh-dxkit update (which lays the workflow down). Either way, update refreshes it and uninstall removes it. It's a reporting/trend feature, not a correctness gate — leave it off unless you want the merge-time score history.
Flow-contract refresh on merge (policy.json:flow.onMergeRefresh + flow.refreshMode)
Keep the committed flow snapshots (.dxkit/flow/) current automatically — doctor warns when a provider moved past the committed contract; this closes that gap without anyone remembering flow publish.
{ "flow": { "onMergeRefresh": true, "refreshMode": "pr" } }
onMergeRefresh: true — installs dxkit-flow-refresh.yml: after each merge (+ weekly + on demand) it re-runs flow publish and lands any snapshot change per refreshMode.
refreshMode: "pr" (default) — ONE standing dxkit/flow-refresh PR, force-updated in place, whose body is a contract-change summary. Route REMOVALS lead with a warning (merging them arms the gate against remaining consumers — the one change a human should review); additions are safe and can ride GitHub auto-merge. Protected-branch-safe.
refreshMode: "push" — direct [skip ci] commit to the default branch. Zero ceremony, unprotected trunks only (a protected branch rejects the push — use pr).
Enable via npx vyuh-dxkit init --with-flow-refresh, or set the policy knobs and run npx vyuh-dxkit update. Either way update refreshes the workflow and uninstall removes it. The landing logic lives in the CLI (flow publish --land=policy), never in workflow bash.
Configuring deep-SAST ingestion (.vyuh-dxkit.json:deepSast)
dxkit's bundled SAST is intraprocedural; interprocedural findings (path traversal, info exposure, SSRF, injection) come from an external engine (Snyk Code or CodeQL) ingested via the dxkit-ingest skill. Persist the engine + Snyk project once so ingest --from-snyk needs no flags:
{
"deepSast": {
"engine": "snyk-code",
"snyk": { "orgId": "…", "projectId": "…" }
}
}
This file is committed and safe — the SNYK_TOKEN is never stored here; it lives only in the environment (locally) or as a CI secret. CLI flags (--org/--project) always override config.
How it ties into the rest of the config surface:
- Hooks / CI (see the
dxkit-hooks skill): the pre-push hook + PR gate enforce against the committed .dxkit/external/<engine>.json snapshot — they never run the heavy engine. The engine runs in a separate CI refresh job (or on demand) that re-ingests and commits the snapshot.
- What blocks a PR: ingested findings are code findings, so
.dxkit/policy.json severity rules apply to them exactly as to native findings.
- Excluding noise:
.dxkit-ignore paths apply to ingested findings too (a finding in an ignored path is dropped).
To set this up end to end (token, first ingest, baseline, refresh job), hand off to the dxkit-ingest skill.
Pointing dxkit at a custom tool directory (.dxkit/tools.json)
By default dxkit finds scanner binaries (gitleaks, semgrep, jscpd, osv-scanner, cloc, …) on PATH and in the usual per-ecosystem locations (npm global, pipx ~/.local/bin, cargo, go, brew). When tools live somewhere else — a corp-managed directory, a project-local toolbox, or a locked-down Windows box where you can't write to the default locations — declare it here:
{
"probePaths": ["D:\\devtools\\bin", "/opt/team/bin"],
"installDir": "D:\\devtools\\bin"
}
probePaths — extra directories dxkit searches for each tool (Windows-aware: matches tool.exe / tool.cmd). This is the primary mechanism — if a tool is already installed somewhere, list its directory here and npx vyuh-dxkit tools list will find it.
installDir — where npx vyuh-dxkit tools install drops new binaries. dxkit injects this into each package manager (pipx, npm-g, cargo, go) and automatically probes both installDir and installDir/bin, so a freshly installed tool is discoverable without extra config.
Both fields are optional; an absent or malformed file is ignored (detection just falls back to the defaults — it never errors).
When to use it
A npx vyuh-dxkit doctor or tools list showing tools as missing when they are actually installed is the signal. Confirm where the binary lives (where gitleaks on Windows, which gitleaks on POSIX), then:
- Create / edit
.dxkit/tools.json and add that directory to probePaths.
- Re-run
npx vyuh-dxkit tools list — the tool should now show as available.
- If the user wants dxkit to install tools into a specific dir, set
installDir, then npx vyuh-dxkit tools install.
- Regenerate the baseline so it reflects the now-available scanners — through the
dxkit-baseline-refresh CI workflow, not a local baseline create --force (see "What NOT to do" for why).
Workflow
When the user asks for a config change:
- Identify which file owns the concern (path exclusion →
.dxkit-ignore; severity routing → .dxkit/policy.json; detection override → .npx vyuh-dxkit.json).
- Open the file, propose the edit, confirm.
- If exclusions changed, refresh the baseline so it doesn't carry stale findings from the now-excluded paths — via the
dxkit-baseline-refresh CI workflow, not a local baseline create --force (see "What NOT to do").
- Commit the config file; let CI refresh + commit the baseline.
What NOT to do
- Don't edit
.dxkit/cache/ or .dxkit/reports/ — they're regenerated on every run (gitignored).
- Don't manually mutate
.dxkit/baselines/main.json — regenerate it. And regenerate it in CI (the dxkit-baseline-refresh workflow), NOT with a local baseline create --force: a local refresh bakes your machine's scanner versions into the committed baseline, so the next PR's guardrail emits spurious TOOLING-DRIFT warnings and phantom "resolved" findings when CI's versions differ. A local --force is fine only for the first capture or a throwaway experiment.
- Don't add
.dxkit/ to .dxkit-ignore — dxkit itself doesn't scan its own outputs.