Skip to content

feat(vuln-scanner): introduce Riva research kernel - #70

Merged
Svector-anu merged 18 commits into
mainfrom
feat/riva-research-kernel
Sep 16, 2026
Merged

Svector-anu merged 18 commits into
mainfrom
feat/riva-research-kernel

Conversation

@Svector-anu

Copy link
Copy Markdown
Owner

Summary

Introduce Riva as a focused, scan-time vulnerability-research kernel while preserving vuln-scanner's existing mission and operational authority.

Changes

  • add skills/vuln-scanner/riva.md with threat-model, invariant, slice, bounded exploration, and evidence contracts
  • add legacy/shadow/Riva selection with legacy as the safe default
  • add a read-only compact target-dossier builder
  • keep triage, PoC verification, disclosure, tracking, memory, and notifications authoritative outside Riva
  • add a deterministic dossier schema test to CI

Safety

  • Riva shadow output is private and non-authoritative
  • no disclosure actions are invoked by this change
  • existing PoC gate remains unchanged
  • unrelated worktree changes are not included

Verification

  • bash scripts/tests/test_vuln_poc_gate.sh
  • bash scripts/tests/test_riva_context.sh
  • git diff --check

Comment thread scripts/resolve-riva-capabilities.sh Outdated
set -u

SHADOW_MODE=0
if [ "${SKILL_NAME:-}" = "vuln-scanner" ] && [[ "${SKILL_VAR:-}" == shadow:* || "${SKILL_VAR:-}" == compare:* ]]; then

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL] Bare shadow and compare selectors are not matched here; include the no-colon forms in this condition. Why it matters: the skill parser accepts those forms and sets KERNEL=shadow, but this workflow leaves the run in write mode with GitHub and disclosure credentials available, violating the comparison-only isolation boundary.

@Svector-anu Svector-anu left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: blocked: shadow selector bypasses isolation
Bare shadow/compare runs retain write capabilities and credentials.

Findings (mirrored as inline comments):

  • [CRITICAL] scripts/resolve-riva-capabilities.sh:7 — bare shadow selectors miss the isolation branch, so a documented comparison mode retains write tools and credentials.

@Svector-anu
Svector-anu force-pushed the feat/riva-research-kernel branch from 8666d73 to 7e94c62 Compare September 16, 2026 12:18
@Svector-anu

Copy link
Copy Markdown
Owner Author

Refreshed this PR onto current origin/main and left it open for human review.

What I found:

  • The Riva kernel is still relevant. The PoC gate, GLM harness support, trufflehog timeout work, and fix(vuln-scanner): rephrase curl-pipe-to-shell mentions to clear the eyebrow RCE gate #78's eyebrow wording fix operate alongside or downstream of Riva's research phase; none supersedes it.
  • The old branch included three unrelated slop-watch commits that were already merged through feat(slop-watch): daily report on which contribution lane is worth working #66. The refreshed history drops those commits, reducing the current diff from 20 files / +459/-23 to 15 files / +345/-13.
  • The claim that CI had never run was not quite accurate: pull-request checks ran on the initial head d74ad1b6 on 2026-09-04. The current pre-refresh head had no attached checks because later commits were pushed without new pull_request check suites; several were only manually tested through workflow_dispatch. The existing path filters do cover this PR's scripts/**, skills/**, catalog, and lockfile changes, so no CI path-filter fix was needed.
  • The existing blocked review was valid for old head 8666d739: bare shadow and compare selectors bypassed the resolver's shadow:* / compare:* isolation match. Head 7e94c624 now isolates all four documented forms and executes them in the guard test.
  • The dossier builder also rejected valid Git worktrees because it required .git to be a directory. It now asks Git to validate the repository, and its context test passes from the isolated review worktree.

Verification on current head 7e94c624:

  • ci-tests: green
  • ci-shellcheck: green
  • ci-skill-integrity: green
  • catalog/category/README checks: green
  • GitHub merge state: MERGEABLE / CLEAN

Recommendation: keep open for human review and merge if the Riva product direction is still desired. I do not recommend closing it as stale or superseded.

