Appearance
In-Session Security Review
nubos-pilot reviews the code it writes for security vulnerabilities while it works, and fixes what it finds in the same session — before the code ever reaches a pull request or a human reviewer. The feature runs automatically once nubos-pilot is installed into a Claude Code project; there is nothing to invoke and nothing to set up.
It is the in-session companion to the milestone-level np-security-reviewer audit (run by /np:validate-phase) and to later code review. It reduces what reaches them; it does not replace them. Treat it as one layer of defense in depth — see ADR-0020.
What it checks, and when
The review runs at three points, each at a different depth.
| When | Hook | Depth |
|---|---|---|
| On each file edit | PostToolUse on Edit/Write/MultiEdit/NotebookEdit | Fast deterministic pattern scan — no model call, no cost |
| At the end of each turn | Stop | Background semantic review of the whole turn-diff by an independent reviewer |
| On each commit/push the agent makes | PostToolUse on Bash (filtered to git commit/git push) | Deeper background review that reads surrounding code to keep false positives low |
Two infrastructure hooks support these: SessionStart initializes the per-session ledger, and UserPromptSubmit captures the git baseline the turn-diff is measured against.
The same installer (install-hooks --which all, run by npx nubos-pilot) also wires a sibling continuous-learning hook on Stop (and a streak-reset on UserPromptSubmit); it is independent of the security review and governed separately by learnings.* (see Configuration → learnings.*).
On each file edit (Layer 1)
When nubos-pilot writes to a file, the new content is scanned for known risky patterns — dynamic code execution (eval(, new Function, os.system, child_process.exec), unsafe deserialization (pickle), DOM injection (dangerouslySetInnerHTML, .innerHTML =, document.write), edits under .github/workflows/, and hardcoded secrets. This is a pure string match — instant and free. Each finding is reported once per pattern per file per session, so repeats do not flood the conversation.
At the end of each turn (Layer 2)
After the turn, the git diff of everything that changed (capped at 30 files) is sent to a separate Claude review focused only on security. It runs in the background, so the reply is not delayed. It catches what a string match cannot — authorization bypass, insecure direct object references, injection, SSRF, weak crypto. Findings are surfaced on the next turn and addressed as a follow-up, visible in the same conversation. After at most three consecutive rounds it yields back to you.
On each commit/push (Layer 3)
When nubos-pilot runs git commit or git push through its Bash tool, a deeper agentic review reads surrounding code (callers, sanitizers, related files) before deciding a finding is real. Only commits nubos-pilot makes itself are reviewed — not commits you run from your own shell or the ! escape. Capped at 20 reviews per rolling hour, and deduplicated against the end-of-turn findings.
Ground rules
- It never blocks. No layer prevents a write or a commit. Layer 3 runs after the commit; the end-of-turn layer only re-prompts nubos-pilot to fix a finding as a follow-up. Findings arrive as instructions.
- The reviewer is independent. The pattern scan involves no model. The semantic reviews run as a separate Claude call with a fresh context and a security-only prompt — never the instance that wrote the code grading itself.
- Findings are reported once. Duplicate and already-reported findings are suppressed.
Customizing
Two extension points, both additive — they add checks on top of the built-ins and can never disable a built-in check. Configure them in .nubos-pilot/config.json under security.
custom_rules_path— a JSON file of extra per-edit patterns (Layer 1). Each rule has arule_name, areminder, and either aregexor a list ofsubstrings, optionally scoped withpaths/exclude_paths.json{ "patterns": [ { "rule_name": "tenant_unfiltered_query", "regex": "\\.objects\\.all\\(\\)", "paths": ["**/src/tenants/**"], "reminder": "Multi-tenant code must filter by org_id." } ] }guidance_path— a markdown "what to watch for" file injected into the model-backed reviews (Layers 2/3), e.g. "Never logcustomer_idat INFO or above" or "All/adminroutes must callrequire_role('admin')".
The project's existing RULES.md / CONTEXT.md continue to authorize or neutralize findings, exactly as in the milestone audit.
Toggles
Everything is on by default. Built-in checks cannot be disabled individually — only whole layers or the entire feature. Set these in .nubos-pilot/config.json; changes take effect at runtime with no reinstall.
json
{
"security": {
"enabled": true,
"scan_on_write": true,
"review_on_stop": true,
"review_on_commit": true,
"custom_rules_path": null,
"guidance_path": null,
"review_timeout_ms": 180000,
"max_stop_reviews_in_a_row": 3,
"max_commit_reviews_per_hour": 20,
"max_files_per_review": 30
}
}Scope
The layer is Claude-runtime only — the hooks are a Claude Code mechanism. It is modeled on Anthropic's official security-guidance plugin but reimplemented entirely in the nubos-pilot node stack, so it carries no Python, venv, or marketplace dependency and installs with the rest of nubos-pilot.
