Contract Reference
Use this as the current contract baseline for new plugins.
This page is now a short summary of the CLI-consumed plugin contract. The implementation-coupled source of truth belongs in the Divekit CLI repository.
Stable Summary
Plugins are organized in plugin suites. A suite owns one build ecosystem and
its build stage (maven, gradle, the generic custom suite); a plugin is one
analysis inside a suite. On GitLab a suite is a group under divekit/plugins/,
its builder repository is the coordinator, and every plugin is one repository
next to it. The CLI currently expects the following:
- a repository is discovered by
manifest.json(format version1.0) on its default branch;kindisplugin-suitefor a builder andpluginfor a plugin. Legacyplugin.jsonof flat pre-suite plugins is still accepted on read - every repository that contributes a pipeline job ships one
job.yaml(image, script, artifact paths, resource hints); the CLI generates the job from it. Legacyci.yamlandci.ymlrun through the pre-suite child-pipeline path during the migration window - the suite manifest pins its plugins (
v1.4.0,~1.2.3,^1.2.3); a course locks the resolved release and the image digest of every plugin, and the suite itself to the builder’s newest release, in.divekit/eval-pipeline/plugins.json(state version2.0).divekit/distributions/<distribution>/eval-pipeline/plugins.json
divekit plugin updateis the only command that moves a lock; nothing is resolved while a pipeline runs- a plugin’s runtime ID is
<suite>/<plugin>; it names the generated job (maven:pmd), the result directory, and the configuration directory - plugin jobs run in the evaluation pipeline itself, after the suite’s build
job, with the materialized submission and the build stage’s artifacts; the
job receives
DIVEKIT_SUITE_ID,DIVEKIT_PLUGIN_ID, andDIVEKIT_PLUGIN_RESULT_DIR(plugin-results/<suite>/<plugin>) - optional
feedback/assets of a plugin are materialized into the evaluation repository; plugin code ships in the plugin image and is never materialized - a plugin that needs configuration declares
configuration.wizardin its manifest; results are written below.divekit/plugins/<suite>/<plugin>/ - normalized reporting uses:
plugin-results/<suite>/<plugin>/report.json
- optional run-specific feedback uses:
plugin-results/<suite>/<plugin>/feedback.mdplugin-results/<suite>/<plugin>/feedback/index.jsonplugin-results/<suite>/<plugin>/feedback/**/*.md
- optional execution issues use:
plugin-results/<suite>/<plugin>/issues/index.jsonplugin-results/<suite>/<plugin>/issues/**/*.mdplugin-results/<suite>/<plugin>/logs/**
- optional plugin pages under
plugin-results/<suite>/<plugin>/html/**are published into the root of the generated GitLab Page by the report stage - the report stage reconciles the composed plugin jobs with the results that arrived: a plugin job that failed or published nothing becomes a failure entry, a plugin the failed build stage kept from running becomes a not-executed warning
- manual report overrides are read from:
.divekit/overrides/*.json.divekit/plugin/overrides/*.json(legacy)
- generated GitLab Pages expose feedback and issues in
index.html,feedback.json, andissues.json - releases are SemVer tags
vX.Y.Z; the release ZIP carriesmanifest.jsonandjob.yamlat the archive root and may includefeedback/** - named discovery sources such as
officialare resolved through~/.divekit/plugin-sources.json, not stored as raw repository URLs
The flat result layout plugin-results/<plugin-id>/ of pre-suite plugins is
accepted on read during the migration window; see
Migrate To Plugin Suites.
Report entries can include optional notices for short, display-only annotations
above that entry’s report body:
[
{
"id": "test-3",
"name": "Test 3",
"category": "Tests",
"status": "success",
"notices": [
{
"tone": "warning",
"title": "Accepted by plugin policy",
"message": "2 of 8 tests passed. This result is accepted by the plugin grading rule."
}
],
"content": "<p>Details for the test.</p>"
}
]
title and message are plain text. They do not support Markdown or HTML.
Supported tones are info, warning, success, and danger.
For feedback items with type: "faq", use title as the question. The
referenced Markdown content should start with the same question as a # heading
and then answer it.
Feedback items can optionally set defaultOpen to control the initial
expanded/collapsed state on the generated Page. If defaultOpen is omitted,
test-specific feedback is expanded by default and global feedback is collapsed by
default.
Use issues for execution problems that are not test results, such as build
failures, plugin failures, or missing tool output. issues/index.json items can
reference Markdown explanations and optional log files. If affectsResult is
true, the generated Page treats the evaluation as incomplete/failed without
creating a fake test.
Manual report overrides can force the status of selected plugin results after
reports are collected. Override files live directly below
.divekit/overrides/ in eval repositories. Older repositories may still use the
legacy .divekit/plugin/overrides/ location; Divekit keeps reading it for
compatibility. Override files have this shape:
{
"version": "1.0",
"id": "jacoco-pit-coverage-threshold-20260529T091500Z",
"reason": "Accepted after manual review",
"createdAt": "2026-05-29T09:15:00Z",
"targets": [
{
"plugin": "maven/jacoco-pit",
"testId": "coverage-threshold",
"status": "success"
}
]
}
Each target names one plugin by its runtime ID and either testId, category,
category plus name, or all: true. Supported statuses are success, warning, failure,
and fatal. If multiple overrides match the same report result, the last
matching override wins after sorting override files by path.
Source of Truth
Use the Divekit CLI repository for the current semantic contract:
That document should remain authoritative for:
- discovery, manifests, pins, and version locking
- the job spec and how jobs are composed into the pipeline
- CLI-managed state files
- normalized report consumption and failure semantics
- hooks and configuration wizards