You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
Commands with a dry-run mode in the ai, argo, devcontainer, docker, docs, grafana, k8s, prometheus, release, repos, review, ssh, telemetry, tf, tls and vault groups now declare --dry-run, among them devops tf apply, devops k8s configure-urls, devops release tag and devops vault logout, so devops <command> --dry-run runs that mode where it used to fail with No such option: --dry-run (#412). Most of these commands print their preview and stop; devops ai analyze path, branch and pr still analyse, without the model, and print the metadata they would save, and devops argo rollouts analyze still evaluates its metric gate but does not abort the rollout.
devops release sync-notes --dry-run prints the repository and the releases it would republish, then stops without reading any release from GitHub. With --all it names <all published releases> instead of listing them (#412).
CI's static job uploads the SARIF of devops scan report to code scanning under category /devops-scan on every push and pull request, so each scanner's findings show on pull requests and close once fixed (#419).
devops review path, devops review branch and devops review pr run mypy over the reviewed Python files and report its errors as findings (#873). mypy runs on the main worktree's .venv Python, or on devops-cli's own interpreter when the main worktree has none, with the reviewed tree's pyproject.toml, or else the main worktree's, as its config file. It runs only when the reviewed tree and the main worktree hold the same uv.lock, because a review never runs uv sync on a reviewed tree, so a project without a uv.lock gets no mypy findings. A branch or pull request review lists every mypy error in a reviewed file as introduced, since it does not type-check the base. The reviews also run Ruff under the reviewed tree's Ruff configuration, but no Ruff finding reaches review.md or findings.json yet: Ruff names each file by a file:// URI, which the review does not match to a reviewed file. Both tools, like the complexity check below, run even when a review is given --no-static-scan, and neither is among the report's listed static analyzers, so the report does not say when one was skipped or could not run.
.devops/review.toml takes [advisory] rules, the Ruff rules a review adds to the project's own selection, and defaults to BLE001 (#873). Like Ruff's other findings, theirs do not reach review.md yet.
review.md gains a ## Complexity table of each function in the reviewed Python files whose McCabe complexity differs from the base, with its complexity before and after, — standing for a function that was added or removed (#873). Functions are matched by bare name within a file, so of several sharing a name, such as two classes' __init__, only the last is compared. The session's findings.json records the same rows as complexity_delta. A path review has no base, so it lists every function as added. A changed or added function that ends above [complexity] max_complexity in .devops/review.toml (default 10) is a MEDIUM finding, or HIGH above one and a half times that cap, and [complexity] max_increase, when set, also flags any rise of at least that much.
tests/test_swallowed_failures_ratchet.py fails when a file under src/ holds more swallowed failures than its ceiling in tests/fixtures/swallowed_failures_ceilings.json, where a file not listed has a ceiling of 0 (#1347). It counts Ruff's BLE001, S110 and S112 findings, and each call passing check=False that stands alone as a statement or is assigned to a name never returned, yielded or read for .returncode, .stdout or .stderr. The failure lists every site in each file over its ceiling as file:line: rule and says to handle the failures rather than raise the ceiling.
A file under its ceiling also fails the test, which prints the command that locks the gain in, uv run python tests/test_swallowed_failures_ratchet.py --lower (#1347). That command recounts src/, lowers each such file's ceiling to its count, drops a file whose count reaches 0, and exits 1 without writing when any file is over its ceiling.
devops roadmap return <item> hands a roadmap item back to refinement: with --confirm it posts an evidence comment on the issue and sets the item's Status on the board to New (#1348). The comment comes from --comment (-c), or from --comment-file, which replaces --comment when both are given. The command exits 1 on an empty comment, a missing comment file or an item that is not on the board. Without --confirm it prints the item's number and title, the target status and the comment, and writes nothing. --dry-run makes no request and prints the requests a run would make, and --dry-run with --confirm is refused.
AGENTS.md asks for a feasibility check before any code or tests: the agent confirms the item's premise against the real system (upstream documentation, library source, live cluster state or the CLI at runtime) and records how in the task file's **Feasibility** field (#1348). When an item cannot be built as specified, or needs a refactor beyond its scope, the agent writes no compensating code: it comments on the issue with the evidence and a proposed re-scope, returns the item to New with devops roadmap return, and stops. Four signals call for stopping instead of adding code: a swallowed error, product code that detects tests, a second fix on top of a fix in the same area within one release, and a review loop that keeps finding new defects in the same feature.
.github/roadmap.toml takes release_slots, the items a release holds above release_cap before a start trims it or a joining critical fix descopes one. It defaults to 4, and a negative value fails with an error naming the key (#1514).
Changed
devops --dry-run <command>, like a run with DEVOPS_CLI_DRY_RUN exported, now runs the command with --dry-run when the command it resolves to declares that option, instead of printing the generic Would run delegated command: line (#412). Unless the command line already gives --dry-run, it is added directly after the command path, ahead of the command's options, positional arguments and any --. A command that does not declare --dry-run still prints only the generic line and does not run, -h or --help shows the command's help, and devops --help says that a delegated command previews only if it declares --dry-run.
devops --dry-run <command>, or a run with DEVOPS_CLI_DRY_RUN exported, now fails with a usage error and exit code 2 on an unknown subcommand instead of printing the generic line and exiting 0 (#412). So does a command that declares --dry-run given an option or argument it rejects, or missing a required one, such as devops --dry-run release prepare without a version.
docs/SDLC.md requires state-mutating commands to declare --dry-run instead of using @dry_run_command (#412).
devops review verify records a person's verdict as a label on the session's findings.json and candidates.json and nothing else; it ranks review history. A known false positive is a reviewed [[suppressions]] entry in .devops/review.toml with a reason and an expiry, and the six Semgrep false positives people had judged in the learned catalog are now such entries (#1150).
Branch and pull request reviews and devops pr check-readiness list the unexpired .devops/review.toml suppressions whose path the change touches, in place of the mitigations ledger's perimeter warning (#1150).
A persona's finding is reported unverified until a person judges it; --no-persona-review gives a tools-only review until the persona stage is removed (#1151). devops ai prompt-eval counts the verdicts the feedback dataset records per labeller, since the deterministic layer it replayed is gone (#1150).
When devops ai agents has a model write AGENTS.md, in any repository, its prompt asks for a feasibility check before coding and for stopping with an evidence comment instead of adding compensating code (#1348). Its built-in template, used with --template or when no model answers, adds the feasibility check, the hand-back with devops roadmap return and the four stop signals only to the AGENTS.md it writes for devops-cli itself.
The task-file template in docs/agent/tasks/README.md has a **Feasibility** line, and tests/test_agent_task_files.py fails any task file without one (#1348). Task files that predate the rule are exempt and are listed in tests/fixtures/task_files_baseline.txt.
A release cut with no changelog fragment and no entries under its version's CHANGELOG.md section fails before it pushes, naming the version, its release branch, the missing section and, from devops roadmap close or the roadmap Service, the completed items with no fragment (#1450).
devops pr check-readiness lets a pull request into a cut release branch edit CHANGELOG.md once the branch holds its version's section, which is how a critical fix after the cut adds its entry (#1450). A pull request into a release branch that changes CHANGELOG.md before the cut is still blocked, docs/ROADMAP.md stays the cut's, and a failed read of the branch's CHANGELOG.md is a blocker naming the error.
devops roadmap close --plan lists CHANGELOG.md among the cut's files and the fragments the cut collects (#1450).
devops roadmap reprioritize still fills a starting release to release_cap (12), but trims it only above its limit, release_cap + release_slots (16), so a P0 or P1 item placed in a release of 12 no longer moves another out (#1514). A critical fix that joins a started or cut release descopes its lowest-ranked unstarted item only once the release holds more than 16, and the size check descopes above the larger of 16 and the release's size at start. The cap, over_size and trim reason comments name the limit.
The roadmap Service's refine job runs every hour and on a first run, as well as after a reprioritize run or an intake that placed a critical fix or a P0 item, so the items of upcoming releases are ready before those releases start. devops roadmap refine takes items nearest place first: the current release's New items, each planned release's New items, nearest release first, then the backlog's P0 and P1 items, each place by priority; the backlog's other New items follow while fewer than the configured release_cap items are Ready across the next planned release and the backlog. In a planned release and among the backlog's P0 and P1 items, refine also takes Ready items it has no record of, and sets one back to New, with a comment, when it finds it not ready. An item whose refine section a person edited no longer takes one of a round's places (#1515).
The Service's devops_cli_service_queue_depth, devops_cli_service_jobs_total, devops_cli_service_job_seconds_total and devops_cli_service_job_start_timestamp_seconds series carry a lane label, release or model, beside repo, and so do its round-failure and worker-crash log lines (#1532). Every repository's model lane waits on the one background model, so a model-lane round runs longer the more repositories' model calls are queued; the model lanes are stalled only when none of them finishes a round for longer than every repository's refine rounds take together.
devops ci security scans src/ and tests/, the targets the repository's new .bandit names, at medium severity and above (#1542). devops scan report on a tree whose .bandit names its targets runs Bandit on them, as that file says, and honours the tree's # nosec markers, so the code-scanning upload reports exactly what the gate fails on; before, it scanned tests/ and ignored # nosec while the gate scanned src/ alone. A tree whose .bandit names no targets is still scanned whole, ignoring # nosec, and a review's scan still reads nothing from the reviewed tree and still ignores # nosec. The tests' Medium and High Bandit findings are fixed: temporary paths come from tmp_path, and a # nosec with its reason marks each literal that is itself under test.
Removed
devops_cli.docs.command_resolver; devops_cli.core.command_resolver replaces it (#412).
The model verifier stage of devops review path, branch and pr, with its prompts verify_finding.md and verify_finding_system.md: no model gives a finding a verdict (#1150).
The hallucination catalog, builtin and learned (common_hallucinations.json), the negative exemplars it showed the personas, and devops review hallucinations list|remove (#1150).
The model-claim guards: the deterministic checks that invalidated a persona's claim (syntax, symbols, headers, the mypy --strictNone-dereference probe, placeholder and unbacked advisories, the runtime floor, judged claims) and the adversarial-debate keyword filter (#1150).
The construct validator and the executable-criteria runner; the criteria allowlist validator stays (#1150).
The severity calibration caps and the location anchoring applied to persona findings, with the "Removed-Symbol Findings" report row and the "Executable Criteria" report section (#1150).
--no-verification and --verification-only on devops review path, branch and pr (#1150).
The ai.tasks.verification task and its DEVOPS_CLI_AI_TASK_VERIFICATION_PROVIDER, _MODEL, _REASONING_EFFORT and _OLLAMA_URLS variables (#1150).
--adjudicator, --perimeter and --regression-test on devops review verify, and the MCP verify_finding tool, which recorded an agent's verdict (#1150).
The mitigations ledger (mitigated_findings.json) (#1150).
Fixed
devops ai benchmark --dry-run no longer saves a task benchmark report to the data.benchmarks_dir directory (#412).
The Prometheus server scrapes only itself and the OpenTelemetry Collector. Alloy, run by k8s-monitoring, finds every other target through annotation autodiscovery, clusterMetrics.kubeDNS and the Loki and DCGM integrations, so the unread API-server scrape (about 60% of head series) and four jobs that matched nothing are gone (#1130).
The server's self-scrape carries the cluster label, which both remaining server jobs take from one anchor (#1130).
k8s/README.md records which monitoring components run outside k8s-monitoring, and why (#1130).
[severity_caps] in .devops/review.toml caps a scanner finding's severity by its path class at admission, for the reviewed head and the base revision alike. A secret scanner's finding, Gitleaks' or one of Trivy's secret results, keeps its severity; any other scanner's finding is capped, Bandit's B105 and Semgrep's credential rules among them (#1301).
A [[suppressions]] path glob in .devops/review.toml covers files at any depth under a **: tests/** covered tests/test_app.py but not tests/ai/review/test_runner.py (#1150).
The roadmap Service's cut (devops roadmap close, and devops release prepare --create-pr) collects changelog.d/ into the version's CHANGELOG.md section and deletes the fragments in the cut commit, so devops release check passes on the release pull request's merge (#1450).
Creating the CLI's tracer no longer runs uname -p: the os.description resource attribute is the system and release from os.uname(), where platform.platform() started a process the first time it was read. A dry run that created the tracer therefore started a process, depending on test order (#1450).
devops roadmap refine keeps one ## Proposed design section per item. The section it writes now ends in its end marker instead of [end-marker], as it has since v0.2.26, so refining an item a second time, after a person edits its body, replaces the section instead of appending another; an end marker in the model's text is still neutralised. An item refined before this fix keeps its old section: refine adds one correctly marked section on its next run, then skips the item until a person deletes the old one (#1470).
The roadmap Service runs each repository's close, reprioritize and metrics jobs in a release lane, and intake and refine, which call the model, in a model lane, each lane with its own worker and its own clone, so a slow intake or refine round no longer holds up closing a delivered item, cutting a release or starting the next one (#1532). Both lanes get every poll and webhook, and a GraphQL budget refusal in either holds both.
A reprioritize success in the Service's release lane makes refine due at the model lane's next poll (#1532).
devops serve --service hands its JSON logging to uvicorn as log_config, and uvicorn builds the service app once it has applied it, so the command no longer reconfigures the process's logging before the server starts (#1543).