| name | runtime-static-hybrid |
| description | Runtime+static consensus: 15-signal weights, modes, saturation curve. Scalpel's novel moat. Use before changing tracer merge, prune decision, or adding signal sources. |
| allowed-tools | Read, Write, Edit, Grep, Glob, Bash |
Runtime + Static Hybrid — Consensus Rules
Purpose
Scalpel's genuine innovation is combining runtime evidence with static over-approximation. Neither alone achieves security-grade reachability:
- Runtime alone: misses unexercised code (false prunes of error paths)
- Static alone: misses dynamic dispatch (false prunes of framework handlers)
Hybrid = runtime as primary truth, static as safety over-approximation, external signals as coverage fillers.
Unlike JIT compilers (which use runtime speculation with deoptimization safety nets), Scalpel makes one-shot AOT prune decisions. No deopt. Consensus must be conservative.
Evidence Weight Table
Each signal source has a confidence weight. Sum of weights per function = confidence score.
| Signal | Weight | Rationale |
|---|
| Runtime observed in production | 10 | Absolute truth — was called |
| Runtime observed in staging | 8 | Production-adjacent, high trust |
| Runtime observed in CI tests | 7 | Deterministic coverage |
| Runtime observed in dev | 5 | Developer happy path |
| Static reachable from entrypoint | 5 | Sound over-approximation |
| APM/tracing span (Datadog, Sentry) | 8 | Real execution evidence |
| Sentry error stack trace | 8 | Provably runs (even if broken) |
| Bytecode LOAD_NAME reference | 6 | Referenced at compile time |
| Test coverage report (pytest-cov, jacoco) | 7 | Instrumented execution |
| String-name literal in source | 2 | Possible dynamic dispatch |
Public API (__all__, exports) | 4 | External contract |
| Framework decorator match | 6 | Framework-dispatched handler |
| Doc mention / README / examples | 2 | Weak signal, public-facing |
| Entry point in pyproject/package.json | 6 | Declared script/bin |
| CVE dependent (reverse direction) | 4 | External user depends on this |
Threshold: only prune if total weight ≤ 1 AND saturation reached.
Consensus Modes
Configurable via --consensus flag on scalpel prune:
| Mode | Rule | Use case |
|---|
strict | Prune only if weight = 0 AND 30+ days of runtime coverage AND no MustKeep | First production deploy, security-critical code |
standard | Prune if weight ≤ 1 AND any runtime coverage AND no MustKeep | Default — balanced |
aggressive | Prune if no runtime hit in window AND static-unreachable AND no MustKeep | Container shrink, non-critical services |
Never prune in strict without at least 2 environment sources (e.g., CI + staging).
Saturation Curve
"Is coverage complete enough to prune safely?"
Track function-discovery rate over time:
day 1: 4200 fns observed
day 2: 4580 (+9%)
day 7: 5100 (+0.2%)
day 14: 5150 (+0.1%) ← plateau
Safe-to-prune signal: daily delta < 0.1% for 3+ consecutive days.
Implementation: maintain rolling window of unique-functions-per-day. CLI: scalpel coverage --window 30d reports saturation.
Never prune before saturation reached. Rule of thumb: 14 days for test suite + 30 days for production.
Trace Merge Algorithm
When merging N trace files into the genome:
- For each trace event, resolve to genome node (file + function name).
- If node exists → upgrade confidence to
ConfirmedUsed, increment observed_count.
- If node doesn't exist → probe-name-mapping issue (see Increment 1.5).
- Apply name normalization: probe may emit
<module>.fn, module:fn, or interned ID. Static analyzer emits Cls.fn or bare fn. Normalize at merge step.
Current bug (Increment 1.5): probe names don't match static names → runtime evidence not counted. Fix: normalize in scalpel-tracer/src/processor.rs before genome insert.
Sampling Strategy
For high-traffic services:
| Strategy | Rule | Overhead |
|---|
| None | Trace every event | 10-30% |
| 1-in-N | Sample every Nth event | 1-3% |
| Time-windowed | Full trace 60s every hour | <1% |
| Stratified | Always trace error paths + 1% of happy paths | <1% |
| Budget-capped | Stop tracing if CPU > X% | Adaptive |
Recommended default for production: stratified sampling.
Runtime-Overrides-Static Rule
Classification rules in priority order:
ConfirmedUsed (runtime) — never downgraded by BFS
StaticallyReachable (BFS from entrypoints) — kept unless overridden
ConditionallyReachable (behind runtime guards) — conservative keep
MustKeep (error handlers, lifecycle) — never pruned
Unreachable — prune candidate after 10-layer gauntlet
See call-graph-soundness skill for the 10 layers.
Multi-Environment Union
Trace files organized:
.scalpel/traces/
├── ci/2026-04-17/...
├── dev/2026-04-17/...
├── staging/2026-04-17/...
└── prod-canary/2026-04-17/...
Merge with per-env trust weights. CLI: scalpel genome merge --envs ci,staging,prod-canary --window 30d.
Production canary = probe runs against 1-5% of prod traffic for fixed duration. Union with CI baseline = highest confidence.
Integration Checklist (for new signal source)
When adding a new evidence source (e.g., Sentry, bytecode walker, GitHub search):
Performance Budget
- Trace ingest: 1M events/sec sustained
- Multi-trace merge (100 files × 10MB): <10s
- Saturation calc per genome: <1s
- Signal union for prune decision (10k functions): <500ms
What Compilers Can't Do (our moat)
Static compilers over-approximate conservatively because they have no runtime evidence. JITs use runtime but with deoptimization safety nets.
Scalpel is AOT-with-runtime-evidence: we make a one-shot decision with data compilers never have. Audit trail is our "proof".
This is the competitive moat. Protect it:
- Keep the hybrid consensus code tight and testable
- Don't let static-only paths bypass runtime check
- Every prune decision must document: runtime evidence ✓/✗, static evidence ✓/✗, other signals
Anti-Patterns
- Using runtime OR static (not AND with safety) as pruning criterion
- Ignoring saturation curve — pruning before coverage plateau
- Weighting untrusted sources (e.g., GitHub code search) equally with runtime
- Downgrading ConfirmedUsed under any circumstance
- Adding signal sources without updating audit trail