diff --git a/docs/cli.md b/docs/cli.md index 20177909..00d2583f 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -152,6 +152,28 @@ nyx scan --engine-profile deep --no-smt --explain-engine

nyx scan --engine-profile deep --explain-engine output: resolved config showing every analysis pass, its current state, and the CLI flag/env var that controls it

+### Dynamic verification + +Available with `--features dynamic`. See [dynamic.md](dynamic.md) for the full pipeline and verdict semantics. + +| Flag | Default | Description | +|------|---------|-------------| +| `--verify` | on | Enable dynamic verification (default when built with `dynamic`). Conflicts with `--no-verify` | +| `--no-verify` | off | Skip verification for this run. Useful for fast static-only scans without editing config | +| `--verify-all-confidence` | off | Also verify findings below `Confidence >= Medium`. Slower; intended for payload tuning | +| `--backend ` | `auto` | Sandbox backend: `auto` (docker if available, else process), `docker` (required), `process` (in-process runner) | +| `--unsafe-sandbox` | off | Force the process backend. Equivalent to `--backend process`. Cannot combine with `--backend docker` | +| `--harden ` | `standard` | Process-backend lockdown: `standard` (no-new-privs + rlimit on Linux) or `strict` (namespaces + chroot + seccomp on Linux; `sandbox-exec` on macOS) | +| `--verbose` | off | Flush the per-finding `VerifyTrace` to stderr after each verdict. Same stream that lands in `expected/trace.jsonl` in the repro bundle | + +### Baseline / patch validation + +| Flag | Default | Description | +|------|---------|-------------| +| `--baseline ` | *(none)* | Read a prior scan's JSON (or a stripped `.nyx/baseline.json`) and diff it against this scan on `stable_hash`. Reports `New` / `Resolved` / `FlippedConfirmed` / `FlippedNotConfirmed` transitions | +| `--baseline-write ` | *(none)* | After scanning, write a stripped baseline (only `stable_hash`, `dynamic_verdict`, `severity`, `path`, `rule_id`; no source). Safe to commit | +| `--gate ` | *(none)* | CI gate to enforce when `--baseline` is active. `no-new-confirmed` exits 2 on any new Confirmed finding; `resolve-all-confirmed` exits 2 if any baseline-Confirmed finding is not fully resolved | + ### Examples ```bash @@ -248,6 +270,44 @@ Remove index data. --- +## `nyx surface` + +Print the project's attack-surface map. + +``` +nyx surface [PATH] [--format ] [--build] +``` + +Loads the `SurfaceMap` persisted by the most recent indexed scan when available; otherwise runs the per-language framework probes against the on-disk source to produce an entry-points-only map. Pass `--build` to force a full inline build (pass-1 summary extraction + call-graph construction) on an unscanned project, which adds `DataStore` / `ExternalService` / `DangerousLocal` nodes the entry-points-only fallback omits. + +| Flag | Default | Description | +|------|---------|-------------| +| `--format ` | `text` | Output format: `text` (indented tree), `json` (canonical SurfaceMap), `dot` (Graphviz source), or `svg` (spawns `dot` locally) | +| `--build` | off | Force a full SurfaceMap build inline when no indexed scan exists. Same cost as `nyx index build` | + +Pipe `dot` output through `dot -Tsvg` for a renderable graph, or use `--format svg` for a one-step render when graphviz is installed. + +--- + +## `nyx verify-feedback` + +Record a correction or confirmation against a dynamic-verifier verdict. Requires `--features dynamic`. + +``` +nyx verify-feedback [--wrong | --right] [--upload] +``` + +| Argument/Flag | Description | +|---------------|-------------| +| `FINDING_ID` | Stable 16-char hex id shown in `nyx scan --verify` output | +| `--wrong ` | Mark the verdict wrong and record the reason. Conflicts with `--right` | +| `--right` | Confirm the verdict. Conflicts with `--wrong` | +| `--upload` | Reserved; uploading to Nyx telemetry is not yet implemented | + +Feedback is written to the local telemetry log under the platform cache dir. + +--- + ## `nyx config` Manage configuration. diff --git a/src/callgraph.rs b/src/callgraph.rs index 4393a0e6..884b3ace 100644 --- a/src/callgraph.rs +++ b/src/callgraph.rs @@ -29,7 +29,6 @@ use std::path::{Path, PathBuf}; pub struct CallEdge { /// The raw callee string as it appeared in source (e.g. `"env::var"`). /// Preserved for diagnostics, **not** the normalized form used for resolution. - #[allow(dead_code)] // used for future diagnostics and path display pub call_site: String, } @@ -56,7 +55,6 @@ pub struct AmbiguousCallee { pub struct CallGraph { pub graph: DiGraph, /// `FuncKey → NodeIndex` for quick lookup. - #[allow(dead_code)] // used for future topo-ordered analysis and call-graph queries pub index: HashMap, /// Callee strings that could not be resolved to any [`FuncKey`]. pub unresolved_not_found: Vec, @@ -262,19 +260,6 @@ impl ClassMethodIndex { } } - /// Number of distinct `(lang, container, method)` keys. Exposed - /// for diagnostics / tests; production code uses [`Self::resolve`]. - #[allow(dead_code)] - pub fn container_keys_len(&self) -> usize { - self.by_container.len() - } - - /// Number of distinct `(lang, method)` keys. Exposed for - /// diagnostics / tests. - #[allow(dead_code)] - pub fn name_keys_len(&self) -> usize { - self.by_name.len() - } } // ── Type hierarchy index ──────────────────────────────────────────────── @@ -294,11 +279,6 @@ impl ClassMethodIndex { pub struct TypeHierarchyIndex { /// `(lang, super_type)` → distinct sub-type / impl container names. by_super: HashMap<(Lang, String), SmallVec<[String; 4]>>, - /// `(lang, sub_type)` → super-types this type extends / implements. - /// Future use for `super.method()` resolution; populated for - /// completeness today. - #[allow(dead_code)] - by_sub: HashMap<(Lang, String), SmallVec<[String; 2]>>, } impl TypeHierarchyIndex { @@ -309,7 +289,6 @@ impl TypeHierarchyIndex { /// summary) collapse via the membership check. pub fn build(summaries: &GlobalSummaries) -> Self { let mut by_super: HashMap<(Lang, String), SmallVec<[String; 4]>> = HashMap::new(); - let mut by_sub: HashMap<(Lang, String), SmallVec<[String; 2]>> = HashMap::new(); for (key, summary) in summaries.iter() { let lang = key.lang; @@ -321,14 +300,10 @@ impl TypeHierarchyIndex { if !subs.iter().any(|s| s == sub) { subs.push(sub.clone()); } - let sups = by_sub.entry((lang, sub.clone())).or_default(); - if !sups.iter().any(|s| s == sup) { - sups.push(sup.clone()); - } } } - TypeHierarchyIndex { by_super, by_sub } + TypeHierarchyIndex { by_super } } /// Return the distinct sub-type / impl container names for @@ -342,16 +317,6 @@ impl TypeHierarchyIndex { .unwrap_or_default() } - /// Return the recorded super-types of `sub_type`. Empty when - /// `sub_type` has no recorded super-types in this language. - #[allow(dead_code)] - pub fn supers_of(&self, lang: Lang, sub_type: &str) -> &[String] { - self.by_sub - .get(&(lang, sub_type.to_string())) - .map(|v| v.as_slice()) - .unwrap_or_default() - } - /// Number of distinct `(lang, super_type)` keys. Exposed for /// diagnostics / tests. #[allow(dead_code)] diff --git a/src/cli.rs b/src/cli.rs index 3d28e1ae..c116646a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -359,7 +359,6 @@ pub enum Commands { #[arg(long, help_heading = "Output")] require_converged: bool, - // ── Analysis engine toggles (override [analysis.engine] config) ─── /// Enable path-constraint solving (default: on) #[arg( long, @@ -448,7 +447,6 @@ pub enum Commands { #[arg(long, help_heading = "Limits")] max_pointsto: Option, - // ── Deprecated aliases (hidden) ───────────────────────────────── /// Deprecated: use --index off #[arg(long, hide = true)] no_index: bool, @@ -532,7 +530,6 @@ pub enum Commands { )] harden: Option, - // Baseline / patch-validation /// Read a previous scan's JSON output (or a stripped .nyx/baseline.json) /// and diff it against the current scan on stable_hash. ///