From 33757db14a04ae9c137465b38410de1e18c13da3 Mon Sep 17 00:00:00 2001 From: Marius Ciepluch <11855163+norandom@users.noreply.github.com> Date: Wed, 17 Jun 2026 21:16:20 +0200 Subject: [PATCH] feat(opencode): add OpenUltraSAST steering skills --- .kiro/specs/openrouter-sast-harness/tasks.md | 1 + .../skills/openultrasast-fix-audit/SKILL.md | 26 ++++++++++++++ .../skills/openultrasast-kiro-impl/SKILL.md | 26 ++++++++++++++ .opencode/skills/openultrasast-scan/SKILL.md | 35 +++++++++++++++++++ .../skills/openultrasast-triage/SKILL.md | 34 ++++++++++++++++++ tests/test_opencode_skills.py | 20 +++++++++++ 6 files changed, 142 insertions(+) create mode 100644 .opencode/skills/openultrasast-fix-audit/SKILL.md create mode 100644 .opencode/skills/openultrasast-kiro-impl/SKILL.md create mode 100644 .opencode/skills/openultrasast-scan/SKILL.md create mode 100644 .opencode/skills/openultrasast-triage/SKILL.md create mode 100644 tests/test_opencode_skills.py diff --git a/.kiro/specs/openrouter-sast-harness/tasks.md b/.kiro/specs/openrouter-sast-harness/tasks.md index cf12cf3..4213e93 100644 --- a/.kiro/specs/openrouter-sast-harness/tasks.md +++ b/.kiro/specs/openrouter-sast-harness/tasks.md @@ -149,6 +149,7 @@ ## Phase 12: MCP And OpenCode Commands +- [x] Add project-local opencode skills for scan, triage, fix audit, and implementation steering. - [ ] Implement narrow MCP server. - [ ] Add `openultrasast.scan`, `status`, `findings`, `get_finding`, `evidence`, `artifacts`, `propose_patch`, and `export_report` tools. - [ ] Add opencode command docs for quick, standard, deep, verify, and patch workflows. diff --git a/.opencode/skills/openultrasast-fix-audit/SKILL.md b/.opencode/skills/openultrasast-fix-audit/SKILL.md new file mode 100644 index 0000000..4bd8a28 --- /dev/null +++ b/.opencode/skills/openultrasast-fix-audit/SKILL.md @@ -0,0 +1,26 @@ +--- +name: openultrasast-fix-audit +description: OpenUltraSAST patch, fix audit, differential review, adversarial review, and patch validation workflow. Use when proposing or auditing fixes for OpenUltraSAST findings from opencode. +--- + +# OpenUltraSAST Fix Audit + +Use this skill to steer fixes for OpenUltraSAST findings. + +## Fix Lifecycle + +1. Intake: restate the finding ID, evidence level, affected path, and acceptance criteria. +2. Plan: choose the smallest defensive change that addresses the root cause. +3. Implement: modify only files required by the finding. +4. Adversarial review: look for bypasses, regressions, false assumptions, and unrelated edits. +5. Reconcile: either fix the review finding or document why it is not applicable. +6. Verify: rerun the reproducer or affected checks. +7. Ready: only then consider advancing to `patch_validated`. + +## Guardrails + +- Do not rewrite modules when a local fix is enough. +- Do not change public APIs unless the vulnerability requires it. +- Do not mark a patch validated from model reasoning alone. +- Use differential review for risky changes in auth, crypto, config, parsers, and sandbox behavior. +- Run Semgrep or CodeQL delta checks when those analyzers supplied the original evidence. diff --git a/.opencode/skills/openultrasast-kiro-impl/SKILL.md b/.opencode/skills/openultrasast-kiro-impl/SKILL.md new file mode 100644 index 0000000..b72c9a3 --- /dev/null +++ b/.opencode/skills/openultrasast-kiro-impl/SKILL.md @@ -0,0 +1,26 @@ +--- +name: openultrasast-kiro-impl +description: OpenUltraSAST Kiro implementation steering. Use when continuing `.kiro/specs/openrouter-sast-harness/tasks.md`, choosing the next phase, updating checkboxes, or keeping implementation aligned with the spec. +--- + +# OpenUltraSAST Kiro Implementation + +Use this skill when implementing the OpenUltraSAST Kiro spec from opencode. + +## Rules + +1. Read `.kiro/specs/openrouter-sast-harness/tasks.md` before choosing work. +2. Implement the next unchecked task slice unless the user names a different phase. +3. Keep each slice independently verifiable with `uv run pytest`. +4. Update task checkboxes only after implementation and tests pass. +5. Prefer minimal harness-compatible primitives over large framework imports. +6. Keep OpenUltraSAST independent of Clearwing; use Clearwing only as an oracle for design patterns. +7. Use project-local opencode skills to steer scan, triage, and fix workflows. + +## Current Phase Order + +- Phase 5: Harness runtime events, processors, contracts, and traces. +- Phase 5A: Static mapping disciplines for SARIF, Semgrep, CodeQL, differential review, and sharp edges. +- Phase 6: Evidence ladder verifier. +- Phase 7 and 7A: Docker sandbox and dynamic evidence. +- Phase 8 and later: Hunter pool, SARIF, deep mode, patch oracle, MCP, fusion, skill index, hardening. diff --git a/.opencode/skills/openultrasast-scan/SKILL.md b/.opencode/skills/openultrasast-scan/SKILL.md new file mode 100644 index 0000000..5694b12 --- /dev/null +++ b/.opencode/skills/openultrasast-scan/SKILL.md @@ -0,0 +1,35 @@ +--- +name: openultrasast-scan +description: OpenUltraSAST scan, index, quick, standard, deep, SARIF, and report workflows. Use when running or planning `ousast scan`, repository indexing, or evidence-gated SAST analysis from opencode. +--- + +# OpenUltraSAST Scan + +Use this skill to steer OpenUltraSAST scan workflows from opencode. + +## Workflow + +1. Confirm the target is a local repository path. +2. Run commands through uv, never by activating a virtualenv manually. +3. Start with quick mode unless the task explicitly requires standard or deep analysis. +4. Treat quick findings as `static_corroboration`, not verified vulnerabilities. +5. Preserve run artifacts under `.openultrasast/runs//`. +6. Report `scan_id`, `run_dir`, finding count, and the strongest available evidence level. + +## Commands + +```bash +uv run ousast scan --mode quick +uv run ousast index +uv run pytest +``` + +## Evidence Rules + +- `suspicion` means a model or weak signal raised a hypothesis. +- `static_corroboration` means deterministic code evidence exists. +- `crash_reproduced` requires an artifact-backed reproducer. +- `root_cause_explained` requires independent verifier reasoning. +- `patch_validated` requires rerunning relevant checks after the patch. + +Do not describe a finding as verified unless its evidence level meets the configured report threshold. diff --git a/.opencode/skills/openultrasast-triage/SKILL.md b/.opencode/skills/openultrasast-triage/SKILL.md new file mode 100644 index 0000000..bbbe0bd --- /dev/null +++ b/.opencode/skills/openultrasast-triage/SKILL.md @@ -0,0 +1,34 @@ +--- +name: openultrasast-triage +description: OpenUltraSAST false-positive elimination, ranking calibration, evidence ladder, verifier triage, and finding adjudication. Use when reviewing findings, reducing false positives, or deciding whether evidence is enough. +--- + +# OpenUltraSAST Triage + +Use this skill when triaging OpenUltraSAST findings from opencode. + +## Triage Loop + +1. Identify the finding, path, rule, severity, confidence, and evidence level. +2. Separate deterministic evidence from model assumptions. +3. Check attacker control, reachability, sanitizer behavior, duplicates, impact, and contradictory evidence. +4. If rejected or unresolved, record the false-positive reason and scope. +5. Prefer scoped demotion over deleting a vulnerability class globally. +6. Feed the outcome into ranking calibration and prompt constraints. + +## False-Positive Reasons + +- `unreachable_path` +- `missing_attacker_control` +- `sanitizer_disproved` +- `static_rule_mismatch` +- `incorrect_model_assumption` +- `duplicate` +- `insufficient_impact` +- `unsupported` +- `contradicted` +- `unverified` + +## Decision Standard + +If evidence is uncertain, mark the finding as requiring next evidence instead of escalating severity. Difficult or high-impact disagreements should trigger fusion/deeper reasoning when available. diff --git a/tests/test_opencode_skills.py b/tests/test_opencode_skills.py new file mode 100644 index 0000000..951311e --- /dev/null +++ b/tests/test_opencode_skills.py @@ -0,0 +1,20 @@ +from pathlib import Path + + +def test_project_opencode_skills_have_required_frontmatter() -> None: + skills_root = Path(".opencode/skills") + skill_files = sorted(skills_root.glob("*/SKILL.md")) + + assert {path.parent.name for path in skill_files} == { + "openultrasast-fix-audit", + "openultrasast-kiro-impl", + "openultrasast-scan", + "openultrasast-triage", + } + + for skill_file in skill_files: + text = skill_file.read_text() + header = text.split("---", 2)[1] + assert f"name: {skill_file.parent.name}" in header + assert "description: " in header + assert "Use when" in header