Skip to content

Make SkillOpt the core optimization workflow#38

Merged
JamesMaki merged 1 commit into
masterfrom
agent/skillopt-core-workflow
Jul 22, 2026
Merged

Make SkillOpt the core optimization workflow#38
JamesMaki merged 1 commit into
masterfrom
agent/skillopt-core-workflow

Conversation

@JamesMaki

@JamesMaki JamesMaki commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Makes SkillOpt the core skill optimization workflow for body and routing-description changes.
  • Uses OpenRouter as the only hosted inference configuration, with Qwen3 32B served through Groq by default.
  • Bakes the Qwen3 0.6B Q4 ONNX embedding model into the Docker image and keeps the smaller compatibility fallback offline-capable.
  • Adds approval-panel risk metrics, a collapsible side-by-side diff, numbered before/after task scores, reasoned rejection audit entries, signed-in reviewer identity, and accessible polling announcements.
  • Adds skill search and filters plus a detailed active, pending, and snapshot version explorer.
  • Updates the README, production guide, tutorial, architecture, configuration, security, SSO, and evidence-gate documentation.
  • Removes obsolete design specs and the tracked repository agent-instruction file.

Why

The merged optimization path and its documentation had drifted apart. Hosted provider examples also exposed configurations the project no longer supports, and the approval surface did not make destructive candidate rewrites obvious enough. This change aligns the implementation, defaults, review UX, tests, and operator documentation around the current SkillOpt and OpenRouter architecture.

User and operator impact

Operators get clearer model names, risk signals, version history, audit reasons, reviewer attribution, and remote-agent deployment guidance. Agent setup remains idempotent and repairable. The local router starts without a Hugging Face download because its default embedding artifact is already in the image.

Validation

  • docker compose config --quiet
  • docker compose build mcp ui
  • Focused Docker suite: 167 passed
  • Full Docker suite, split into bounded shards after the single-process run hit the Docker memory limit: 513 passed, 3 skipped, all 516 collected tests executed
  • Final routing regression suite: 9 passed
  • Restarted ui and mcp services, both healthy
  • Authenticated smoke checks for /auth/me, /api/skills, and /api/history, all returned 200
  • Repository scans confirmed no retired optimizer name, removed hosted-provider references, deleted spec references, or em dash characters remain

Summary by CodeRabbit

  • New Features
    • Enhanced evidence-gated change-control UI with change-risk summary, side-by-side comparisons, version browsing (active/pending/snapshots), and searchable skill inventory.
    • Added optional, length-limited rejection reasons that are recorded in the audit trail.
    • Extended SkillOpt to drive description optimization and support direct vs agent rollout modes.
    • Updated OpenRouter setup with ordered provider priority, ZDR-only enforcement, and clearer local endpoint configuration.
    • Added baked embedding-model cache behavior for faster offline startup.
  • Documentation
    • Refreshed setup/security/config/architecture/tutorial/SSO materials to match the new workflows and auth posture.
  • Bug Fixes
    • Improved provider preflight to fail fast when OpenRouter model coverage is unavailable, and aligned routing-budget handling with the SkillOpt description search.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: da033a48-3dad-4820-890b-ad2d538a5386

📥 Commits

Reviewing files that changed from the base of the PR and between 07b2acf and 983a99e.

📒 Files selected for processing (33)
  • .env.example
  • ARCHITECTURE.md
  • CONTRIBUTING.md
  • Dockerfile
  • PRODUCTION_SETUP.md
  • README.md
  • docs/configuration.md
  • docs/evidence-gate.md
  • docs/how-it-works.md
  • docs/security.md
  • docs/sso.md
  • docs/superpowers/plans/2026-07-15-skills-only-scope.md
  • docs/superpowers/specs/2026-07-15-skills-only-scope-design.md
  • docs/tutorial.md
  • mcp_server/embedding.py
  • optimize/__init__.py
  • optimize/ab.py
  • optimize/promote.py
  • optimize/rollout.py
  • optimize/routing.py
  • requirements.txt
  • tests/conftest.py
  • tests/test_embedding.py
  • tests/test_env_check.py
  • tests/test_optimize.py
  • tests/test_routing.py
  • tests/test_ui.py
  • ui/app.py
  • ui/auth.py
  • ui/oidc.py
  • ui/oidc_flow.py
  • ui/rbac.py
  • ui/static/index.html

📝 Walkthrough

Walkthrough

The PR replaces GEPA-based routing with bounded SkillOpt optimization, adds baked embedding-cache detection, expands evidence-gated review and rejection workflows, updates authentication behavior, and revises OpenRouter, deployment, security, and SkillOpt documentation.

Changes

SkillOpt routing and provider configuration

Layer / File(s) Summary
Provider defaults and embedding cache behavior
.env.example, Dockerfile, mcp_server/embedding.py, optimize/__init__.py, tests/test_embedding.py, tests/test_env_check.py
OpenRouter defaults, model resolution, provider preflight failures, baked embedding environment variables, and cache-only loading behavior are updated and tested.
Bounded SkillOpt routing
optimize/routing.py, optimize/rollout.py, optimize/ab.py, requirements.txt, tests/test_routing.py, tests/test_optimize.py
The routing pass uses SkillOpt reflection, edit ranking, re-evaluation, strict-improvement acceptance, and SKILLOPT_ROLLOUTS; the GEPA dependency and legacy rollout references are removed.

Evidence-gated review lifecycle

Layer / File(s) Summary
Review API and audit records
optimize/promote.py, ui/app.py, ui/auth.py
Snapshot components, authenticated actors, review risk/comparisons, and normalized rejection reasons are exposed through the review API and audit trail.
Review interface and validation
ui/static/index.html, tests/test_ui.py
The UI adds risk summaries, side-by-side diffs, version exploration, searchable skills, rejection overlays, improved score tables, and rejection-history rendering with matching tests.

Documentation and repository guidance

Layer / File(s) Summary
Configuration, security, and deployment guidance
.env.example, PRODUCTION_SETUP.md, ARCHITECTURE.md, docs/configuration.md, docs/security.md, docs/sso.md
Documentation describes OpenRouter/ZDR routing, local endpoints, SkillOpt settings, authentication modes, audit attribution, external Langfuse deployment, and updated SSO behavior.
Product flow and contributor documentation
README.md, docs/how-it-works.md, docs/evidence-gate.md, docs/tutorial.md, CONTRIBUTING.md, tests/conftest.py
README, tutorial, evidence-gate, workflow, and contribution guidance now reflect SkillOpt optimization, held-out evaluation, human review, reasoned rejection, and current configuration names.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: making SkillOpt the central optimization workflow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/skillopt-core-workflow

Comment @coderabbitai help to get the list of available commands.

@JamesMaki
JamesMaki marked this pull request as ready for review July 22, 2026 05:27
@JamesMaki
JamesMaki force-pushed the agent/skillopt-core-workflow branch from 07b2acf to 983a99e Compare July 22, 2026 05:31
@JamesMaki
JamesMaki marked this pull request as draft July 22, 2026 05:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
optimize/__init__.py (1)

76-85: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make Groq the actual default provider.

When OPENROUTER_PROVIDERS is unset, this emits no provider.order, so the default Qwen request uses the generic ZDR pool rather than preferring Groq. Set Groq in code as the default while preserving an explicit empty value as an opt-out; update the corresponding default assertion in tests/test_env_check.py.

Proposed fix
-    order = [p.strip() for p in os.environ.get("OPENROUTER_PROVIDERS", "").split(",") if p.strip()]
+    configured = os.environ.get("OPENROUTER_PROVIDERS")
+    order = ([p.strip() for p in configured.split(",") if p.strip()]
+             if configured is not None else ["groq"])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@optimize/__init__.py` around lines 76 - 85, Update openrouter_extra_body to
default provider.order to Groq when OPENROUTER_PROVIDERS is unset, while
treating an explicitly empty environment value as an opt-out that omits the
order. Update the corresponding default assertion in tests/test_env_check.py to
verify Groq is preferred by default.
🧹 Nitpick comments (2)
ui/app.py (1)

202-208: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing exception chaining (ruff B904).

raise HTTPException(404, str(exc)) drops the original traceback context. Minor, but flagged by static analysis on this newly-added code path.

🔧 Proposed fix
     try:
         components = load_snapshot_components(skill, version)
     except ValueError as exc:
-        raise HTTPException(404, str(exc))
+        raise HTTPException(404, str(exc)) from exc

As per static analysis hints, ruff flags "Within an except clause, raise exceptions with raise ... from err or raise ... from None" (B904) at this line.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/app.py` around lines 202 - 208, Update the exception handling around
load_snapshot_components to explicitly chain the HTTPException from the caught
ValueError, preserving the original exception context while retaining the
existing 404 response and message.

Source: Linters/SAST tools

ui/static/index.html (1)

677-680: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Status pill still says "generating"; inconsistent with the new SkillOpt wording elsewhere.

The per-skill chip now reads "SkillOpt running" (line 634) and the optimize button reads "optimizing…" (line 795), but the top-of-board status pill for the same running state still says just "generating" — a leftover from the pre-SkillOpt wording.

✏️ Proposed fix
   const pill = $("`#status-pill`");
   if (pending) { pill.className = "pill act"; pill.textContent = `${pending} to review`; }
-  else if (running) { pill.className = "pill run"; pill.textContent = "generating"; }
+  else if (running) { pill.className = "pill run"; pill.textContent = "optimizing"; }
   else { pill.className = "pill idle"; pill.textContent = "idle"; }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/static/index.html` around lines 677 - 680, Update the running-state branch
of the status-pill logic to display “SkillOpt running” instead of “generating,”
keeping the existing class assignment and pending/idle behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/configuration.md`:
- Line 55: Update the “SkillOpt optimization” heading in the documentation to
use level-two Markdown heading syntax, restoring the hierarchy directly beneath
the document H1.

In `@docs/tutorial.md`:
- Around line 341-345: Declare the fenced output block as text by changing the
fence preceding the loop output in the tutorial to use the text language
identifier, while preserving the block contents unchanged.

---

Outside diff comments:
In `@optimize/__init__.py`:
- Around line 76-85: Update openrouter_extra_body to default provider.order to
Groq when OPENROUTER_PROVIDERS is unset, while treating an explicitly empty
environment value as an opt-out that omits the order. Update the corresponding
default assertion in tests/test_env_check.py to verify Groq is preferred by
default.

---

Nitpick comments:
In `@ui/app.py`:
- Around line 202-208: Update the exception handling around
load_snapshot_components to explicitly chain the HTTPException from the caught
ValueError, preserving the original exception context while retaining the
existing 404 response and message.

In `@ui/static/index.html`:
- Around line 677-680: Update the running-state branch of the status-pill logic
to display “SkillOpt running” instead of “generating,” keeping the existing
class assignment and pending/idle behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4be95044-2f45-43ef-aedb-8ff7c79bf2a4

📥 Commits

Reviewing files that changed from the base of the PR and between 0db9ff1 and 07b2acf.

📒 Files selected for processing (38)
  • .env.example
  • AGENTS.md
  • ARCHITECTURE.md
  • CONTRIBUTING.md
  • Dockerfile
  • PRODUCTION_SETUP.md
  • README.md
  • docs/configuration.md
  • docs/evidence-gate.md
  • docs/how-it-works.md
  • docs/security.md
  • docs/sso.md
  • docs/superpowers/plans/2026-07-15-skills-only-scope.md
  • docs/superpowers/plans/2026-07-17-human-gated-skill-lifecycle.md
  • docs/superpowers/specs/2026-07-15-component-pass-optimization.md
  • docs/superpowers/specs/2026-07-15-skills-only-scope-design.md
  • docs/superpowers/specs/2026-07-17-human-gated-skill-lifecycle-design.md
  • docs/superpowers/specs/2026-07-19-sso-rbac-design.md
  • docs/tutorial.md
  • mcp_server/embedding.py
  • optimize/__init__.py
  • optimize/ab.py
  • optimize/promote.py
  • optimize/rollout.py
  • optimize/routing.py
  • requirements.txt
  • tests/conftest.py
  • tests/test_embedding.py
  • tests/test_env_check.py
  • tests/test_optimize.py
  • tests/test_routing.py
  • tests/test_ui.py
  • ui/app.py
  • ui/auth.py
  • ui/oidc.py
  • ui/oidc_flow.py
  • ui/rbac.py
  • ui/static/index.html
💤 Files with no reviewable changes (8)
  • docs/superpowers/specs/2026-07-19-sso-rbac-design.md
  • docs/superpowers/specs/2026-07-15-component-pass-optimization.md
  • docs/superpowers/plans/2026-07-17-human-gated-skill-lifecycle.md
  • docs/superpowers/specs/2026-07-15-skills-only-scope-design.md
  • AGENTS.md
  • docs/superpowers/plans/2026-07-15-skills-only-scope.md
  • requirements.txt
  • docs/superpowers/specs/2026-07-17-human-gated-skill-lifecycle-design.md

Comment thread docs/configuration.md
`JUDGE_MODELS`) are covered in [The evidence gate](evidence-gate.md).

### Candidate generation
### SkillOpt optimization

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Restore the heading hierarchy.

### SkillOpt optimization skips directly from the document H1. Change it to ## so markdown linting and document navigation remain valid.

Proposed fix
-### SkillOpt optimization
+## SkillOpt optimization
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### SkillOpt optimization
## SkillOpt optimization
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 55-55: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/configuration.md` at line 55, Update the “SkillOpt optimization” heading
in the documentation to use level-two Markdown heading syntax, restoring the
hierarchy directly beneath the document H1.

Source: Linters/SAST tools

Comment thread docs/tutorial.md
Comment on lines 341 to 345
```
[loop] ===== pdf =====
[mine] analyzed 23 real traces · mean judge score 0.52 · 11 bad cases
[loop] pdf: below health bar (mean 0.52), optimizing…
[loop] done. 1 challenger(s) queued for review: ['pdf']
[mine] ... unjudged cluster(s) remain; the next run continues from the cache
[loop] pdf: mining coverage is ...; deferring the health decision until cached representative judging covers every trace cluster.
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Declare the output block language.

Add text to this fence to satisfy markdownlint.

Proposed fix
-```
+```text
 [loop] ===== pdf =====
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
[loop] ===== pdf =====
[mine] analyzed 23 real traces · mean judge score 0.52 · 11 bad cases
[loop] pdf: below health bar (mean 0.52), optimizing…
[loop] done. 1 challenger(s) queued for review: ['pdf']
[mine] ... unjudged cluster(s) remain; the next run continues from the cache
[loop] pdf: mining coverage is ...; deferring the health decision until cached representative judging covers every trace cluster.
```
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 341-341: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/tutorial.md` around lines 341 - 345, Declare the fenced output block as
text by changing the fence preceding the loop output in the tutorial to use the
text language identifier, while preserving the block contents unchanged.

Source: Linters/SAST tools

@JamesMaki
JamesMaki marked this pull request as ready for review July 22, 2026 05:38
@JamesMaki
JamesMaki merged commit 346a43d into master Jul 22, 2026
2 checks passed
@JamesMaki
JamesMaki deleted the agent/skillopt-core-workflow branch July 22, 2026 05:38
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