ZeroOne Ops:面向 GitLab 与 GitHub 的 OpenAI 辅助审查与修复智能体
JustinMelger/ZeroOne-ops
ZeroOne Ops 为 GitLab 和 GitHub 提供受策略约束的 OpenAI 辅助审查与修复,将 SonarQube 与 SARIF/Ruff 发现归一化为可治理的修复工作项,并生成 provider 原生的 MR/PR。
The home for software agents that run in your pipeline.
ZeroOne Ops provides governed OpenAI-assisted review and remediation for GitLab and GitHub, with explicit policy, lifecycle state, and provider-native change requests.
What It Does
ZeroOne Ops helps teams:
- review GitLab merge requests and GitHub pull requests with staged, continuity-aware analysis
- normalize SonarQube and SARIF/Ruff findings into governed remediation work; collect all SonarQube pages before promotion, preserve existing work when a source is unavailable, and exclude dismissed identities before capacity ranking
- generate bounded fixes, validate them, and publish provider-native change requests
- control policy, inspect automation state, and reconcile completed or blocked remediation work
The current focus is cross-provider rollout hardening and a simpler control-plane installation experience. See the roadmap.
System Flow
flowchart TD
A[Finding producers\nSonarQube / SARIF] --> B[Normalized finding intake]
B --> C{Platform control plane}
C --> D[GitLab policy and work-item issues]
C --> E[GitHub policy and work-item issues]
D --> F[Shared remediation]
E --> F
F --> G[GitLab MR / GitHub PR]
G <--> H[Staged change-request review]
G --> I[Lifecycle reconciliation]
I --> D
I --> E
D --> J[Derived operational summaries]
E --> J
Loading
Quick Start
Then choose one provider setup:
- GitLab: copy examples/.zeroone-ops.json
to
.zeroone-ops.json, include examples/.gitlab-ci.example.yml, and declare itszeroone-ops-fixandzeroone-ops-reviewstages in the root project pipeline. - GitHub: copy
examples/.zeroone-ops.github.json to
.zeroone-ops.json, then add examples/github-review.yml and examples/github-operations.yml under.github/workflows/.
Both CI examples use the published ZeroOne Ops container, so the target
repository does not need to install the zeroone-ops CLI. The GitHub
operations template uses Ruff as an example SARIF producer and installs uv
for that example's validation setup. Replace the SARIF generation and
toolchain-specific steps with the tools used by your repository.
Configure the matching provider credentials and OPENAI_API_KEY as described
in the runbook, then run the relevant workflow manually for
the first smoke test. From a ZeroOne Ops development checkout, the core
commands are:
uv run zeroone-ops findings sync --dry-run uv run zeroone-ops dashboard policy --dry-run uv run zeroone-ops remediation run --dry-run uv run zeroone-ops work-items sync-status --dry-run uv run zeroone-ops work-items recover --dry-run uv run zeroone-ops review --dry-run
Operating The Control Plane
CI owns the ZeroOne Ops commands. Operators use provider-native records and the installed workflows or pipelines rather than running the CLI directly.
| Operator need | GitLab | GitHub |
|---|---|---|
| Change automation policy | Comment on the policy issue in issue mode; dashboard issue in legacy mode | Comment on the policy issue |
| Inspect a remediation item | Authoritative work-item issue in issue mode; dashboard workflow row in legacy mode | Authoritative work-item issue |
| Recover a blocked item | Comment on the work-item issue in issue mode, then run the control-plane job; dashboard issue in legacy mode | Comment on the work-item issue; the workflow runs on that comment |
| Inspect an active change request | Follow the work-item issue in issue mode; dashboard link in legacy mode | Follow the work-item or operational-summary link |
Each provider installation has the same conceptual jobs: finding sync, remediation, lifecycle reconciliation, policy processing, and recovery processing. Schedules own normal operation; manual runs are for rollout and operator follow-up.
For actionable findings on a remediation PR/MR, the review comment links to
the authoritative work-item issue. Request a same-branch revision there with
/zeroone remediation requeue, not on the PR/MR. See the runbook.
Each accepted command authorizes one attempt; failed revisions require a fresh
operator command rather than automatically retrying on the next scheduled run.
dashboard sonar, dashboard remediate, and dashboard reconcile remain
available as legacy GitLab aliases. Prefer findings sync, remediation run,
and work-items sync-status for new automation. Each legacy alias emits a
non-blocking CI warning with its replacement and no fixed removal version.
Useful quality commands:
uv run ruff check .
uv run mypy src
uv run pytest
just architectureOptional local pre-commit hook setup for Ruff:
uv sync uv run pre-commit install uv run pre-commit run --all-files
Core Workflows
Finding Sync
- normalize SonarQube and configured SARIF findings into the shared finding contract
- project promoted findings into authoritative GitLab or GitHub work-item issues
- keep non-promoted findings visible only as aggregate backlog counts in the derived operational summary, without turning every finding into an issue
Mypy JSON To SARIF
This repository's Finding Dogfood workflow
scans src/ daily with MyPy, repository-configured Ruff, and Semgrep. Empty runs
are expected when CI already prevents those defects. Manual default-branch runs
can additionally publish test-suite MyPy findings using include_test_findings;
these are real work items under a separate source namespace, not a dry run.
See the dogfood operating notes before enabling it.
ZeroOne Ops consumes SARIF rather than requiring a Mypy-specific integration. The Mypy-to-SARIF example converter turns Mypy's JSON output into a configured SARIF artifact:
mkdir -p artifacts set +e uv run mypy --output json src > artifacts/mypy.json mypy_status=$? set -e python examples/mypy_to_sarif.py artifacts/mypy.json artifacts/mypy.sarif test "$mypy_status" -le 1
Configure artifacts/mypy.sarif with a stable source ID such as
mypy-sarif. Mypy commonly reports typing and test-maintenance diagnostics as
SARIF errors, so an artifact-local mapping can give them medium workflow
priority while retaining the raw SARIF level as source evidence:
{
"path": "artifacts/mypy.sarif",
"source_id": "mypy-sarif",
"severity_mapping": {
"error": "medium",
"warning": "medium",
"default": "medium"
}
}source_id is an operator-owned, stable source namespace. It is used for
finding identity and reconciliation even when a scanner reports a different
tool name. For example, a Semgrep report with driver name Semgrep OSS can use
the stable configured ID semgrep-sarif; the reported tool identity remains
available as source metadata. Changing an existing source_id creates a new
source namespace and does not migrate existing work items.
Exit code 1 means Mypy found type errors and still produces an authoritative
artifact; an exit code above 1 means the analysis did not complete and should
fail the pipeline. Artifact mappings support error, warning, note,
none, and default; unmapped levels use the existing SARIF mapping of
error to high, warning or an absent level to medium, and other levels to
low.
Severity control note:
remediation.bootstrap_severitiesseeds a repository's initial policy; it is not the ongoing operator control surface- policy decisions determine which normalized findings are promoted into durable remediation work
- if no policy or bootstrap severity is configured, the initial baseline is
lowandmediumenabled withhighdisabled
Control Plane And Policy
- GitLab issue mode stores policy in a dedicated policy issue and workflow state in authoritative work-item issues; only Maintainers and Owners can issue policy or recovery commands
- GitHub stores policy in a dedicated policy issue; only repository admins can issue policy commands
- GitHub work-item issues remain authoritative, while the operational summary is a read-only derived overview
- use
zeroone-ops dashboard policyto process policy commands
Remediation And Lifecycle
- select one eligible remediation item per run and produce a bounded patch
- run explicitly configured environment setup and validation commands before publication
- create or reuse a GitLab merge request or GitHub pull request in CI mode
- use
zeroone-ops work-items sync-statusto converge merged and closed change-request state - preserve closed-unmerged change requests as blocked records until an authorized operator explicitly dismisses or retries them
Change-Request Review
- review one merge request or pull request per run
- publish one deterministic summary note per reviewed revision
- deduplicate by change-request identity and head SHA
- keep the summary note authoritative even when bounded inline comments are enabled
Dry-Run And Fixtures
Dry-run can use local fixtures before a repository is connected to real services.
For issue control planes, finding-sync dry runs evaluate local findings and policy only. They do not load existing open work items, so active capacity and stale-item reconciliation are not included in the preview.
Included fixtures:
- fixtures/sonar/issues.json
- fixtures/llm/analysis.json
- fixtures/llm/edit.json
- samples/auto_fixable_example.py
The repository's current default config file is .zeroone-ops.json. Copyable operator examples now live in examples/, including:
- examples/.zeroone-ops.json for GitLab
- examples/.zeroone-ops.github.json for GitHub
- examples/.zeroone-ops.minimal.json for a minimal GitLab setup
- examples/.env.example
- examples/.gitlab-ci.example.yml
- examples/github-review.yml
- examples/github-operations.yml for GitHub finding sync, remediation, lifecycle, policy, and recovery processing
Use the root .zeroone-ops.json as the repository's live runtime config, and use the files in examples/ as copyable templates when wiring the bot into another repository.
Config structure direction:
- top-level shared runtime settings stay at the root
- platform selection stays at the root
- review-specific behavior lives under
review - remediation target, promotion seed, and analysis behavior live under
remediation - source-specific ingestion lives under
sonarqubeorsarif - the active provider uses exactly one provider block:
gitlaborgithub
For example:
platformreview.inline_comments_enabledremediation.bootstrap_severitiesremediation.max_active_work_itemsremediation.source_prioritiesremediation.validation_feedback_enabledremediation.target_branchremediation.validation_setup_commandsremediation.validation_commandsremediation.analysis.max_file_bytessonarqube.mock_issues_pathsarif.artifactssarif.artifacts[].severity_mapping
New configuration should use these nested blocks. GitLab examples can combine SonarQube and SARIF intake; GitHub examples use Ruff as one lightweight SARIF producer example.
remediation.max_active_work_items bounds active remediation work across the
repository when using GitHub or GitLab issue control planes. It defaults to
10; only open approved and in-progress remediation work items consume the
limit. Deferred findings remain visible through aggregate backlog counts.
remediation.source_priorities optionally ranks policy-eligible work before
severity when capacity is limited. Lower non-negative values have higher
priority; sources not in the mapping use the neutral tier 100, preserving
severity-first behavior when the mapping is omitted. For example:
{
"remediation": {
"source_priorities": {
"sonarqube": 10,
"semgrep-sarif": 20,
"ruff-sarif": 100,
"mypy-sarif": 100
}
}
}The supported compatibility fields review.platform, gitlab.target_branch,
remediation.supported_severities, validation_setup_commands, and
validation_commands emit non-blocking CI warnings with their replacement
fields. They have no fixed removal version and should not be used in new
configuration.
To test the real OpenAI path instead of local fixtures:
export OPENAI_API_KEY=... export OPENAI_MODEL=gpt-4.1-mini
Optional MLflow tracing is available for OpenAI-backed runs. It is off by default and can be enabled with environment variables such as:
export ZEROONE_MLFLOW_ENABLED=true export MLFLOW_TRACKING_URI=http://localhost:5000 export MLFLOW_EXPERIMENT_NAME=zeroone-ops-review
For CI use, prefer tighter MLflow request settings so an unreachable tracking server does not slow a run down for too long:
export MLFLOW_HTTP_REQUEST_TIMEOUT=5 export MLFLOW_HTTP_REQUEST_MAX_RETRIES=1
For v1 safety, remediation only accepts structured edits that touch exactly one file.
remediation.validation_feedback_enabled is opt-in. It compares configured
validation commands before and after a remediation patch, preserving known
baseline failures and allowing one correction attempt only for a new diagnostic
in the same editable file.
repository_guidance_paths optionally defines the exact repository files used
as bounded guidance for both review and remediation. When omitted, ZeroOne Ops
uses its built-in guidance discovery; when configured, the list replaces those
defaults and does not expand globs. Markdown guidance keeps source order within
selected sections while
skipping navigation-only links; headings, prose, instruction-bearing list items,
and adjacent fenced examples remain bounded prompt evidence. A commands, setup,
verification, or testing section is selected first when present. The remaining
sections prioritize review expectations, working rules, instructions,
verification, testing, and architecture over descriptive sections. The three
selected sections contribute up to 12, 10, and 10 lines respectively, so one
long section cannot consume the full file budget.
Guidance files must be UTF-8 text; unreadable files are skipped with a warning.
Execution Trust Model
Validation and setup commands are executable CI policy, not passive configuration. Treat changes to them like workflow changes, and run privileged remediation only from trusted default-branch configuration and triggers. See the execution trust model for the complete operator guidance.
Credentials And Secrets
For local testing, the most common environment variables are:
OPENAI_API_KEYOPENAI_MODELGITHUB_TOKENGITHUB_REPOSITORYGITLAB_URLGITLAB_TOKENSONARQUBE_URLSONARQUBE_TOKENSONARQUBE_PROJECT_KEY
Store CI secrets as masked and protected variables, and avoid shell tracing
around authenticated git remote rewrites. GitHub remediation jobs need
contents: write, issues: write, and pull-requests: write; review jobs
need issues: write and pull-requests: write. Use the runbook for
workflow-by-workflow token requirements and permission guidance.
The GitHub operations example reads OPENAI_API_KEY from repository secrets
and uses the OPENAI_MODEL repository variable when present; otherwise it
uses its documented default model.
Container And Releases
Build the local image:
docker build -t zeroone-ops:latest .Run it against a checked-out repository:
docker run --rm \
-v "$(pwd):/workspace" \
--env-file .env \
zeroone-ops:latestThe image keeps the installed bot in /opt/zeroone-ops and uses /workspace
as the repository root, so mounting another repository does not hide the bot's
virtual environment. The published runtime image uses a multi-stage build and
runs as a non-root user.
GitHub release automation uses release-please plus the publish workflow.
Stable release tags now follow the zeroone-ops-vX.Y.Z pattern.
Prerelease tags can use zeroone-ops-vX.Y.Z-rc.N; those publish explicit
prerelease image tags without updating latest, while the workflow still
accepts older tag prefixes during transition.
Pull a published image with:
docker pull ghcr.io/<owner>/zeroone-ops:0.2.0
Operational GitHub Actions and GitLab CI templates pin a released image tag. Replace the version deliberately when upgrading. Repositories requiring a stronger supply-chain boundary can pin the same release by immutable image digest instead.
A supported GitLab CI installation template is provided in
examples/.gitlab-ci.example.yml. It uses the
published zeroone-ops image and the canonical neutral commands. Its default
ZERO_ONE_OPS_VERSION is the template compatibility version; upgrade
intentionally by changing that project or group variable to a later released
ZeroOne Ops version. GitHub templates use the matching repository variable for
their default image pin. For GitHub review smoke tests, use
examples/github-review.yml as the starting
workflow file. For the GitHub control plane, copy
examples/github-operations.yml and the
GitHub JSON config template together.
Execution Modes
Local mode:
- creates a branch
- applies the patch
- can request interactive approval before commit
- does not create a merge request unless you switch to CI mode
CI mode:
- creates a branch
- applies the patch
- pushes the branch
- creates or reuses a provider-specific merge request or pull request
- never blocks for terminal approval
Docs
Use these docs for the deeper operational details:
- docs/README.md for the documentation map
- docs/runbook.md for CI setup, credentials, rollout order, and smoke-test recipes
- docs/roadmap.md for what is shipped, current, and parked
- Legacy dashboard retirement audit for support-window evidence and cleanup prerequisites; retirement is not yet approved
- docs/design/functional/functional-design.md and docs/design/technical/technical-design.md for the broader functional and technical design surfaces across review, remediation, dashboard, and operator workflows
来源:GitHub · github.com