@Svector-anu
Svector-anu merged commit 4324748 into main Sep 16, 2026
7 checks passed
@Svector-anu
Svector-anu deleted the feat/riva-research-kernel branch September 16, 2026 13:34

@Svector-anu Svector-anu left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: blocked — MCP-server entry point bypasses the new shadow-mode isolation this PR adds (already merged; needs an urgent follow-up fix)

Note: this PR merged at 2026-09-16T13:28:43Z, before this review ran. Posting for traceability — the finding below is live on main right now, not a pre-merge blocker.

Good news first: the previously-flagged critical (memory/logs/2026-09-12.md — bare shadow/compare selector bypassing the read-only guard) is fixed here. scripts/resolve-riva-capabilities.sh now matches bare shadow/compare in addition to the shadow:*/compare:* prefix forms, and commit 7e94c624 adds a regression test (test_riva_shadow_guard.sh) asserting all four selector shapes force SHADOW_MODE=1/SKILL_MODE=read-only. Confirmed by reading the script directly, not just the test.

Findings:

  • [CRITICAL] apps/mcp-server/src/skill-executor.ts:111 (resolveMode) and :306 (env: process.env) — the MCP-server dispatch path resolves capability mode via scripts/skill_mode.sh directly and never sources the new scripts/resolve-riva-capabilities.sh. vuln-scanner has no mode: frontmatter, so resolveMode() always returns write, and the spawned harness inherits the full ambient environment (env: process.env) with no secret withholding. Running vuln-scanner with var=shadow or var=compare through the MCP server (not GitHub Actions) gets full write tools and every live credential (GH_TOKEN, RESEND_API_KEY, etc.) — the exact isolation this PR hardens on the aeon.yml path is entirely absent here. The PR's Safety section ("Riva shadow output is private and non-authoritative", "no disclosure actions are invoked by this change") is false on this entry point, and CLAUDE.md's "behaviour is entry-point-agnostic" contract for apps/mcp-server/apps/webhook doesn't hold for this feature. Why it matters: an operator or automation triggering vuln-scanner var=shadow:owner/repo via the MCP server would unknowingly run Riva's "private research" mode with full disclosure authority and secrets, defeating the isolation that is this PR's stated purpose.

Recommend a fast-follow PR that either (a) has apps/mcp-server/src/skill-executor.ts source/call the same resolve-riva-capabilities.sh logic before resolving mode/env, or (b) extracts the shadow-selector check into scripts/skill_mode.sh itself so every dispatch surface (aeon.yml, mcp-server, any future webhook path) shares one enforcement point instead of two independently-maintained copies.

Svector-anu added a commit that referenced this pull request Sep 16, 2026
…atch path (#81)

pr-review's independent verification of #70 caught this after merge: the
shadow/compare selector check that forces read-only + strips disclosure
credentials only lived in scripts/resolve-riva-capabilities.sh, which only
aeon.yml sources. apps/mcp-server/src/skill-executor.ts resolves capability
mode straight from scripts/skill_mode.sh with no knowledge of the selector,
so vuln-scanner var=shadow dispatched through the MCP server got full write
tools and the complete ambient environment, including every live credential,
defeating the isolation that PR's Safety section claimed held everywhere.

Moves the selector check into skill_mode.sh itself (is_shadow_selector, one
new is-shadow subcommand) so it's a single enforcement point instead of two
independently-maintained copies, per the review's own recommendation.
resolve-riva-capabilities.sh now delegates to it instead of duplicating the
pattern. skill-executor.ts threads the runtime var into resolveMode and, when
it resolves as a shadow run, strips the same credential set aeon.yml already
withholds before spawning the harness.

Verified: all 5 existing Riva test files still pass unchanged, the shell
logic produces identical output to the old inline check for every existing
selector shape, and the new is-shadow path is exercised directly for both
positive and negative cases (right skill/wrong skill, right var/wrong var).
No test harness exists yet for apps/mcp-server/src itself; typecheck passes
but the TS-side fix isn't covered by an automated regression test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant