oc-code-auditor — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited oc-code-auditor (Agent Skill) and scored it 78/100 (yellow). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 2 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} is the classic direct prompt-injection phrasing. Placed in a skill body that the agent reads as trusted instructions, it tries to make the agent abandon its prior rules and follow whatever comes next — a full system-prompt override.
ignore/disregard/forget … previous instructions sentence.The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
On first invocation, read `references/orchestrator.md` and follow its welcome protocol.
Tri-agent code quality system: Auditor finds problems → Fixer proposes remediations → Verifier confirms the fixes actually solve the findings (not just cosmetic reshuffles).
The Auditor-only mode (/oc-audit) runs a one-pass sweep and produces a findings report. The full harness (/oc-audit fix-all) chains all three agents for find → fix → verify.
CODE AUDITOR COMMANDS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SWEEP MODES
/oc-audit full Full codebase sweep — all categories
/oc-audit security Security-focused (auth, injection, secrets, CORS)
/oc-audit perf Performance (N+1, bundle, caching, queries)
/oc-audit quality Code quality (dead code, complexity, patterns)
/oc-audit ux UX/accessibility (a11y, states, consistency, responsive)
/oc-audit pre-deploy Pre-deployment gate (security + perf + config)
/oc-audit file [path] Audit specific file(s)
/oc-audit diff Audit git diff or staged changes
/oc-audit diff --read-only <range> Auditor-only review of a range; writes audit/findings-<sha>.json
TRI-AGENT HARNESS
/oc-audit fix-all Run full Auditor → Fixer → Verifier loop
/oc-audit fix <id> Fix a single finding with verification
/oc-audit verify Re-run Verifier on previous fixes
BOOTSTRAP
/oc-audit test-bootstrap Generate test suite for untested codebase
UTILITIES
/oc-audit report Regenerate findings report from last audit
/checkpoint Show checkpoint status
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Type any command to begin. /oc-audit to see this again.CODEBASE
│
▼
┌──────────┐
│ AUDITOR │ Sweeps for problems
│ │ Output: findings report with severity + location
└────┬─────┘
│
▼ (findings)
┌──────────┐
│ FIXER │ Proposes concrete code changes per finding
│ │ Output: diffs/patches per finding
└────┬─────┘
│
▼ (fixes)
┌──────────┐
│ VERIFIER │ Confirms each fix addresses the finding
│ │ Grades from the diff and original finding only, not the Fixer's rationale
│ │ Output: verified/rejected per fix
└──────────┘it can't easily fix, and over-report findings it already knows the fix for. Separating Auditor from Fixer keeps the audit honest.
code cosmetically without actually solving the underlying problem. A separate Verifier that re-reads the original finding and the diff catches this — it asks "does this diff actually prevent the vulnerability / fix the bug / solve the performance issue?" without being influenced by the Fixer's explanation.
introducing unreviewed changes. The Verifier flags scope creep: "This diff changes 40 lines but the finding was about 3 lines. The extra changes need their own review."
The Auditor sweeps the codebase and produces findings. This is a read-only agent — it never modifies code.
Run each applicable category. Skip categories that don't apply (e.g., skip UX for a pure API project).
#### 1a. Security Sweep
Read references/security-checklist.md for the full checklist.
| Check | Severity |
|---|---|
| Hardcoded secrets (API keys, tokens, passwords in source) | CRITICAL |
| SQL injection (string concatenation in queries) | CRITICAL |
| Auth bypass (missing middleware on protected routes) | CRITICAL |
| XSS vectors (unescaped user input in HTML/JSX) | HIGH |
| CORS misconfiguration (wildcard with credentials) | HIGH |
| Missing rate limiting on auth endpoints | HIGH |
| Vulnerable dependencies (known CVEs) | MEDIUM-HIGH |
| Missing input validation | MEDIUM |
#### 1b. Performance Sweep
| Check | Severity |
|---|---|
| N+1 queries (DB call inside loop) | HIGH |
| Missing indexes (frequent WHERE columns, no index) | MEDIUM |
| Bundle bloat (importing entire library for one function) | MEDIUM |
| Synchronous blocking in async context | HIGH |
| Unbounded list queries (no pagination) | MEDIUM |
#### 1c. Code Quality Sweep
| Check | Severity |
|---|---|
| Dead code (unused exports, unreachable branches) | LOW |
| Complexity hotspots (functions > 50 lines, cyclomatic > 10) | MEDIUM |
| Missing error handling (bare catch, swallowed errors) | MEDIUM |
Type safety gaps (any types, missing null checks) | MEDIUM |
| Duplication (copy-pasted logic) | MEDIUM |
| TODO/FIXME/HACK markers | LOW |
#### 1d. Configuration & DevOps Sweep
| Check | Severity |
|---|---|
| Missing .env.example | MEDIUM |
| No .gitignore or missing entries | HIGH |
| No type checking (TS without strict mode) | MEDIUM |
| Missing CI/CD | MEDIUM |
| Stale dependencies | LOW |
#### 1e. UX & Accessibility Sweep
Read references/ux-audit-checklist.md for the full checklist.
| Check | Severity |
|---|---|
| Color contrast below 4.5:1 | HIGH |
| Missing form labels | HIGH |
| Div buttons (non-semantic click handlers) | MEDIUM |
| Missing keyboard navigation | HIGH |
| Missing loading/empty/error states | MEDIUM |
| Hardcoded colors/spacing (not using tokens) | MEDIUM |
| Non-responsive components | MEDIUM |
#### 1f. AI-App Safety Sweep (only when an LLM is in the loop)
Phase: AI app? Run this sweep when the codebase calls an LLM (Anthropic / OpenAI SDK, messages.create, a chat/agent loop) or exposes tools/MCP to a model. Skip it entirely for non-AI apps. Read references/ai-safety-rules.md for the full rule pack; the fast pre-screen tripwires live in references/ai-safety-signatures.json.
Two surfaces, both keyed back to the rule pack:
| Check | Rule | Severity |
|---|---|---|
| Untrusted content (user/RAG/tool output) concatenated into the system prompt | AI-INJ-001/002 | HIGH |
| Indirect injection — tool/retrieval output flows into the next prompt turn unescaped | AI-INJ-005/006 | HIGH |
| Persona/policy override reachable via untrusted text | AI-INJ-003/007 | HIGH |
| System prompt / secrets exfiltratable through the model | AI-INJ-004 | HIGH–CRITICAL |
eval/new Function on model output | AI-TOOL-001 | CRITICAL |
Shell exec (exec/spawn/child_process/subprocess, shell: true) reachable from a tool | AI-TOOL-002/003 | CRITICAL |
| Unbounded tool loop (no call ceiling / max-iterations) | AI-TOOL-004 | HIGH |
Destructive op (DROP/DELETE/rm -rf) built from tool/user input | AI-TOOL-005 | CRITICAL |
| Tool allowlist drift / privilege escalation via chained calls | (LLM-reasoned) | HIGH |
The pre-screen seeds findings; the Auditor then traces data flow the regexes can't see (where untrusted text enters the prompt, which capabilities a tool argument can reach). This sweep is the code-level complement to oc-agent-forge's tool budgets and oc-claude-api's tool-use contract — and to oc-security-auditor's threat model one level up.
After individual sweeps:
### [F-001] [Short title]
**Severity:** CRITICAL | HIGH | MEDIUM | LOW
**Category:** security | performance | quality | config | ux | ai-safety
**Location:** `src/api/auth.ts:42-58`
**Fix effort:** S (< 30 min) | M (30 min - 2 hr) | L (2+ hr)
**Problem:**
[2-3 sentences: what's wrong and why it matters]
**Evidence:**
[Code snippet or command output]# Code Audit Report — [project]
**Scope:** [full (incl. 1f if LLM) | security | perf | quality | ux | pre-deploy]
**Findings:** [count by severity]
**Overall health:** [A-F with justification]
## Findings (ordered by severity, then fix effort)
[findings...]
## Recommended Fix Order
[Numbered list considering dependencies between fixes]/oc-audit fix <id> or /oc-audit fix-all)The Fixer takes audit findings and produces concrete code changes. It reads the finding, reads the relevant source code, and produces a diff.
The Fixer is a senior engineer focused on surgical precision:
For each finding:
## Fix: [F-001] [Short title]
### Diff--- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -42,5 +42,8 @@
SELECT * FROM users WHERE email = '${email}';+ const query = SELECT * FROM users WHERE email = ?; + const result = await db.prepare(query).bind(email).first();
### Rationale
Parameterized query prevents SQL injection. Using D1's `.bind()` ensures
the email is properly escaped.
### Tests affected
- [x] Existing tests still pass
- [x] No new test needed (parameterization is the fix)
### Files changed
- `src/api/auth.ts` (1 file, +2 lines, -1 line)/oc-audit fix-all)Run the full loop on all findings:
The Verifier confirms that fixes actually address findings. All three roles run in the same session, so its separation is a discipline, not a mechanism: grade from the original finding and the diff alone — skip the fix document's ### Rationale block and do not re-read the Fixer's exploration notes.
The Verifier is a skeptical code reviewer who has seen too many "fixes" that don't fix:
Improve the performance? Or did it just move code around?
the extra changes need justification.
91 have the same pattern — those are still vulnerable.
## Verification — Fix [F-001]
### Finding: [original finding title]
### Fix: [brief description of what the diff does]
### Verdict: VERIFIED / REJECTED / PARTIAL
### Analysis
- Does the diff address the finding? [Yes/No/Partially]
- Scope: [Surgical / Acceptable / Scope creep detected]
- Regressions: [None detected / Potential issue at line X]
- Completeness: [Fix covers all instances / N similar patterns still unfixed]
### If REJECTED:
[Specific reason and guidance for the Fixer to try again]| Verdict | Meaning | Action |
|---|---|---|
| VERIFIED | Fix correctly addresses the finding | Mark finding as resolved |
| PARTIAL | Fix addresses part of the issue | Feed back to Fixer with specifics |
| REJECTED | Fix doesn't solve the problem or introduces new issues | Feed back to Fixer, try again |
If a fix is REJECTED or PARTIAL:
| Mode | Sweeps | Tri-Agent | Best for |
|---|---|---|---|
/oc-audit full | All 6 (1f only when an LLM is in the loop) | Auditor only | First audit, periodic health check |
/oc-audit security | 1a + auth cross-cut | Auditor only | Pre-deploy, after auth changes |
/oc-audit perf | 1b | Auditor only | Performance investigation |
/oc-audit quality | 1c | Auditor only | Tech debt assessment |
/oc-audit ux | 1e | Auditor only | Before UAT, UX health check |
/oc-audit pre-deploy | 1a + 1b + 1d | Auditor only | Deploy gate |
/oc-audit diff --read-only <range> | 1a–1e over the range's changed files | Auditor only | Review lanes, evaluator spawns, PR review; emits a findings artifact |
/oc-audit fix <id> | — | Fixer + Verifier | Fix one specific finding |
/oc-audit fix-all | All applicable | All three agents | Full find-fix-verify cycle |
/oc-audit verify | — | Verifier only | Re-verify previous fixes |
/oc-audit diff --read-only <range>)The Auditor alone, over a Git range (main..HEAD, <base>..<head>, or a PR's merge-base range). It never modifies code and never spawns the Fixer, which is what makes it safe to run from a review lane or an evaluator subagent on a branch it does not own. It produces two things, and a run that produces neither is not a review:
<sha> = the range head), an array of{ id, severity, title, file, line, evidence, fix } — id as F-NNN, severity one of CRITICAL/HIGH/MEDIUM/LOW, evidence the quoted lines that prove the finding, fix the minimal remediation in one sentence. An empty array is a valid, PASS-grade result.
Candidate-bound deployment handoff below but with payload.policy: "code-review-diff-v1", payload.range, and payload.findings_ref pointing at the artifact. verdict is FAIL when any CRITICAL or HIGH finding is open, INCOMPLETE when the range could not be fully read, PASS otherwise.
When spawned, the report's first line is skill_invoked: yes|no (<args>) and its second is the artifact path — the caller grades from the artifact, not the prose.
For orchestrators: when a FAIL comes back, ask the same reviewer for /oc-audit fix-all on a writable branch (it already holds the findings) and take the diff plus Verifier verdict, instead of bouncing the FAIL to another lane. The 2026-10-08 audit (I-12) traced ≥11 review rounds on one PR to exactly that bounce.
/oc-audit test-bootstrap)Generate a starter test suite for untested codebases. Not a quality audit — a bootstrapping operation.
Process:
If .opchain/qa.yaml exists (oc-qa-ops), take targets and levels from its pyramid and honor coverage.overrides exemptions instead of inventing priorities (v1.9).
Output: actual test files written to the project, not a report.
The audit's letter grade stays the headline. But v1.6 asks every quality skill to also emit a numeric score against a stable rubric so the pipeline can read trend. On each graded sweep, code-auditor appends to the wire-1.1 eval_scores checkpoint field, mapping the grade to a 0..10 score:
"eval_scores": [
{ "rubric": "oc-code-auditor", "score": 8.0, "max": 10, "at": "2026-06-25T12:00:00Z",
"dimensions": { "security": 9, "performance": 8, "quality": 7, "ux": 8 },
"ref": ".checkpoints/oc-code-auditor.checkpoint.json" }
]Grade → score mapping (fixed, so runs are comparable): A≈9.5, B≈8, C≈6.5, D≈4, F≈2 (nudge ±0.5 for +/−). dimensions carries the per-category sub-scores from the sweep. The score is additive — it does not change the grade, the Auditor/Fixer/Verifier loop, or the CRITICAL/HIGH deploy-block logic. oc-telemetry-ops aggregates these into eval_score_trend; oc-orchestrator reads a downward trend as a "schedule the next audit" signal.
The shared checkpoint schema, write rules and resume protocol live in references/checkpoint-protocol.md, bundled with this skill. This section adds only what is specific to oc-code-auditor.
{project-dir}/.checkpoints/oc-code-auditor.checkpoint.json
| Event | What to Save |
|---|---|
| Audit started | Scope, mode, file count |
| Each category sweep complete | Findings from that category |
| Full report generated | Finding count by severity, grade — grade + counts restated in progress_summary (e.g. "Grade C+; 1 CRITICAL, 4 HIGH open"); trend score in eval_scores. Those are the fields sibling skills read |
| Fix applied | Finding ID, diff summary, files changed |
| Fix verified/rejected | Verification verdict per finding |
| Fix-all complete | Summary: fixed, verified, rejected counts |
Never close over open findings. Do not set status: complete while any CRITICAL or HIGH finding is unresolved: set skill_state.loop_state to open and put the next fix in next_actions[0]. loop_state is open, closed (every CRITICAL/HIGH verified), or abandoned (the user stopped the loop; say so in progress_summary).
{
"mode": "fix-all",
"findings_total": 22,
"findings_by_severity": { "critical": 1, "high": 4, "medium": 11, "low": 6 },
"grade": "C+",
"fixes_applied": 5,
"fixes_verified": 4,
"fixes_rejected": 1,
"current_finding": "F-006",
"loop_state": "open"
}| Reads from | Why |
|---|---|
| oc-reverse-spec | Stack, architecture, file inventory → skip re-scanning |
| oc-app-architect | Sprint scores, known issues → don't re-report |
| oc-stack-forge | Typed pipeline standard → grade against |
| oc-qa-ops | .opchain/qa.yaml pyramid targets (when present) → test-bootstrap levels |
| Read by | Why |
|---|---|
| oc-deploy-ops | Grade + counts in progress_summary (trend score in eval_scores) → deploy gate |
| oc-git-ops | Grade + counts (progress_summary) → include in PR |
| oc-docs-forge | Quality notes / audit findings → PR testing & audit documentation |
| oc-app-architect | Grade + counts (progress_summary); individual findings come from the audit report, which is conversation output with no committed path → pre-seed Phase 6 evaluator |
| oc-ux-engineer | Component health → UX audit context |
| oc-security-hardening | Findings whose fix is a declarative, verifiable control (header, limit, policy) — mark them route: oc-security-hardening in the findings report so /oc-harden fix executes them and records the manifest entry; the Fixer keeps application-logic fixes (v1.9) |
| oc-qa-ops | Findings + test-bootstrap output feed /oc-qa audit's gap analysis (v1.9) |
| oc-security-auditor | Grade + counts → cross-reference, don't duplicate; individual findings from the report or PM sub-tickets |
| oc-bug-check | Grade + counts → context for what an audit already flagged (per-finding detail is not in the checkpoint) |
| oc-scale-ops | Performance findings → pre-identified bottlenecks |
| oc-monitoring-ops | Error-handling gaps → logging instrumentation needs |
| oc-migration-ops | Pre-existing findings → don't introduce new issues during a migration |
| oc-modularize-ops | Coupling hotspots → natural seams |
| oc-cost-ops | Which phase an audit run belongs to, for cost attribution |
Audits run inside a context. The PR was opened from a ticket; the sprint that produced the code is linked to a ticket. v1.2 makes the auditor post its findings back where humans expect to see them: the PM tool. See oc-integrations-engineer for the canonical PM-MCP patterns.
After every /oc-audit pre-deploy or /oc-audit full run, if a linked PM ticket can be resolved (from the PR body, the oc-app-architect.checkpoint.json, or the user prompt), post a structured summary comment:
Auditor: Grade {A-F}.
Counts: {CRITICAL N, HIGH N, MEDIUM N, LOW N, ADVISORY N}
Top three (by severity × exploitability):
1. {file:line} — {one-line title}
2. {file:line} — {one-line title}
3. {file:line} — {one-line title}
Counts + grade: .checkpoints/oc-code-auditor.checkpoint.jsonThe comment is intentionally compact — the checkpoint carries counts and the grade, not individual findings; the full findings are the audit report itself and the HIGH+ sub-tickets below. The summary is what subscribers + reviewers see in their notification stream.
For every CRITICAL or HIGH finding, file a sub-ticket parent-linked to the PR ticket:
issue_type: bug from .opchain/pm.yaml.priority: maps from severity (CRITICAL → highest tier;HIGH → high tier).
labels: auditor, severity:<level>, area:<extracted-from-path>.title: {file}: {one-line finding}.body: file + line + reproduction + suggested fix from thefinding record.
assignee: unassigned, unless remediation_owners is set in.opchain/pm.yaml (an optional owner map by area — see oc-integrations-engineer's pm.yaml example); then use the matching area's owner.
pm_refs(role: child, created_by_skill: oc-code-auditor) in the same write, per the bundled checkpoint protocol's pm_refs section.
MEDIUM and LOW findings stay in the audit report only. We don't spam the tracker for everything; the principle is that the PM tool holds work that someone is going to act on.
If a subsequent /oc-audit round shows that a previously-filed sub-ticket no longer reproduces (the issue is closed in code), append a comment to the sub-ticket: Auditor verified clean in {sha} and transition to done from .opchain/pm.yaml states. If a previously-clean finding regresses, re-open the same sub-ticket if it exists rather than creating a duplicate.
pm_deferred_actions[], per oc-integrations-engineer/references/pm-mcp-protocol.md §4.
per file rather than per-finding when more than 5 findings hit the same file.
code is clean. Missing semicolon is not HIGH.
Verifier assumes it doesn't. This tension produces real quality.
After completing the existing verification criteria, obtain the source identity with node scripts/lib/release-evidence.mjs --print-candidate --json. Publish a versioned verification.verdict entry in this skill's checkpoint handoffs, using that exact candidate_identity object. This identity excludes checkpoint evidence from the source projection; it does not attest built bytes or ignored environment configuration. Do not manufacture PASS from a prior summary. Missing criteria produce FAIL or INCOMPLETE.
Required fields: a unique handoff id, contract_version: "1.0", type: "verification.verdict", ISO created_at and actual verified_at, producer: { "skill": "oc-code-auditor", "run_id": "<actual-run-id>" }, the printed candidate_identity as candidate, and payload: { "verdict": "PASS|FAIL|INCOMPLETE", "policy": "pre-deploy-code-audit-v1" }. Replace the verdict placeholder with the actual result. Preserve prior run history and write through the checkpoint protocol. If source content changes before evidence is committed, recompute the identity and re-run affected verification before producing a new handoff.
The deployment wrapper consumes this required handoff before building or deploying and blocks if it is missing, invalid, stale, or non-PASS. Executable verification is a separate A receipt, produced in the current checkout; this checkpoint is not a substitute.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.