# rootcoz > Turn failing Jenkins builds and JUnit XML into actionable root-cause reports your team can review, discuss, and track. --- Source: run-your-first-analysis.md # Run Your First Analysis You want one real Jenkins build analyzed end to end so you can stop reading raw CI output and start from a report. The fastest path is to start the bundled Docker setup, save a username, submit a build, and let RootCoz open the report for you. ## Prerequisites - Docker with Docker Compose - A Jenkins URL, username, password or API token, and one build number you want to inspect - One AI provider credential - A web browser ## Quick Example ```bash cp .env.example .env ``` ```dotenv JENKINS_URL=https://jenkins.example.com JENKINS_USER=your-username JENKINS_PASSWORD=your-api-token AI_PROVIDER=claude AI_MODEL=your-model-name ANTHROPIC_API_KEY=your-anthropic-api-key ``` ```bash docker compose up -d curl http://localhost:8000/health ``` 1. Open `http://localhost:8000`. 2. Enter a username and click `Save`. 3. Click `New Analysis`. 4. Enter `Job Name` and `Build Number`. 5. Click `Submit Analysis`. RootCoz opens a live status page first, then switches to the report when the analysis completes. > **Note:** The Docker image already includes the supported AI CLIs. For a first run, you only need one working provider credential plus `AI_PROVIDER` and `AI_MODEL`. ## Step-by-Step 1. Create your `.env` file. Start with the quick example above, then swap the provider credential if you are not using Claude. | AI provider | Also set in `.env` | | --- | --- | | Claude | `ANTHROPIC_API_KEY=...` | | Gemini | `GEMINI_API_KEY=...` | | Cursor | `CURSOR_API_KEY=...` | > **Warning:** Replace the example Jenkins values before you start the stack. Docker Compose will start even if those values still point at placeholders. 2. Start RootCoz. Run: ```bash docker compose up -d ``` Then confirm the server is responding: ```bash curl http://localhost:8000/health ``` The web app and API are both served from `http://localhost:8000`. 3. Create your profile. On a first visit, RootCoz sends you to a profile screen. A username is enough for regular use. The `API Key`, `GitHub Token`, `Jira Email`, and `Jira Token` fields are optional for this first report. > **Tip:** Leave the token fields blank on day one. Add them later when you are ready to create issues directly from a report. 4. Submit your first Jenkins build. Click `New Analysis`, keep `Jenkins Job` selected, then fill in: - `Job Name` - `Build Number` If you already set `JENKINS_URL`, `JENKINS_USER`, and `JENKINS_PASSWORD` in `.env`, you can leave the matching form fields blank. If you want different values for just this run, enter them on the form to override the server defaults. Review `AI Provider` and `AI Model` before you submit. Leave `Wait for build completion` on unless you do not want RootCoz to wait for an active Jenkins build. 5. Open the report. After you click `Submit Analysis`, RootCoz shows a status page while the job is `waiting`, `pending`, or `running`. When analysis finishes, it redirects to the stored report automatically. If you come back later, the dashboard keeps the run so you can reopen it without submitting again. ## Advanced Usage - You can override the server defaults per run from `New Analysis`, including Jenkins connection fields, `AI Provider`, `AI Model`, `AI CLI Timeout`, Jira search settings, and source repository settings. - `New Analysis` also supports `Paste XML` and `Upload File` when you want to analyze JUnit XML directly instead of pulling from Jenkins. - If Jenkins uses a self-signed certificate, set `JENKINS_SSL_VERIFY=false` before starting RootCoz. - Personal GitHub and Jira tokens in your profile are mainly for actions you take later from the report, such as issue creation. See [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html). - If you want to connect external systems at the server level after your first run, see [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html). - If you prefer to script this flow once the server is running, see [CLI Command Reference](cli-command-reference.html). ## Troubleshooting - If `docker compose up -d` says `AI_PROVIDER is required` or `AI_MODEL is required`, add both values to `.env` and start again. - If `Submit Analysis` fails immediately, re-check your Jenkins URL, username, and token. You can also enter those values directly on `New Analysis` for a one-off override. - If the status page stays in `waiting`, Jenkins is still running and RootCoz is monitoring it. Leave it running, or disable `Wait for build completion` on a later submission if you do not want that behavior. - If the profile page says `The username 'admin' is reserved`, choose a different username unless you were given an admin API key. - If the browser shows connection errors, verify `curl http://localhost:8000/health` works, then inspect the server logs with `docker compose logs rootcoz`. - If you get a `403` allow-list error while submitting, ask an administrator to add your username or grant you admin access. ## Related Pages - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Tracking Analysis Progress](tracking-analysis-progress.html) - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) - [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html) --- Source: finding-runs-on-the-dashboard.md # Finding Runs on the Dashboard Use the dashboard filters to get from a long run list to the exact analysis you need, whether it is still active or already finished. Filtering first helps you avoid opening the wrong run when several jobs have similar names or many runs are happening at once. ## Prerequisites - You can sign in and open `Dashboard`. - At least one analysis run exists. See [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) for details. ## Quick Example 1. Open `Dashboard`. 2. Set `Status` to `running`. 3. Choose a `Team`. 4. If tags are available, click one under `Filter by tag`. 5. Set `From` and `To` to the day range you care about. 6. Click the matching run. > **Tip:** Watch the run count above the table while you filter. Once it drops to a short list, open the run you want. ## Step-by-Step 1. Start with the newest runs. The dashboard shows the most recent runs first and refreshes automatically, so active runs can change status without a manual reload. 2. Narrow the list by status. Use `Status` first to separate active work from finished or failed runs. | If you want to find | Set `Status` to | | --- | --- | | A run still waiting on Jenkins | `waiting` | | A run queued for analysis | `pending` | | A run currently being analyzed | `running` | | A finished report | `completed` | | A run that ended with an analysis error | `failed` | | An AI analysis timeout | `timeout` | > **Note:** Runs labeled `Analysis Timed Out` are found with the `timeout` filter. 3. Add metadata filters. Use `Team`, `Tier`, and `Version` to narrow the list by ownership or release. If your runs use tags, click one or more tags under `Filter by tag` to narrow the list further. The `Clear metadata` button removes only the metadata filters, which makes it easy to try a different combination. 4. Limit the date range. Use `From` and `To` to keep only runs created inside the time window you care about. Use the clear button next to the date fields to remove both dates at once. 5. Refine the short list. Use the search box to narrow by run name. If you still have too many matches, sort by `Created`, `Failures`, `Reviewed`, `Comments`, or `Children`, and raise `Rows per page` to `50`. 6. Open the run you need. Click the row or the run name. Active runs, failed runs, and timed-out runs open the live status view; completed runs open the full report. ## Advanced Usage - Tag filters use AND logic. If you select two tags, the dashboard shows only runs that have both tags. - `From` and `To` are inclusive. A same-day range keeps runs from the start of that UTC day through the end of that UTC day. - Search is case-insensitive, which is useful after you have already narrowed the list with status or metadata. - `Team`, `Tier`, `Version`, tag, and date filters stay in the page URL. Refreshing keeps them, and you can bookmark or share that filtered view. - The search text and `Status` choice do not stay in the URL, so they reset on a full reload. - Sort order is remembered for the current browser tab, which helps if you prefer scanning by `Created` or `Failures`. - The dashboard shows the 500 most recent runs. If an older run is missing, it may have aged out of the dashboard list. > **Warning:** Date filtering uses the run's created date in UTC. A run close to midnight can fall on a different day than the local time shown in your browser. ## Troubleshooting - I do not see `Team`, `Tier`, `Version`, or tag filters: those controls only appear when runs already have metadata values to choose from. - I see `No jobs match your filters`: remove filters one at a time, starting with tags or date, then reset `Status`, then clear the search text. - I cleared metadata, but the list is still empty: `Clear metadata` does not remove the date range, search text, or `Status` filter. - A run looks like it should match the date, but it does not: hover over `Created` to check the exact timestamp, then compare it with the UTC date range. ## Related Pages - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Tracking Analysis Progress](tracking-analysis-progress.html) - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Exploring Failure History and Test Trends](exploring-failure-history-and-test-trends.html) --- Source: submitting-jenkins-builds-and-junit-xml.md # Submitting Jenkins Builds and JUnit XML Submit a Jenkins build or a JUnit XML file when you want rootcoz to analyze failures with the right AI, repository context, peer review, and Jira search for that specific run. Setting those options before you submit gives the first report better evidence and usually saves a re-run. ## Prerequisites - A reachable rootcoz server. - An AI provider and model. If you do not set them per submission, they must already be configured as defaults. - For Jenkins submissions: the job name and build number, plus Jenkins connection details if your server does not already have them. - For repository-aware analysis: the tests repo URL, and access to clone it if it is private. - For Jira matching: a Jira URL, project key, and either Jira Cloud email + API token or a Jira Server/Data Center PAT available for the run. - If you still need the initial setup, see [Run Your First Analysis](run-your-first-analysis.html). ## Quick Example **Jenkins build** ```bash rootcoz --server http://localhost:8000 analyze \ --job-name my-job \ --build-number 42 \ --provider claude \ --model opus-4 ``` **JUnit XML file** 1. Open `New Analysis`. 2. Choose `Paste XML` or `Upload File`. 3. Add the XML, choose the AI settings for this run, and click `Submit Analysis`. > **Tip:** To see model IDs your server currently exposes, run `rootcoz --server http://localhost:8000 ai-models --provider claude`. | If you already have… | Use this path | What happens next | | --- | --- | --- | | A Jenkins build number | `Jenkins Job` in the web app or `rootcoz analyze` | rootcoz can wait for the build, pull Jenkins test data, and optionally fetch artifacts | | A finished `.xml` file | `Paste XML` or `Upload File` in the web app | rootcoz analyzes the XML immediately and opens the result directly | ## Step-by-Step ```bash rootcoz --server http://localhost:8000 analyze \ --job-name my-job \ --build-number 42 \ --provider claude \ --model opus-4 \ --tests-repo-url https://github.com/org/tests:release-4.19 \ --additional-repos "infra:https://github.com/org/infra,product:https://github.com/org/product" \ --peers "cursor:gpt-5.4-xhigh,gemini:gemini-2.5-pro" \ --peer-analysis-max-rounds 5 \ --jira \ --jira-url https://jira.example.com \ --jira-email user@example.com \ --jira-api-token "$JIRA_API_TOKEN" \ --jira-project-key PROJ \ --wait \ --poll-interval 2 \ --max-wait 60 ``` Use that as a Jenkins template. The steps below show how to map the same choices into `New Analysis`, or trim the command down when you only need a few overrides. 1. Choose the submission path that matches what you already have. Use `Jenkins Job` or `rootcoz analyze` when the build is in Jenkins. Use `Paste XML` or `Upload File` when you already have a JUnit XML file and do not need Jenkins polling. > **Note:** In the current codebase, `rootcoz analyze` submits Jenkins jobs. Raw JUnit XML submission is handled in the web app, and the bundled pytest example can send XML automatically after a test run. 2. Identify the Jenkins build or XML file. For Jenkins, enter the job name and build number; folder-style names such as `folder/job-name` are supported. Add `Jenkins URL`, `Jenkins User`, and `Jenkins Password / Token` only when you need to override the server defaults for this run. For a running Jenkins build, leave `Wait for build completion` turned on. In the CLI, use `--wait`, `--poll-interval`, and `--max-wait`; use `--no-wait` if you want to skip Jenkins polling for that submission. For XML, paste the full JUnit XML or upload a `.xml` file. 3. Set the AI provider and model for this job. Rootcoz accepts `claude`, `gemini`, and `cursor`. In the form, pick `AI Provider` and `AI Model`; in the CLI, use `--provider` and `--model`. If you need a quick lookup first, run: ```bash rootcoz --server http://localhost:8000 ai-models --provider claude ``` Use `AI CLI Timeout` or `--ai-cli-timeout` when one provider/model needs more time than your default. Use `Raw Prompt` or `--raw-prompt` only when this run needs extra instructions that do not belong in your normal setup. 4. Add repository context before you submit. `Tests Repo URL` gives rootcoz a repository to clone for code context, and in the web app you can split that into `Tests Repo URL` plus `Ref / Branch`. In the CLI, append the ref to the URL, such as `https://github.com/org/tests:release-4.19`. Use `Additional Repositories` or `--additional-repos` when one repository is not enough. The CLI format is `name:url,name:url`, and each entry can also be pinned to a ref the same way. If the tests repo is private, use `--tests-repo-token` or store that token in your CLI config; the web form assumes the server already has repository access. 5. Turn on peer analysis when you want a second opinion before you review failures. In the web app, toggle `Enable peer review`, add one or more peers, and set `Max Rounds`. In the CLI, use `--peers "provider:model,provider:model"` and optionally `--peer-analysis-max-rounds`. Peer analysis is best when you want the main AI answer challenged by other models. Keep `Max Rounds` small unless the disagreement is genuinely valuable; the allowed range is `1` to `10`. 6. Enable Jira search when you want rootcoz to look for related bugs during analysis. In the web app, turn on `Enable Jira search` and set `Jira URL` plus `Project Key` when you need per-job overrides. In the CLI, `--jira` turns it on and you can also pass auth and SSL options per submission. For Jira Cloud, use `--jira-email` plus `--jira-api-token`. For Jira Server/Data Center, use `--jira-pat`. If you want to skip Jira matching for one run, use `--no-jira` or switch `Enable Jira search` off. > **Warning:** Jira matching only works when rootcoz has a Jira URL, project key, and credentials for the run. That can come from server defaults, CLI config, or the CLI flags you pass on this submission. Searching Jira during analysis is separate from creating a ticket afterward. See [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) when you are ready to file one. 7. Submit the job and open the result. In the web app, click `Submit Analysis`. Jenkins submissions open the status view first; XML submissions open the result directly. From the CLI, rootcoz prints the queued job ID and poll URL. To check the current state, run: ```bash rootcoz --server http://localhost:8000 status ``` When the analysis is complete, review the grouped failures and classifications. See [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) for the report workflow. ## Advanced Usage ### Save your usual defaults in CLI config If you submit similar jobs every day, put the stable settings in `$XDG_CONFIG_HOME/rootcoz/config.toml` or `~/.config/rootcoz/config.toml`. Then your command stays short and you only override what changes for a specific run. ```toml [default] server = "dev" [defaults] jenkins_url = "https://jenkins.example.com" tests_repo_url = "https://github.com/your-org/your-tests" ai_provider = "cursor" ai_model = "gpt-5.4-xhigh" wait_for_completion = true poll_interval_minutes = 2 max_wait_minutes = 0 enable_jira = true peers = "cursor:gpt-5.4-xhigh,gemini:gemini-2.5-pro" peer_analysis_max_rounds = 3 [servers.dev] url = "http://localhost:8000" ``` With that in place, a typical submission becomes: ```bash rootcoz --server dev analyze --job-name my-job --build-number 42 ``` See [CLI Command Reference](cli-command-reference.html) for the full flag list, or [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) for reusable patterns. ### Analyze successful builds or control artifact download Jenkins submissions support two useful per-job overrides. Turn on `Force analysis on successful builds` or use `--force` when you want AI analysis even though Jenkins reported `SUCCESS`. Leave `Fetch build artifacts` on or use `--get-job-artifacts` when logs or screenshots matter, and use `Max Size (MB)` or `--jenkins-artifacts-max-size-mb` to cap how much rootcoz downloads for that run. Artifact download is enabled by default. If you want a lighter analysis, turn it off with `--no-get-job-artifacts`. ### Submit JUnit XML straight from pytest After you add the bundled pytest hook to your project, you can send JUnit XML to rootcoz automatically and write the enriched XML back to the same file after failures. Set the server and AI environment variables, then run pytest with both `--junitxml` and `--analyze-with-ai`. ```bash export ROOTCOZ_SERVER=http://localhost:8000 export ROOTCOZ_AI_PROVIDER=claude export ROOTCOZ_AI_MODEL=opus-4 pytest --junitxml=report.xml --analyze-with-ai ``` > **Note:** This workflow only runs when the test session fails, and it skips enrichment if `--junitxml` was not supplied. The returned XML includes rootcoz analysis properties and a `report_url` property that points back to the rootcoz result. ### Override SSL verification only for one run If Jenkins or Jira uses a self-signed certificate, the CLI lets you relax SSL verification per job instead of changing your global setup. Use `--no-jenkins-ssl-verify` and/or `--no-jira-ssl-verify` only for the affected submission. ## Troubleshooting - `No AI provider configured` or `No AI model configured`: set the provider/model in the submission itself or add them to your normal defaults before submitting again. - `Invalid XML`: upload or paste a real JUnit XML document, not a console log or HTML report. - `No test failures found in the provided XML.`: rootcoz still creates a completed result, but it keeps the original XML because there was nothing to analyze. - `Jenkins reachability check failed`: verify the Jenkins URL, credentials, and network path from the rootcoz server. If the build is already complete and you do not want polling, try `--no-wait`. - `Timed out waiting for Jenkins job ...`: increase `Max Wait` / `--max-wait`, or submit later when the build is closer to completion. - Jira search shows no useful matches: confirm the Jira URL, project key, and credentials available for the run, and turn Jira off for jobs where that search is not helpful. ## Related Pages - [Run Your First Analysis](run-your-first-analysis.html) - [Tracking Analysis Progress](tracking-analysis-progress.html) - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) - [CLI Command Reference](cli-command-reference.html) --- Source: tracking-analysis-progress.md # Tracking Analysis Progress Use this page when you want to see whether an analysis is still queued, waiting on Jenkins, actively running, or ready to review. It also shows how to tell normal waiting from a real timeout and how to start a fresh run when the result is outdated. - A RootCoz run has already been submitted. If not, see [Run Your First Analysis](run-your-first-analysis.html). - If you use the CLI, `rootcoz` is pointed at the correct server and username. - You have permission to view the run. ```bash rootcoz analyze --job-name "folder/job-name" --build-number 123 rootcoz results show JOB_ID ``` The first command queues the run and prints a `Job queued` value plus a `Poll:` link. Open that link in a browser, or run `rootcoz results show JOB_ID` again whenever you want to check the latest stored status from the terminal. > **Note:** The `Poll:` value can be a relative path such as `/results/...`. Open it on the same RootCoz server you submitted to. 1. Start from the job ID or the `Poll:` link. - `rootcoz analyze` returns immediately with `Status: queued`. - In the web app, Jenkins submissions go straight to the live status page. - You can reopen the same result URL later. Active and failed runs land on the status view, while completed runs open the final report. 2. Read the run status correctly. | What you see | What it means | What to do | | --- | --- | --- | | `queued` | RootCoz accepted the request and created a job ID. | Save the job ID or open the `Poll:` link. | | `pending` | The run is in RootCoz's own queue. | Wait for it to start. | | `waiting` | RootCoz is polling Jenkins because waiting is enabled. | Keep the status page open, or tune wait settings on the next run. | | `running` | AI analysis is in progress. | Keep watching until the report is ready. | | `completed` | The report is ready. | Open the final report and review the results. | | `failed` | The run stopped before finishing. | Read the error and decide whether to rerun. | | `Analysis Timed Out` | The web UI recognized an AI timeout failure. | Rerun with a longer AI timeout. | > **Note:** A Jenkins wait timeout still ends as `failed`. The special `Analysis Timed Out` label is for AI timeouts, not for Jenkins wait overruns. 3. Watch the live status page. - RootCoz refreshes the page every 10 seconds while the run is active. - The progress list keeps timestamped steps such as waiting for Jenkins, analyzing, optional Jira search, saving, and peer review rounds. - You can refresh the browser without losing the progress history that was already recorded. 4. Know when the run is finished. - A `completed` run moves you to the report automatically. - A `failed` run stays on the status page and shows the error so you can decide what to do next. - Completed reports show when the run was created, when it completed, and how long the analysis step took. 5. Re-run the job when results need refreshing. ```bash rootcoz re-analyze JOB_ID ``` | Re-run method | Best when | What happens | | --- | --- | --- | | `rootcoz re-analyze JOB_ID` | You want the same analysis again quickly. | RootCoz queues a new run with the stored settings. | | `Re-Analyze` in the web app | You want to change the rerun settings. | RootCoz queues a new run and lets you adjust AI provider, model, AI CLI timeout, peer review, Jira search, repositories, artifacts, and force behavior. | Every rerun gets a new job ID. The original run stays available. ## Advanced Usage ```bash rootcoz analyze \ --job-name "folder/job-name" \ --build-number 123 \ --wait \ --poll-interval 5 \ --max-wait 45 \ --ai-cli-timeout 20 ``` Use these flags when the default progress behavior is not enough: - `--wait` and `--no-wait` control whether RootCoz waits for Jenkins before analysis. - `--poll-interval` controls how often RootCoz checks Jenkins. - `--max-wait` caps the Jenkins wait. `0` means no limit. - `--ai-cli-timeout` caps the AI step, not the Jenkins wait. - `--jenkins-timeout` is separate and only affects individual Jenkins API requests. > **Tip:** Waiting is on by default. If RootCoz does not have a Jenkins URL, the run cannot stay in `waiting` and will move straight toward analysis instead. ```toml [defaults] wait_for_completion = true poll_interval_minutes = 2 max_wait_minutes = 0 ai_cli_timeout = 10 ``` Put default wait and timeout values in `~/.config/rootcoz/config.toml` if you do not want to repeat them on every run. ```bash rootcoz results dashboard rootcoz results show JOB_ID --json ``` Use `rootcoz results dashboard` when you want a terminal view of several runs at once. Use `rootcoz results show JOB_ID --json` when you want the full stored response for scripting or automation. > **Tip:** If the server restarts while a run is still in `waiting`, RootCoz resumes it. Runs that were already `pending` or `running` are better treated as interrupted and may need a rerun. For the full CLI flag list, see [CLI Command Reference](cli-command-reference.html). ## Troubleshooting - A run stays in `waiting` longer than expected: the Jenkins build may still be running, or RootCoz may not be able to reach Jenkins. Increase `--max-wait`, shorten `--poll-interval` if you want more frequent checks, or submit with `--no-wait`. - You see `Analysis Timed Out`: use `Re-Analyze` and raise `AI CLI Timeout`, or submit the build again with a larger `--ai-cli-timeout`. `rootcoz re-analyze JOB_ID` reuses the old timeout. - The status page says `Failed to reach the server. Retrying...`: keep it open. RootCoz automatically retries transient connection failures. - You get `Job not found` or `Access denied`: verify the job ID, the selected server, and the user you are signed in as. The run may also have been deleted. - Re-analysis is rejected because the original run has no stored settings: submit a fresh analysis instead of rerunning that older record. ## Related Pages - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html) - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) - [CLI Command Reference](cli-command-reference.html) --- Source: reviewing-and-classifying-failures.md # Reviewing and Classifying Failures Use the report page to decide which failing tests are already understood, which need a different classification, and which still need more work. Doing this consistently keeps the run’s review status trustworthy and prevents the same underlying failure from being triaged more than once. ## Prerequisites - A completed run with failures. See [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html). - If the run is still queued or running, wait for it to finish first. See [Tracking Analysis Progress](tracking-analysis-progress.html). ## Quick Example 1. Open a completed run. 2. Expand the first failure card. 3. If the current bucket is wrong, change `Override classification` to `CODE ISSUE`, `PRODUCT BUG`, or `INFRASTRUCTURE`. 4. Click `Review` for a single failure, or `Review All` for a grouped card. 5. Repeat until the badge at the top changes from `Needs Review` to `Reviewed`. That is the whole review loop: confirm the classification, then mark the failure done. The rest of this page shows how to do that confidently when one card covers several tests, peer analysis is available, or failures are nested under child jobs. ## Step-by-Step 1. Check the run-level review badge first. At the top of the report, rootcoz shows `Needs Review`, `X/Y Reviewed`, or `Reviewed`. That total includes failures in child jobs, so it is the fastest way to tell whether you are actually finished. | If you see | What it means | What to do | | --- | --- | --- | | `Review` | This card represents one failing test. | Review it individually. | | `Review All (2/5)` and `Affected Tests (5)` | Several tests share the same underlying failure. | Decide once, then update the whole group. | | `Peer Analysis` | Additional AI reviewers weighed in. | Open it when the classification is unclear or disputed. | | `Child Jobs (N)` | Downstream jobs have failures of their own. | Review those sections before expecting the run to be fully reviewed. | 2. Treat grouped failures as one problem first. If a card shows `Affected Tests`, those tests failed for the same reason. Use that list to confirm how many tests are affected, then use `Review All` when the whole group is ready to close. > **Tip:** On grouped cards, the classification menu updates the group, not just the one test name shown at the top. 3. Read the card in the order rootcoz presents it. Start with `Error`, then `Analysis`. If present, use `Artifacts Evidence` when you want the supporting logs or evidence, `Suggested Fix` when the failure looks actionable in code, and `Bug Report` when the failure is better treated as a product issue. 4. Use peer-analysis output when you want a second opinion. Open the top `Peer Analysis` section to scan the whole run, or the `Peer Analysis` block inside a single failure card when you are working one issue at a time. The summary shows which models participated, how many debates reached consensus, and how many rounds were used. If an entry says `+N tests with same error`, one peer-analysis result covers more than one affected test. Inside each round, compare the `Main AI` and `Peer` entries, their classifications, and whether a peer `Agrees` or `Disagrees`. 5. Save the right classification. Use `Override classification` only when the current bucket is wrong. The available choices are `CODE ISSUE`, `PRODUCT BUG`, and `INFRASTRUCTURE`. | Action | Use it for | What changes | | --- | --- | --- | | `Review` or `Review All` | You have finished triage for this failure. | Review status only | | `Override classification` | The failure is in the wrong bucket. | Saved classification for the failure group in this run | | `Comments` | You need to leave context or hand off work. | A visible note on the failure, and sometimes a review suggestion | > **Note:** Marking a failure as reviewed does not change its classification, and changing the classification does not mark it reviewed. 6. Mark the failure reviewed. Use `Review` for a single test or `Review All` for a grouped card. After you click it, the button changes to `Reviewed`, and the UI can show who marked it. If you leave a comment that clearly says the failure has been handled, rootcoz may offer `Mark as reviewed?`. Accept it only if the failure truly no longer needs triage. 7. Repeat the same process for child jobs. Open `Child Jobs`, expand each failed job, and review those cards just like the top-level failures. Child jobs can be nested, so keep expanding until you reach the leaves. > **Warning:** A classification change inside a child job applies to the specific child build you are reviewing. If the same job fails again in a different build, review that build separately. 8. Finish the run and update external status if needed. When every failure in the run is reviewed, the top badge changes to `Reviewed`. If Report Portal is available on your server, rootcoz can then prompt you to update it, or you can use the `Push to Report Portal` button where it appears. ## Advanced Usage Use the CLI when you want repeatable review updates or need to fix a specific item without going back through the UI. ```bash rootcoz results review-status job-123 rootcoz results set-reviewed job-123 --test "test_a" --reviewed rootcoz override-classification job-123 --test "test_a" --classification "CODE ISSUE" rootcoz push-reportportal job-123 ``` Use those commands for top-level failures in a run. The first command is useful in scripts because it reports review progress and comment count. ```bash rootcoz results set-reviewed some-job-id --test "test_child_a" --reviewed --child-job "child-job" --child-build 42 rootcoz override-classification some-job-id --test "test_child_a" --classification "INFRASTRUCTURE" --child-job "child-job" --child-build 42 rootcoz push-reportportal some-job-id --child-job-name "child-job" --child-build-number 42 ``` Use the child-job flags when you are updating a pipeline child build instead of the top-level run. For the full syntax and output options, see [CLI Command Reference](cli-command-reference.html). The `All failures reviewed` prompt appears when you finish the last remaining review in the current session. It does not open just because you navigated to a run that was already fully reviewed. ## Troubleshooting - I cannot see review controls yet: the run may still be queued, running, or not fully processed. See [Tracking Analysis Progress](tracking-analysis-progress.html). - The page never reaches `Reviewed`: expand `Child Jobs` and check for nested failures. The run-level counter includes them. - A grouped card shows more than one classification badge: not every affected test currently has the same saved classification. Reapply the desired classification from that card, or update the remaining tests individually. - `Review All` or `Override classification` reports only partial success: retry the listed test names one by one, or use the CLI commands above for the exact failures that did not save. - `Push to Report Portal` is missing or disabled: your server may not have that feature enabled, or the selected scope may have no failures to push. ## Related Pages - [Tracking Analysis Progress](tracking-analysis-progress.html) - [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html) - [Commenting and Mentioning Teammates](commenting-and-mentioning-teammates.html) - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) - [Exploring Failure History and Test Trends](exploring-failure-history-and-test-trends.html) --- Source: commenting-and-mentioning-teammates.md # Commenting and Mentioning Teammates You want to keep failure follow-up attached to the exact report your team is already using, and pull the right person into the conversation without losing context. RootCoz lets you comment directly on a failure, `@mention` teammates, and use `Mentions` plus optional browser notifications to keep the thread moving. ## Prerequisites - You are signed in with a RootCoz username. - You have a report with at least one failure. - Optional: your browser supports push notifications if you want mention alerts. - If you still need to locate the report, see [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html). ## Quick Example ```text Hey @alice check this ``` Post that in a failure's `Comments` box. RootCoz highlights the mention in the thread, adds it to `alice`'s `Mentions` inbox, and keeps the discussion attached to the failure. ## Step-by-Step 1. Open the report and expand the failure you want to discuss. Comments live inside each failure card under `Comments`. If several tests are grouped into one failure card, they share the same comment thread. 2. Write the comment, then add the mention. ```text Opened bug: OCPBUGS-12345 cc @alice @bob ``` Type `@` and the start of a username. RootCoz shows matching usernames so you can pick the right person instead of guessing. > **Tip:** Use the suggestion list instead of typing a username from memory. Mentions are exact, so a typo or shortened name will not notify the right person. 3. Post the comment. Press `Enter` to post, or click `Post`. Use `Shift+Enter` when you want a new line without sending the comment. 4. Follow up from `Mentions`. Open `Mentions` from the top navigation. Unread mentions show a badge, and clicking a mention marks it read and opens the matching report with the relevant failure card expanded. 5. Clear the inbox when you are done. Open mentions one by one as you work through them, or use `Mark all as read` to clear everything at once. If you need to correct something, delete your own comment from the report and post a new one. 6. Enable browser notifications if you want faster follow-up. When push notifications are available, RootCoz can prompt you to enable them. You can also turn them on or off later from your profile, and notifications are only used for `@mentions`. > **Note:** RootCoz refreshes comments in an open report and unread mention counts while you work, so you usually do not need to reload the page to see new discussion. ## Advanced Usage - Keyboard controls make comment entry faster: `Enter` posts the comment, `Shift+Enter` adds a new line, `Arrow Up` and `Arrow Down` move through mention suggestions, `Enter` or `Tab` inserts the highlighted username, and `Esc` closes the suggestion list. - If your comment clearly says the failure is already handled, RootCoz may ask whether you want to mark it reviewed right away. - Add issue or PR links directly in the thread when they help the next person act faster: ```text Fix merged: https://github.com/org/repo/pull/123 ``` Supported GitHub and Jira links become clickable in comments, and RootCoz can show live status such as `open`, `closed`, or `merged` next to them. - Mention matching follows these rules: | Text | Result | | --- | --- | | `@alice` | Mentions `alice` | | `cc @alice @bob` | Mentions both users | | `@alice-bob` | Valid mention | | `@alice_bob` | Valid mention | | `user@domain.com` | Not treated as a mention | | `@alice ping @alice` | One mention entry for `alice` | - Self-mentions still appear in `Mentions`, but they do not trigger a browser notification. - If you prefer the CLI, these commands cover the same workflow: ```bash rootcoz mentionable-users rootcoz comments add job-1 --test "tests.TestFoo.test_bar" --message "Hey @alice check this" rootcoz mentions --unread rootcoz mentions-mark-read --ids 1,2,3 rootcoz mentions-mark-all-read ``` Browser notifications are browser-only, so there is no CLI command for push subscription. See [CLI Command Reference](cli-command-reference.html) for full syntax. - If the same failure keeps returning, review older comments and outcomes in its history. See [Exploring Failure History and Test Trends](exploring-failure-history-and-test-trends.html) for details. ## Troubleshooting - The `@` suggestion list does not appear: Type `@` and keep typing the username prefix. If you are unsure of the exact name, run `rootcoz mentionable-users` and use one of the listed usernames. - You are not getting browser notifications: Your browser must support push notifications, this site's notification permission must be allowed, and the RootCoz server must have push notifications configured. If you previously blocked notifications, re-enable this site's notification permission in your browser settings. - You clicked `Not now` and the prompt did not come back: enable notifications later from your profile instead. - You can open reports but cannot post comments: Your RootCoz server may be using an allow list for write actions. Ask an administrator to add your username. - You need to fix a comment after posting: RootCoz supports delete, not in-place edit. Delete your own comment and repost the corrected version. ## Related Pages - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Updating Your Profile and Notifications](updating-your-profile-and-notifications.html) - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) - [Exploring Failure History and Test Trends](exploring-failure-history-and-test-trends.html) - [CLI Command Reference](cli-command-reference.html) --- Source: creating-github-and-jira-issues.md # Creating GitHub and Jira Issues Use a completed failure report to draft a GitHub issue or Jira ticket, review it, and file it under your own name. This is the fastest way to turn RootCoz analysis into tracked follow-up work without copying logs, AI output, or links by hand. ## Prerequisites - A completed analysis report with the failure you want to file. If you need one first, see [Run Your First Analysis](run-your-first-analysis.html). - Your RootCoz username saved in `Settings`. - For browser-based GitHub creation, a personal access token with `repo` scope saved in `Settings`. - For browser-based Jira creation, a Jira token saved in `Settings`; add your Jira email too when you use Jira Cloud. - The server must have GitHub issue creation and/or Jira issue creation enabled. > **Note:** In the browser, you can preview generated content without personal tokens. Creating the issue directly from the dialog stays disabled until your personal GitHub or Jira details are saved. ## Quick Example ### Browser 1. Open a completed report and expand the failure you want to file. 2. Click `GitHub Issue` or `Jira Ticket`. 3. Keep or edit the prompt, click `Continue`, and review the preview. 4. Click `Create GitHub Issue` or `Create Jira Ticket`. ### CLI ```bash rootcoz preview-issue \ job-1 \ --test tests.TestA.test_one \ --type github \ --github-token "$GITHUB_TOKEN" \ --github-repo-url "https://github.com/org/repo" rootcoz create-issue \ job-1 \ --test tests.TestA.test_one \ --type github \ --title "Bug: login fails" \ --body "Login returns 500" \ --github-token "$GITHUB_TOKEN" \ --github-repo-url "https://github.com/org/repo" ``` If your CLI server profile already stores the same tracker values, you can omit the matching flags. ## Step-by-Step 1. Open `Settings`, save your username, and add the tracker token you want to use. For Jira Cloud, save your Jira email and token together. 1. Open the completed report and expand the failure card you want to turn into tracked work. 1. If the failure card shows AI selection controls, pick the provider and model you want for issue generation. Turn on `Include links` if you want the issue body to include the Jenkins build and report links when the server can publish them. 1. Click `GitHub Issue` or `Jira Ticket`. RootCoz loads the current issue prompt first; if no default prompt is available, the prompt starts empty. 1. Edit the prompt if needed and click `Continue`. RootCoz generates a preview instead of creating the issue immediately, so you can rewrite it before anything is submitted. | Tracker | Choices you may need to make | What RootCoz generates for you | | --- | --- | --- | | GitHub | `Repository`, when the analysis included more than one repo | Prompt-based title, body, and similar issues | | Jira | `Jira Project`, `Issue Type`, and optional `Security Level` | Prompt-based title, body, and similar issues | When the server already has a Jira project key, RootCoz pre-fills it for you. 1. Review the preview carefully. Similar issues appear at the top when RootCoz can find matches, which makes it easier to reuse existing work instead of filing a duplicate. > **Tip:** Leave Jira `Security Level` empty when the issue should stay public. If you choose `Custom...` for Jira issue type, enter the exact issue type name before creating the ticket. 1. Update the title and body until they read the way you want, then click `Create GitHub Issue` or `Create Jira Ticket`. 1. Open the new issue from the success screen. RootCoz also adds a comment on the failure with the tracker link so the report keeps the issue reference. > **Tip:** After a bug link is added, RootCoz may ask whether the failure should be marked as reviewed. ## Advanced Usage ### Check server support and token health ```bash rootcoz capabilities rootcoz validate-token github --token "$GITHUB_TOKEN" rootcoz validate-token jira --token "$JIRA_TOKEN" --email "user@example.com" ``` Run these first when a button is disabled, a token looks suspicious, or you want to confirm the server supports the tracker you plan to use. ### Inspect or override the issue prompt ```bash rootcoz get-issue-prompt job-1 rootcoz preview-issue \ job-1 \ --test tests.TestA.test_one \ --type github \ --ai-provider claude \ --ai-model opus-4 \ --issue-prompt "Include product version" ``` The browser dialog lets you edit the prompt before previewing. The CLI does the same with `--issue-prompt`, and you can also switch to a different AI provider or model for the preview. ### Look up Jira project and security values ```bash rootcoz jira-projects \ --jira-token "$JIRA_TOKEN" \ --jira-email "user@example.com" rootcoz jira-security-levels PROJ \ --jira-token "$JIRA_TOKEN" \ --jira-email "user@example.com" ``` Use these commands when you need valid Jira project keys or security level names before creating the ticket. ### Create issues for child-job failures or with Jira-specific options ```bash rootcoz create-issue \ job-1 \ --test tests.TestA.test_one \ --type jira \ --title "DNS timeout" \ --body "DNS resolution fails" \ --child-job child-runner \ --child-build 5 \ --jira-project-key PROJ \ --jira-security-level Restricted \ --jira-issue-type Story ``` Use `--child-job` and `--child-build` when the failure belongs to a pipeline child job. For GitHub, `--github-repo-url` lets you override the target repository when needed. For the full CLI flag list, see [CLI Command Reference](cli-command-reference.html). ## Troubleshooting - `GitHub Issue` or `Jira Ticket` is disabled in the report: the server has that tracker flow turned off. Check `rootcoz capabilities` or ask an administrator. - The browser dialog lets you preview but not create: save your personal token first. For Jira Cloud, save the email and token together. - Jira project search or security levels are empty: make sure your Jira token is saved and valid. Without it, RootCoz cannot populate the full Jira lists. - `Include links` still produces plain-text references: the server is missing a public URL for report links, so RootCoz falls back to non-clickable references. - GitHub creation fails because no repository is available: the analysis did not include a usable repo target. Re-run the analysis with repo information, or use `--github-repo-url` from the CLI. - Jira creation fails because no project key is available: choose a project in the dialog or pass `--jira-project-key` in the CLI. - You get `Invalid token` or an `invalid or expired` error: run `rootcoz validate-token` and then save the updated token. - You get `User not allowed`: ask an administrator to add your username to the server allow list. See [Managing Users and API Keys](managing-users-and-api-keys.html). ## Related Pages - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html) - [Updating Your Profile and Notifications](updating-your-profile-and-notifications.html) - [CLI Command Reference](cli-command-reference.html) - [API Endpoint Reference](api-endpoint-reference.html) --- Source: exploring-failure-history-and-test-trends.md # Exploring Failure History and Test Trends When a failure comes back again and again, you want to know whether it is a repeat problem, a flaky test, or just noise in one job. This guide shows how to search stored failures, inspect one test across runs, and compare classifications so you can decide faster and avoid repeating old investigation work. ## Prerequisites - Your RootCoz server already has completed analyses to inspect. - For the web app, you are signed in with a RootCoz username. - For CLI examples, `rootcoz` is configured for your server with `--server` or a saved profile. See [Configuration Reference](configuration-reference.html). ## Quick Example ```bash rootcoz history test tests.TestA.test_one ``` Use this first when you want the recorded failure history for one test, including recent failing runs, related comments, and the classification mix. ```bash rootcoz history test tests.network.TestDNS.test_lookup --job-name ocp-4.16-e2e ``` Use the `--job-name` form when you want RootCoz to estimate pass/fail rate for one specific job instead of showing failure-only history. > **Note:** The web app is the fastest way to browse and open related reports. The CLI is the fastest way to get job-scoped pass/fail math for one test. ## Step-by-Step 1. Open `History` in the web app. Start with a test name in the search box, and add a classification filter when you want to narrow the list to patterns like `FLAKY`, `REGRESSION`, `INFRASTRUCTURE`, or `KNOWN_BUG`. Click a row to open that report, or click the test name to open the per-test history view. 2. Read the test history page from top to bottom. Check the note under the test name before you interpret the summary cards, then use the classification chips and their counts to see how that test has been labeled over time. 3. Compare several entries in `Recent Runs`, not just the newest one. A steady label across many runs usually means a repeat problem, while labels that bounce across nearby runs are a strong signal to investigate flakiness or environment issues. 4. Check the comments before you start a fresh investigation. This is often the quickest place to find earlier bug links, ownership notes, or "already fixed" breadcrumbs that save you from reopening the same work. 5. When you need a cleaner trend view for one job, switch to the CLI. ```bash rootcoz history test tests.network.TestDNS.test_lookup --job-name ocp-4.16-e2e ``` Use this when the web page gives you enough browsing context but you also want a job-scoped failure rate and a tighter comparison set. Add `--limit` if you want more recent failing runs in the output. > **Tip:** If you need to locate the right report before switching to history, see [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html). ## Advanced Usage | When you want to... | Use this command | | --- | --- | | Browse the full stored failure stream | `rootcoz history failures` | | Compare one test against older runs only | `rootcoz history test tests.TestA.test_one --exclude-job-id job-99` | | Check job-wide trend data for automation or scripts | `rootcoz --json history stats ocp-e2e` | | Review saved classification decisions for one report | `rootcoz classifications list --job-id job-123` | | Find every test that shares one known error signature | `rootcoz history search --signature sig-abc` | Use `rootcoz history failures` when you want breadth. It is the best CLI view for scanning many stored failures, and you can narrow it further with `--search`, `--classification`, `--limit`, and `--offset`. Use `rootcoz history test` when you want depth. Add `--job-name` for a meaningful pass/fail rate inside one job, and add `--exclude-job-id` when you are reviewing the current report and want to compare it only against older history. Use `rootcoz --json history stats ocp-e2e` when you want machine-readable trend data. The JSON output includes the overall failure rate, common failures, and the `recent_trend` field. Use `rootcoz classifications list --job-id ...` when you want to compare saved report decisions such as `PRODUCT BUG` or `INFRASTRUCTURE`. For the broader cross-build failure stream, stay with `history failures` or `history test`. Use `rootcoz history search --signature ...` only when you already have the exact signature value from automation or JSON output. Signature matching is exact, so partial values will not help. See [CLI Command Reference](cli-command-reference.html) for the full flag list. ## Troubleshooting - The web test history page shows `Failure Rate` as `N/A`: this is expected when you are browsing failure-only history without a job filter. Run `rootcoz history test tests.network.TestDNS.test_lookup --job-name ocp-4.16-e2e` for job-scoped pass/fail math. - A test history page is empty: RootCoz can only show stored analysis history. If that test has never failed in analyzed runs, there is nothing to compare yet. - A run you just submitted is not showing up in history yet: wait for the analysis to finish, then refresh and try again. See [Tracking Analysis Progress](tracking-analysis-progress.html). - The CLI says no server is configured or cannot connect: pass `--server` explicitly or fix your saved server profile. See [Configuration Reference](configuration-reference.html). ## Related Pages - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Commenting and Mentioning Teammates](commenting-and-mentioning-teammates.html) - [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html) - [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) - [CLI Command Reference](cli-command-reference.html) --- Source: updating-your-profile-and-notifications.md # Updating Your Profile and Notifications Use `Settings` to change the name RootCoz uses for you, refresh saved GitHub and Jira credentials, and turn mention alerts on or off without breaking your access. The same flow also lets you add admin access only when you need it. ## Prerequisites - A saved RootCoz username, or access to the welcome/setup form if this is your first time. - Your GitHub personal access token if you want RootCoz to use your GitHub identity. - Your Jira token, and your Atlassian email if you use Jira Cloud. - An API key for an admin account if you need admin access. See [Managing Users and API Keys](managing-users-and-api-keys.html) for details. - If you still need to generate tracker tokens, see [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html). ## Quick Example 1. Click the `Settings` gear in your user badge. 2. Change `Username`. 3. Paste a new value into `GitHub Token`. 4. Click `Save`. 5. In `Push Notifications`, click `Enable`. This is enough to keep your profile current and start getting browser alerts when someone mentions you in a comment. ## Step-by-Step 1. Open the profile form. If you are already signed in, click the `Settings` gear in the user badge. If you are not signed in yet, use the same form on the welcome screen. 2. Update your username. Enter the name you want RootCoz to use for comments, mentions, and personal settings. > **Warning:** The username `admin` is reserved. Use it only with the API key that belongs to `admin`. 3. Save your GitHub and Jira credentials. Fill in only the fields you use: - `GitHub Token`: GitHub personal access token with `repo` scope. - `Jira Email`: required for Jira Cloud; use the same email as your Atlassian account. - `Jira Token`: Jira Cloud API token or Jira Server/Data Center personal access token. Click `Save`. When RootCoz can validate a non-empty token, it shows an `Authenticated as ...` message under that field. If you update only one token, RootCoz leaves the other saved tracker fields alone. > **Note:** Saved GitHub and Jira credentials stay in this browser and are also synced to the server with encryption at rest, so RootCoz can restore them in another browser after you sign in with the same username. 4. Add or refresh admin access. In `Admin Authentication`, enter the `Username` and `API Key` that belong together, then click `Save`. If the login succeeds, RootCoz saves that username and starts an admin session. The `Settings` page shows your role badge when that session is active. 5. Turn browser notifications on or off. After you have saved a username once, use the `Push Notifications` section: - Click `Enable` to allow mention alerts. - Click `Disable` to stop them. - If notifications are already blocked in your browser, change the site permission first, then return to RootCoz. RootCoz only sends browser notifications when someone mentions you in a comment. See [Commenting and Mentioning Teammates](commenting-and-mentioning-teammates.html) for the mention workflow. 6. Confirm the result. After you save, RootCoz returns you to the dashboard. Reopen `Settings` if you want to verify your username, token status, admin badge, or notification state. ## Advanced Usage > **Tip:** RootCoz may also show an `Enable Notifications?` prompt on the dashboard. If you click `Not now`, the pop-up stops appearing, but you can still enable notifications later from `Settings`. | Change | What RootCoz does | | --- | --- | | Save one tracker token | Keeps the other saved tracker fields unchanged. | | Leave a tracker field blank | Keeps the existing saved server copy instead of deleting it. | | Save your own tracker token on a server that already has shared credentials | Uses your personal token for your tracker actions. | | Log out | Clears the local username and local token copy in that browser. | | Sign in again with the same username | Reloads saved tracker tokens from the server when they are available. | | Keep using an admin session | Renews the admin session automatically while you stay active. | A few extra cases are worth knowing: - On a first-time profile setup, you save the username first and then turn on notifications after RootCoz returns you to the dashboard. - Jira Cloud works best when `Jira Email` and `Jira Token` are saved together. - Email-style usernames work normally. Use the raw value, not a URL-encoded version such as `user%40example.com`. ## Troubleshooting | Problem | What to do | | --- | --- | | `The username 'admin' is reserved` | Use a different username, or enter the API key that belongs to `admin` and save again. | | `Invalid username or API key` | Make sure the `Username` matches the API key you were given. | | GitHub or Jira validation fails | Check that the token is current, that the GitHub token has `repo` scope, and that Jira Cloud includes the correct `Jira Email`. If Jira says it is not configured, ask your administrator to enable Jira on the server. | | `Push notifications are not supported in this browser` | Use a browser that supports browser push notifications. | | `Notifications blocked` | Re-enable notifications for the site in your browser settings, then return to `Settings` and click `Enable` again. | | Notifications fail in Brave | Turn on `Use Google services for push messaging` in Brave, then try `Enable` again. | | You logged out and your tokens seem gone | Sign in again with the same username. RootCoz reloads your saved tracker tokens from the server when it can. | ## Related Pages - [Commenting and Mentioning Teammates](commenting-and-mentioning-teammates.html) - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) - [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html) - [Managing Users and API Keys](managing-users-and-api-keys.html) - [Run Your First Analysis](run-your-first-analysis.html) --- Source: managing-users-and-api-keys.md # Managing Users and API Keys Use this page when you need to give someone admin access, replace an admin key without surprises, or limit write access to a known set of users. The goal is to keep RootCoz usable for your team while making access changes predictable and easy to recover from. This page covers RootCoz admin access keys only. For GitHub, Jira, and Report Portal credentials, see [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html). ## Prerequisites - A RootCoz server URL. - A current admin credential: either the server's `ADMIN_KEY` or an existing delegated admin API key. - The `rootcoz` CLI for command-line examples, or browser access to the RootCoz UI. - Permission to update server environment variables and restart RootCoz if you need to change `ADMIN_KEY`, `ALLOWED_USERS`, `TRUST_PROXY_HEADERS`, or `SECURE_COOKIES`. ## Quick Example ```bash export ROOTCOZ_SERVER="https://rootcoz.example.com" export ROOTCOZ_API_KEY="your-current-admin-key" rootcoz auth whoami rootcoz admin users create newadmin rootcoz admin users list ``` This authenticates the CLI for the current shell, creates a delegated admin named `newadmin`, and shows the users the server currently knows about. ## Step-by-Step 1. Authenticate as an admin. ```bash export ROOTCOZ_SERVER="https://rootcoz.example.com" export ROOTCOZ_API_KEY="your-current-admin-key" rootcoz auth whoami ``` | What you have | How to use it | | --- | --- | | server `ADMIN_KEY` | Sign in in the browser as username `admin`, or pass the key with `ROOTCOZ_API_KEY` or `--api-key` in the CLI | | delegated admin API key | Sign in in the browser with that admin's username, or pass the key with `ROOTCOZ_API_KEY` or `--api-key` in the CLI | In the browser, enter the admin username and API key on the setup screen or in `Settings`. After a successful admin sign-in, the `Users` section becomes available. > **Note:** Use the server `ADMIN_KEY` to bootstrap or recover access. For day-to-day admin work, create named admin users and use their delegated keys instead. 2. Create a delegated admin. ```bash rootcoz admin users create newadmin ``` This creates a named admin account and returns a fresh API key once. Save it immediately before you close the terminal or dialog. In the browser, open `Users`, choose **Create Admin User**, enter the username, and copy the key before closing the dialog. > **Tip:** Create at least two delegated admins. RootCoz will not let you demote or delete the last admin in the user list. 3. Rotate a delegated admin API key. ```bash rootcoz admin users rotate-key newadmin ``` Rotation replaces the user's old admin key immediately. Any current admin browser sessions for that user are also ended, so update saved CLI credentials or automation right away. > **Warning:** The replacement key is shown once. If it is lost, rotate the key again and redistribute the new value. 4. Promote or demote a user. ```bash rootcoz admin users change-role alice admin rootcoz admin users change-role alice user ``` Promoting a known user to `admin` generates a delegated admin key for that user. Demoting an admin back to `user` removes their admin key and ends their current admin sessions. Use promotion when the person already appears in the user list. If they are brand new, ask them to open RootCoz once so they appear in the list, or create them directly as an admin instead. 5. Control who can submit or modify data. ```bash ALLOWED_USERS=alice,bob,carol ``` Set `ALLOWED_USERS` in the server environment and restart RootCoz. When it is empty, write access is open. When it is set, only the listed users can perform write actions such as submitting analyses, adding comments, marking tests reviewed, and overriding classifications. | `ALLOWED_USERS` | Who can write | | --- | --- | | empty or not set | Any user with a username | | `alice,bob,carol` | `alice`, `bob`, or `carol` | | any value, authenticated as admin | Admins always bypass the allow list | Matching is case-insensitive, so `Alice` and `alice` are treated the same. Read-only views are not restricted by the allow list. For regular CLI usage, include a username with `--user` or `ROOTCOZ_USERNAME`. Without that identity, write actions can fail when the allow list is enabled. ## Advanced Usage - Save an admin key in a CLI profile: ```toml [servers.prod] url = "https://rootcoz.example.com" api_key = "rootcoz_your_admin_key" ``` ```bash rootcoz --server prod admin users list ``` This is useful if you administer the same server often. After a key rotation, update the saved `api_key` before you run the next admin command. See [CLI Command Reference](cli-command-reference.html) for the full flag list. - Reduce or remove admin access: ```bash rootcoz admin users change-role oldadmin user rootcoz admin users delete oldadmin ``` Demote a person to `user` if they should keep using RootCoz without admin privileges. Delete is for delegated admin accounts that should be removed entirely. - Let a trusted proxy identify regular users automatically: ```bash TRUST_PROXY_HEADERS=true ``` Enable this only behind a trusted reverse proxy that sends `X-Forwarded-User`. RootCoz will use that username for normal users automatically, but it will not accept a proxy-supplied `admin` as the bootstrap admin account. - Understand what each access change does: | Action | Immediate effect | | --- | --- | | create admin | Generates a new delegated admin key | | rotate key | Old key stops working and current admin sessions for that user end | | promote user to admin | Generates a delegated admin key | | demote admin to user | Revokes the admin key and ends current admin sessions for that user | | delete admin | Removes delegated admin access and ends current sessions for that user | ## Troubleshooting - `Cannot demote the last admin user` or `Cannot delete the last admin user`: create another delegated admin first, then retry. - `User 'name' not found` when changing roles: the user has not appeared in RootCoz yet. Ask them to open RootCoz once, or create them directly as an admin. - `Invalid username or API key` with the bootstrap key: in the browser, use username `admin`. With a delegated key, use the matching admin username. - `Cannot delete your own account` or `Cannot change your own role`: sign in as a different admin and make the change from that account. - `User not allowed. Contact an administrator to be added to the allow list.`: add the username to `ALLOWED_USERS`, or make sure the CLI command includes `--user` or `ROOTCOZ_USERNAME`. - Browser admin login does not stick on local HTTP: set `SECURE_COOKIES=false` for local development, restart RootCoz, and sign in again. ## Related Pages - [Updating Your Profile and Notifications](updating-your-profile-and-notifications.html) - [Configuration Reference](configuration-reference.html) - [CLI Command Reference](cli-command-reference.html) - [API Endpoint Reference](api-endpoint-reference.html) - [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) --- Source: automating-common-tasks-with-the-cli.md # Automating Common Tasks with the CLI Copy these patterns as-is, then swap the concrete server, user, job, and test values for your environment. See [CLI Command Reference](cli-command-reference.html) for every flag, [API Endpoint Reference](api-endpoint-reference.html) for raw `--json` payloads, and [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) for tracker-specific automation. > **Note:** If you already use named server profiles in `~/.config/rootcoz/config.toml`, skip the `ROOTCOZ_SERVER` export and add `--server dev` after `rootcoz` instead. ## Fail Fast on Server Health Use this before cron jobs or CI wrappers so you do not enqueue work against an unhealthy RootCoz server. ```bash set -euo pipefail export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" python3 - <<'PY' import json import subprocess import sys health = json.loads(subprocess.check_output(["rootcoz", "--json", "health"], text=True)) print(f"rootcoz status: {health['status']}") for name, check in sorted(health.get("checks", {}).items()): detail = check.get("detail", "") suffix = f" ({detail})" if detail else "" print(f"{name}: {check.get('status', 'unknown')}{suffix}") sys.exit(1 if health["status"] == "unhealthy" else 0) PY ``` `rootcoz health` uses the detailed `/api/health` endpoint when available and falls back to the lightweight legacy check when it is not. In automation, inspect the JSON `status` field yourself because RootCoz can still return structured health output when the server reports an unhealthy 503. - `rootcoz --json capabilities` reports optional automation flags such as GitHub, Jira, and Report Portal support. - Add `export ROOTCOZ_NO_VERIFY_SSL=true` when you are testing against a server with a self-signed certificate. ## Queue an Analysis and Wait for the Result Use this when you want a single shell block that submits a Jenkins build, waits for RootCoz to finish, and leaves you with the final JSON payload. ```bash set -euo pipefail export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" export ROOTCOZ_USERNAME="alice" job_id="$( rootcoz --json analyze \ --job-name "ocp-e2e-aws-ovn-upgrade" \ --build-number 41892 \ --provider "cursor" \ --model "gpt-5.4-xhigh" \ | python3 -c 'import json, sys; print(json.load(sys.stdin)["job_id"])' )" while :; do status="$( rootcoz --json status "$job_id" \ | python3 -c 'import json, sys; print(json.load(sys.stdin)["status"])' )" echo "$(date -u +%H:%M:%S) $job_id -> $status" case "$status" in completed|failed) break ;; pending|waiting|running) sleep 15 ;; *) echo "Unexpected status: $status" >&2; exit 1 ;; esac done rootcoz --json status "$job_id" ``` The first command queues analysis and captures the returned `job_id`, and the loop keeps polling stored job status until the run becomes `completed` or `failed`. The final `status --json` call gives the next step a full machine-readable result document instead of just a short table. - Add `--wait --poll-interval 2 --max-wait 30` if the Jenkins build might still be running when you submit the analysis. - `rootcoz ai-models --provider cursor` lists valid model IDs, and `rootcoz ai-configs` shows provider/model pairs that already completed successfully on this server. - Use `--peers "cursor:gpt-5.4-xhigh,gemini:gemini-2.5-pro"` or `--additional-repos "infra:https://github.com/acme/infra"` when the AI needs extra debate or repository context. ## Re-run a Previous Analysis Use this when you want a fresh run from the same saved settings instead of rebuilding the original request by hand. ```bash set -euo pipefail export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" export ROOTCOZ_USERNAME="alice" source_job_id="$( rootcoz --json results list --limit 1 \ | python3 -c 'import json, sys; print(json.load(sys.stdin)[0]["job_id"])' )" new_job_id="$( rootcoz --json re-analyze "$source_job_id" \ | python3 -c 'import json, sys; print(json.load(sys.stdin)["job_id"])' )" echo "Re-analysis queued: $source_job_id -> $new_job_id" ``` The first command grabs the newest stored job ID, and the second queues a re-analysis that reuses the original request parameters. Replace the `results list` step with a specific job ID when you want to replay a particular historical run instead of the latest one. ## Review a Failing Test from the Shell Use this when you already know the run and test you want to comment on and mark reviewed. ```bash set -euo pipefail export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" export ROOTCOZ_USERNAME="alice" job_id="9a5ac7e2-1b61-4e67-a2a8-0dbb3c7ef5b1" test_name="tests.network.TestIngress.test_route_flaps" rootcoz results review-status "$job_id" rootcoz comments add "$job_id" \ --test "$test_name" \ --message "@bob reproduced this during the 2026-04-18 router rollout; tracking in NET-4281" rootcoz results set-reviewed "$job_id" \ --test "$test_name" \ --reviewed ``` This checks the run's review counts, adds a comment to one failing test, and then marks that failure as reviewed under your username. It is the fastest CLI workflow when you already know the `job_id` and fully qualified test name you want to close out. - `rootcoz mentionable-users` lists usernames you can safely `@mention`. - `rootcoz classify "$test_name" --type INFRASTRUCTURE --job-id "$job_id" --reason "router rollout"` stores a classification alongside the review. - Add `--child-job` and `--child-build` to both commands when the failure came from a pipeline child job. ## Check One Test's Failure History Use this when you want the recent context for a single failing test before you classify or review it. ```bash export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" export ROOTCOZ_USERNAME="alice" rootcoz history test \ "tests.network.TestIngress.test_route_flaps" \ --job-name "ocp-e2e-aws-ovn-upgrade" \ --limit 10 ``` This prints the failure count, failure rate, last classification, recent runs, and related comments for one fully qualified test name. Use it when you need quick context on whether a failure is new, noisy, or already well understood. - Add `--exclude-job-id "9a5ac7e2-1b61-4e67-a2a8-0dbb3c7ef5b1"` to compare against earlier history without the run you are currently triaging. ## Build a Filtered Failure Queue Use this when you need a small, scripted batch of historical failures filtered by job, classification, and search text. ```bash set -euo pipefail export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" export ROOTCOZ_USERNAME="alice" rootcoz --json history failures \ --job-name "ocp-e2e-aws-ovn-upgrade" \ --classification "PRODUCT BUG" \ --search "route" \ --limit 20 \ --offset 0 \ > product-bug-queue.json echo "Saved product-bug-queue.json" ``` This builds a paginated slice of historical failures filtered by job, stored classification, and search text. It works well for ad hoc review queues and for exporting small batches into other tools. - Drop `--json` if you want the built-in table instead of a file. - If you already have a specific error signature hash, use `rootcoz history search --signature "4e6f3e8c1e6c4540833d6f2d3f89ce9a83c5a7d54b4f6e5b19f9d4f642b9a4c1"`. ## Work Through Unread Mentions Use this when you want an inbox-like CLI loop for comments that mentioned your username. ```bash export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" export ROOTCOZ_USERNAME="alice" rootcoz mentions --unread rootcoz mentions-mark-read --ids "812,815" ``` `mentions --unread` limits the list to new notifications for the current user, and `mentions-mark-read` accepts a comma-separated list of comment IDs. This gives you a quick follow-up flow without opening the web UI. - Use `rootcoz mentions-mark-all-read` to clear everything in one step. - Add `--offset 50` to page through older mentions. ## Confirm Admin Access Before Changes Use this before creating users, changing roles, or rotating keys so you know exactly which admin identity the CLI is using. ```bash export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" read -rsp "Admin API key: " ROOTCOZ_API_KEY export ROOTCOZ_API_KEY echo rootcoz auth whoami rootcoz admin users list ``` Admin commands authenticate with `--api-key` or `ROOTCOZ_API_KEY`, so this pattern keeps the key out of shell history while still making the rest of the shell session usable. `auth whoami` confirms the effective identity before you create, delete, or change users. > **Warning:** `admin users create`, `admin users change-role ... admin`, and `admin users rotate-key` show the new API key once and it cannot be retrieved later. - `rootcoz admin users create "release-bot"` creates a delegated admin and prints its first API key. - `rootcoz admin users rotate-key "release-bot"` rotates an existing key. - `rootcoz auth login --username "platform-admin" --api-key "$ROOTCOZ_API_KEY"` validates credentials without changing config, but it does not persist a session. ## Export Weekly Token Usage Use this when you need a quick weekly usage file for chargeback, provider comparisons, or admin reporting. ```bash export ROOTCOZ_SERVER="https://rootcoz.ci.example.com" read -rsp "Admin API key: " ROOTCOZ_API_KEY export ROOTCOZ_API_KEY echo rootcoz admin token-usage \ --period week \ --group-by provider \ --format csv \ > rootcoz-token-usage-weekly.csv echo "Saved rootcoz-token-usage-weekly.csv" ``` With no filters, `admin token-usage` prints a summary dashboard; adding `--period` or `--group-by` switches it into filtered reporting mode. CSV output is convenient when you want a file you can hand off to finance, ops, or another script. - `rootcoz admin token-usage --job-id "9a5ac7e2-1b61-4e67-a2a8-0dbb3c7ef5b1"` shows token and cost details for one analysis. - `rootcoz --json admin token-usage --provider cursor --group-by model` gives machine-readable per-model usage for one provider. ## Related Pages - [CLI Command Reference](cli-command-reference.html) - [API Endpoint Reference](api-endpoint-reference.html) - [Configuration Reference](configuration-reference.html) - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) --- Source: connecting-github-jira-and-report-portal.md # Connecting GitHub, Jira, and Report Portal ## Check Server Readiness Use this when you want to see which integrations are already available before you start saving tokens or restarting the server. ```bash export ROOTCOZ_SERVER="http://localhost:8000" rootcoz capabilities --json rootcoz health --json ``` `github_issues_enabled` and `jira_issues_enabled` are feature toggles, while `server_github_token`, `server_jira_token`, `server_jira_project_key`, `reportportal`, and `reportportal_project` show how much the server can do without your own credentials. `health` is also where Report Portal validation lives, because the server probes the RP API and reports that result under `checks.reportportal`. > **Tip:** For the exact JSON fields, see [API Endpoint Reference](api-endpoint-reference.html). ## Validate a GitHub PAT Use this when you want to confirm a GitHub token works before you depend on it for duplicate checks or issue submission. ```bash export ROOTCOZ_SERVER="http://localhost:8000" rootcoz validate-token github --token "ghp_EXAMPLE_TOKEN_REPLACE_ME" ``` The server validates the token with GitHub's `/user` endpoint and prints the authenticated login on success. This does not store the token anywhere, so it is the safest first smoke test before you save it in rootcoz or automation. - GitHub tracker actions use a personal access token with `repo` access. - A valid token alone is not enough for submission; rootcoz also needs a target GitHub repository from the analyzed result, `TESTS_REPO_URL`, or `github_repo_url`. ## Validate Jira Access Use this when you want to confirm Jira access and discover the project key or security level rootcoz should use later. ```bash export ROOTCOZ_SERVER="http://localhost:8000" JIRA_TOKEN="ATATT3xFfGF0AbM93-example-token" JIRA_EMAIL="alice@example.com" rootcoz validate-token jira --token "$JIRA_TOKEN" --email "$JIRA_EMAIL" rootcoz jira-projects --jira-token "$JIRA_TOKEN" --jira-email "$JIRA_EMAIL" rootcoz jira-security-levels QE --jira-token "$JIRA_TOKEN" --jira-email "$JIRA_EMAIL" ``` The validation call uses the server's configured `JIRA_URL`, then the lookup commands show which projects and security levels that token can actually see. Provide `--email` for Jira Cloud; omit it for Jira Server/Data Center bearer-token auth. - Prefer `JIRA_PAT` on the server side; rootcoz still accepts `JIRA_API_TOKEN`, but current auth resolution prefers `JIRA_PAT` when both exist. - `jira-security-levels` returns an empty list when the project has no issue security or the token cannot read it. ## Save Personal Tracker Tokens Use this when you want browser-based tracker actions to run under your own identity instead of only server-wide credentials. ```bash ROOTCOZ_SERVER="http://localhost:8000" USERNAME="alice" curl -sS -b "rootcoz_username=$USERNAME" \ "$ROOTCOZ_SERVER/api/dashboard" >/dev/null curl -sS -X PUT "$ROOTCOZ_SERVER/api/user/tokens" \ -H "Content-Type: application/json" \ -b "rootcoz_username=$USERNAME" \ -d '{ "github_token": "ghp_EXAMPLE_TOKEN_REPLACE_ME", "jira_email": "alice@example.com", "jira_token": "ATATT3xFfGF0AbM93-example-token" }' curl -sS -b "rootcoz_username=$USERNAME" \ "$ROOTCOZ_SERVER/api/user/tokens" ``` The first request ensures the username exists in the database, and the token save call stores only the fields you send for that user. Rootcoz encrypts those saved tracker tokens at rest, and the same API lets you read them back to verify what is currently on the server. > **Tip:** Send only the fields you want to change; omitted tracker fields keep their existing values. ## Store Tracker Defaults in CLI Config Use this when you want repeatable CLI tracker workflows without retyping tokens, repo URLs, or project keys every time. ```bash mkdir -p ~/.config/rootcoz cat > ~/.config/rootcoz/config.toml <<'EOF' [default] server = "lab" [servers.lab] url = "http://localhost:8000" username = "alice" github_token = "ghp_EXAMPLE_TOKEN_REPLACE_ME" github_repo_url = "https://github.com/acme/platform-tests" jira_token = "ATATT3xFfGF0AbM93-example-token" jira_email = "alice@example.com" jira_project_key = "QE" jira_security_level = "Internal" EOF rootcoz config show ``` The CLI reads `~/.config/rootcoz/config.toml` and uses these tracker fields as defaults when you omit flags. That keeps repeated Jira and issue commands short, while one-off CLI flags still override the config when you need a different token or target. > **Warning:** The CLI config file is plain text on disk, so protect it the same way you protect any other local secret. > **Tip:** See [CLI Command Reference](cli-command-reference.html) for the full set of commands that read config defaults. ## Enable Server-Side Issue Creation Use this when you run your own rootcoz server and want GitHub and Jira issue actions available even before users add personal tokens. ```bash export TESTS_REPO_URL="https://github.com/acme/platform-tests" export GITHUB_TOKEN="ghp_EXAMPLE_SERVER_TOKEN" export ENABLE_GITHUB_ISSUES=true export JIRA_URL="https://acme.atlassian.net" export JIRA_EMAIL="rootcoz-bot@acme.example" export JIRA_PAT="ATATT3xFfGF0AbM93-server-example-token" export JIRA_PROJECT_KEY="QE" export ENABLE_JIRA_ISSUES=true docker compose up -d --force-recreate rootcoz export ROOTCOZ_SERVER="http://localhost:8000" rootcoz capabilities --json ``` This gives the server its own GitHub and Jira defaults so previews, duplicate checks, and tracker submission can work without waiting for per-user setup. If you run rootcoz outside Docker Compose, restart that process with the same environment variables instead. - On Jira Server/Data Center, drop `JIRA_EMAIL` and keep `JIRA_PAT`. - Users can still override server defaults with their own GitHub or Jira tokens when they want issues filed under their own account. ## Enable Report Portal Use this when you want rootcoz to expose Report Portal push controls and verify the RP token before the first push. ```bash export REPORTPORTAL_URL="https://rp.acme.example" export REPORTPORTAL_API_TOKEN="rp_api_token_for_rootcoz" export REPORTPORTAL_PROJECT="platform-qe" export PUBLIC_BASE_URL="https://rootcoz.acme.example" export ENABLE_REPORTPORTAL=true docker compose up -d --force-recreate rootcoz export ROOTCOZ_SERVER="http://localhost:8000" rootcoz health --json rootcoz capabilities --json ``` Rootcoz only exposes Report Portal push when the URL, API token, and project are all configured, and the health check is where the server validates that token. `PUBLIC_BASE_URL` is required because the RP comment payload includes a link back to the rootcoz result page. > **Warning:** Report Portal push cannot work with relative rootcoz URLs; set `PUBLIC_BASE_URL` to the externally reachable rootcoz origin. - Set `REPORTPORTAL_VERIFY_SSL=false` if your RP instance uses a self-signed certificate. - `capabilities` should show `reportportal: true` and the configured `reportportal_project`. ## Push a Result to Report Portal Use this when you want rootcoz classifications copied into the matching Report Portal launch for the most recent result returned by the CLI. ```bash export ROOTCOZ_SERVER="http://localhost:8000" JOB_ID="$(rootcoz results list --json | python -c 'import json,sys; print(json.load(sys.stdin)[0]["job_id"])')" rootcoz push-reportportal "$JOB_ID" --json ``` Rootcoz finds the matching launch from the Jenkins build URL stored in the RP launch description, matches failed items to rootcoz failures by test name, and updates defect types in one batch. When a failure already has Jira matches, rootcoz also sends them to Report Portal as external issues, so the response is the thing to inspect for `pushed`, `unmatched`, `errors`, and `launch_id`. > **Warning:** If the matching RP launch does not contain the Jenkins build URL in its description, rootcoz cannot find it and the push returns a structured error instead of an update. - To target a pipeline child analysis, add `--child-job-name "e2e-upgrade" --child-build-number 42`. - If you want a specific job instead of the newest one, pick a different `job_id` from `rootcoz results list --json`. ## Related Pages - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) - [Updating Your Profile and Notifications](updating-your-profile-and-notifications.html) - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) - [Configuration Reference](configuration-reference.html) - [CLI Command Reference](cli-command-reference.html) --- Source: cli-command-reference.md # CLI Command Reference `rootcoz [GLOBAL OPTIONS] COMMAND [ARGS]...` > **Note:** For profile fields, config file layout, and environment-backed defaults, see [Configuration Reference](configuration-reference.html). > **Tip:** For task-focused command patterns, see [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html). > **Note:** For HTTP request and response schemas, see [API Endpoint Reference](api-endpoint-reference.html). ## Global Options These options are accepted before the command name. | Name | Type | Default | Description | | --- | --- | --- | --- | | `--server`, `-s` | string | default profile if configured | Server profile name or full base URL. Reads `ROOTCOZ_SERVER`. | | `--json` | boolean | `false` | Print JSON instead of text output for commands that support JSON output. | | `--user` | string | profile value or empty | Username used for comments and review actions. Reads `ROOTCOZ_USERNAME`. | | `--api-key` | string | profile value or empty | Bearer token used for admin-authenticated requests. Reads `ROOTCOZ_API_KEY`. | | `--no-verify-ssl` | boolean | profile value or `false` | Disable HTTPS certificate verification. Reads `ROOTCOZ_NO_VERIFY_SSL`. | | `--verify-ssl` | boolean | unset | Force HTTPS certificate verification on, even when the selected profile disables it. | | `--insecure` | boolean | `false` | Alias for `--no-verify-ssl`. | | `--show-completion` | `bash` \| `zsh` | unset | Print the shell completion script for the selected shell. | | `--help` | boolean | `false` | Show help for the current command. | > **Warning:** `--verify-ssl` and `--insecure` cannot be used together. > **Note:** When `--server` is a full URL, profile values do not cascade into the command. When `--server` is omitted, `rootcoz` uses the default profile from `$XDG_CONFIG_HOME/rootcoz/config.toml` or `~/.config/rootcoz/config.toml`. Example: ```bash rootcoz --server dev --json results list ``` ## Output Modes | Mode | Syntax | Effect | | --- | --- | --- | | Text | default | Prints aligned tables, short status lines, or command-specific plain text. Table output preserves full values. | | JSON | `rootcoz --json ...` or `rootcoz --json` | Prints pretty-printed JSON with 2-space indentation for commands that support JSON output. | | Full result JSON | `rootcoz results show JOB_ID --full` | Prints the complete stored result document. | | Token usage CSV | `rootcoz admin token-usage --format csv` | Prints CSV instead of text. | > **Note:** Command tables below list command-specific parameters only. Apply the global options above to any leaf command unless the command section says otherwise. Example: ```bash rootcoz --json health rootcoz results list --json rootcoz results show job-123 --full rootcoz admin token-usage --group-by provider --format csv ``` ## Analysis and Results > **Tip:** See [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html), [Tracking Analysis Progress](tracking-analysis-progress.html), and [Finding Runs on the Dashboard](finding-runs-on-the-dashboard.html) for workflow guidance. ### `health` Checks server availability. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz health ``` Return value/effect: Prints the current service status and any named health checks. ### `analyze` Queues a Jenkins build for analysis. > **Note:** Unset options can fall back to the selected server profile. Env-backed flags read the environment variable named in the description before profile fallback. > **Warning:** `--build-number`, `--ai-cli-timeout`, `--jenkins-timeout`, `--jenkins-artifacts-max-size-mb`, `--jira-max-results`, and `--poll-interval` must be greater than `0` when set. `--max-wait` and `--max-concurrent` must be non-negative. `--peer-analysis-max-rounds` must be between `1` and `10`. Core options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--job-name`, `-j` | option | string | required | Jenkins job name. | | `--build-number`, `-b` | option | integer | required | Jenkins build number to analyze. | | `--provider` | option | string | unset | AI provider. Profile fallback applies. | | `--model` | option | string | unset | AI model. Profile fallback applies. | | `--jira` / `--no-jira` | option | boolean | unset | Enable or disable Jira integration for this request. | | `--raw-prompt` | option | string | empty | Extra AI instructions appended to the request. | Jenkins and repository options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--jenkins-url` | option | string | unset | Jenkins base URL. Reads `JENKINS_URL`. | | `--jenkins-user` | option | string | unset | Jenkins username. Reads `JENKINS_USER`. | | `--jenkins-password` | option | string | unset | Jenkins password or API token. Reads `JENKINS_PASSWORD`. | | `--jenkins-ssl-verify` / `--no-jenkins-ssl-verify` | option | boolean | unset | Override Jenkins HTTPS certificate verification. | | `--jenkins-timeout` | option | integer | unset | Jenkins API timeout in seconds. | | `--jenkins-artifacts-max-size-mb` | option | integer | unset | Maximum downloaded artifact size in MB. | | `--get-job-artifacts` / `--no-get-job-artifacts` | option | boolean | unset | Download all job artifacts for analysis context. | | `--tests-repo-url` | option | string | unset | Tests repository URL. Reads `TESTS_REPO_URL`. | | `--tests-repo-token` | option | string | unset | Token for cloning a private tests repository. Reads `TESTS_REPO_TOKEN`. | | `--additional-repos` | option | string | unset | Comma-separated repo specs in `name:url`, optionally with `:ref` and `@token`. | Jira, GitHub, and peer-AI options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--jira-url` | option | string | unset | Jira base URL. Reads `JIRA_URL`. | | `--jira-email` | option | string | unset | Jira Cloud email. Reads `JIRA_EMAIL`. | | `--jira-api-token` | option | string | unset | Jira Cloud API token. Reads `JIRA_API_TOKEN`. | | `--jira-pat` | option | string | unset | Jira Server/Data Center PAT. Reads `JIRA_PAT`. | | `--jira-project-key` | option | string | unset | Jira project key. Reads `JIRA_PROJECT_KEY`. | | `--jira-ssl-verify` / `--no-jira-ssl-verify` | option | boolean | unset | Override Jira HTTPS certificate verification. | | `--jira-max-results` | option | integer | unset | Maximum number of Jira search matches. | | `--github-token` | option | string | unset | GitHub token. Reads `GITHUB_TOKEN`. | | `--ai-cli-timeout` | option | integer | unset | AI CLI timeout in minutes. | | `--peers` | option | string | unset | Comma-separated `provider:model` peer-analysis list. | | `--peer-analysis-max-rounds` | option | integer | unset | Maximum peer-analysis rounds. | Queue and concurrency options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--wait` / `--no-wait` | option | boolean | unset | Wait or do not wait for the Jenkins build to finish before analysis. | | `--poll-interval` | option | integer | unset | Minutes between Jenkins polls. | | `--max-wait` | option | integer | unset | Maximum minutes to wait for completion. `0` means no time limit when the server accepts it. | | `--force` / `--no-force` | option | boolean | unset | Analyze even when the build succeeded, or explicitly disable that behavior. | | `--max-concurrent` | option | integer | `0` | Maximum concurrent AI CLI calls. `0` means no CLI-side override. | Example: ```bash rootcoz analyze \ --job-name ocp-e2e-aws \ --build-number 1542 \ --provider claude \ --model claude-sonnet-4 \ --wait ``` Return value/effect: Queues the analysis and prints the new `job_id`, queue `status`, and result polling URL. ### `re-analyze` Queues a new analysis using the saved settings from an earlier job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Existing analysis job ID to re-run. | Example: ```bash rootcoz re-analyze job-123 ``` Return value/effect: Queues a new analysis and prints the new `job_id`, `status`, and result URL. ### `status` Shows the current state of one analysis job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID to query. | Example: ```bash rootcoz status job-123 ``` Return value/effect: Default output is a two-column table with `job_id` and `status`. JSON mode returns the full stored result payload. ### `results list` Lists recent analysis jobs. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--limit`, `-l` | option | integer | `50` | Maximum number of jobs to return. | Example: ```bash rootcoz results list --limit 10 ``` Return value/effect: Prints a table with `job_id`, `status`, `jenkins_url`, and `created_at`. ### `results dashboard` Lists analysis jobs with dashboard metadata. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz results dashboard ``` Return value/effect: Prints a table with `job_id`, `job_name`, `build_number`, `status`, `failure_count`, `reviewed_count`, `comment_count`, and `created_at`. ### `results show` Shows one stored analysis result. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID to display. | | `--full`, `-f` | option | boolean | `false` | Print the complete result document as JSON. | Example: ```bash rootcoz results show job-123 ``` Return value/effect: Default output is a summary table with `job_id`, `status`, `summary`, `failures`, `children`, `ai_provider`, and `created_at`. `--full` prints the full result JSON. ### `results delete` Deletes one or more stored analysis jobs. > **Warning:** `--all` requires `--confirm` and cannot be combined with explicit job IDs. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID ...` | arg | string[] | required unless `--all` | One or more analysis job IDs to delete. | | `--all` | option | boolean | `false` | Delete every job returned by the dashboard listing. | | `--confirm` | option | boolean | `false` | Required safety flag for `--all`. | Example: ```bash rootcoz results delete job-123 job-124 ``` Return value/effect: Deletes the requested job IDs. Single-job runs print one confirmation line; multi-job runs print a success summary and any failures. ### `results review-status` Shows review progress for one result set. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | Example: ```bash rootcoz results review-status job-123 ``` Return value/effect: Prints a table with `total_failures`, `reviewed_count`, and `comment_count`. ### `results set-reviewed` Sets or clears the reviewed state for one failure. > **Warning:** `--child-build` must be non-negative. Values greater than `0` require `--child-job`. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | | `--test`, `-t` | option | string | required | Test name to update. | | `--reviewed` / `--not-reviewed` | option | boolean | required | Mark the failure reviewed or not reviewed. | | `--child-job` | option | string | empty | Child job name for pipeline child failures. | | `--child-build` | option | integer | `0` | Child build number for pipeline child failures. | Example: ```bash rootcoz results set-reviewed job-123 --test tests.TestA.test_one --reviewed ``` Return value/effect: Prints a short confirmation line, including the reviewer name when the server returns it. ### `results enrich-comments` Refreshes stored comment links with live tracker state. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | Example: ```bash rootcoz results enrich-comments job-123 ``` Return value/effect: Refreshes linked PR and ticket state for the job's comments and prints a completion line. ### `ai-configs` Lists AI provider/model pairs found in completed analyses. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz ai-configs ``` Return value/effect: Prints a table with `ai_provider` and `ai_model`. If no completed analyses contributed configurations, it prints an empty-state message. ### `ai-models` Lists currently available models by AI provider. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--provider`, `-p` | option | string | empty | Limit output to one provider. | Example: ```bash rootcoz ai-models --provider claude ``` Return value/effect: With `--provider`, prints the models for that provider. Without it, prints one section per provider with a model count and `id`/`name` rows. ## History and Classification > **Tip:** See [Exploring Failure History and Test Trends](exploring-failure-history-and-test-trends.html) and [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) for workflow guidance. ### `history test` Shows failure history for one fully qualified test name. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `TEST_NAME` | arg | string | required | Fully qualified test name. | | `--limit`, `-l` | option | integer | `20` | Maximum number of recent runs to return. | | `--job-name`, `-j` | option | string | empty | Limit history to one Jenkins job name. | | `--exclude-job-id` | option | string | empty | Exclude results from one analysis job ID. | Example: ```bash rootcoz history test tests.TestA.test_one --limit 10 ``` Return value/effect: Prints summary lines for the test, then a `Recent runs` table and a `Comments` table when those sections are present. ### `history search` Finds tests that share one error signature. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--signature`, `-s` | option | string | required | Error signature hash to search for. | | `--exclude-job-id` | option | string | empty | Exclude results from one analysis job ID. | Example: ```bash rootcoz history search --signature 2f0c8d0c... ``` Return value/effect: Prints the signature, total occurrence count, unique test count, and a table of matching tests. ### `history stats` Shows aggregate history statistics for one Jenkins job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_NAME` | arg | string | required | Jenkins job name. | | `--exclude-job-id` | option | string | empty | Exclude results from one analysis job ID. | Example: ```bash rootcoz history stats ocp-e2e-aws ``` Return value/effect: Prints job-level totals and, when available, a `Most common failures` table. ### `history failures` Lists paginated failure history across jobs. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--limit`, `-l` | option | integer | `50` | Maximum rows to return. | | `--offset`, `-o` | option | integer | `0` | Pagination offset. | | `--search`, `-s` | option | string | empty | Test-name search string. | | `--classification`, `-c` | option | string | empty | Classification filter. | | `--job-name`, `-j` | option | string | empty | Jenkins job-name filter. | Example: ```bash rootcoz history failures --classification "PRODUCT BUG" --limit 25 ``` Return value/effect: Prints a total-count line followed by a table with `test_name`, `job_name`, `classification`, and `analyzed_at`. ### `classify` Creates a classification for one failure. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `TEST_NAME` | arg | string | required | Fully qualified test name. | | `--type`, `-t` | option | string | required | Classification type: `FLAKY`, `REGRESSION`, `INFRASTRUCTURE`, `KNOWN_BUG`, or `INTERMITTENT`. | | `--job-id` | option | string | required | Analysis job ID this classification belongs to. | | `--reason`, `-r` | option | string | empty | Free-text reason. | | `--job-name`, `-j` | option | string | empty | Jenkins job name for the failure. | | `--references` | option | string | empty | Bug URLs or ticket keys. | | `--child-job` | option | string | empty | Child job name for pipeline child failures. | | `--child-build` | option | integer | `0` | Child build number for pipeline child failures. | Example: ```bash rootcoz classify tests.TestA.test_one --type FLAKY --job-id job-123 --reason "Intermittent DNS lookup" ``` Return value/effect: Creates a classification record and prints its server-generated ID. ### `classifications list` Lists stored classifications. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--job-id` | option | string | empty | Filter by analysis job ID. | | `--test-name`, `-t` | option | string | empty | Filter by test name. | | `--type`, `-c` | option | string | empty | Filter by classification type. | | `--job-name`, `-j` | option | string | empty | Filter by job name. | | `--parent-job-name` | option | string | empty | Filter by parent job name. | Example: ```bash rootcoz classifications list --type FLAKY --job-name ocp-e2e-aws ``` Return value/effect: Prints a table with `test_name`, `classification`, `reason`, `created_by`, and `created_at`. If nothing matches, it prints an empty-state message. ### `override-classification` Overrides one failure's top-level classification. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | | `--test`, `-t` | option | string | required | Test name to override. | | `--classification`, `-c` | option | string | required | Override value, such as `CODE ISSUE`, `PRODUCT BUG`, or `INFRASTRUCTURE`. | | `--child-job` | option | string | empty | Child job name for pipeline child failures. | | `--child-build` | option | integer | `0` | Child build number for pipeline child failures. | Example: ```bash rootcoz override-classification job-123 --test tests.TestA.test_one --classification "PRODUCT BUG" ``` Return value/effect: Updates the stored classification and prints the final value returned by the server. ## Comments and Mentions > **Tip:** See [Commenting and Mentioning Teammates](commenting-and-mentioning-teammates.html) for workflow guidance. ### `comments list` Lists comments for one analysis job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | Example: ```bash rootcoz comments list job-123 ``` Return value/effect: Prints a table with `id`, `test_name`, `comment`, `username`, and `created_at`. If the job has no comments, it prints an empty-state message. ### `comments add` Adds a comment to one failure. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | | `--test`, `-t` | option | string | required | Test name to comment on. | | `--message`, `-m` | option | string | required | Comment text. | | `--child-job` | option | string | empty | Child job name for pipeline child failures. | | `--child-build` | option | integer | `0` | Child build number for pipeline child failures. | Example: ```bash rootcoz comments add job-123 --test tests.TestA.test_one --message "Opened PROJ-456" ``` Return value/effect: Creates the comment and prints the new comment ID. ### `comments delete` Deletes one comment. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | | `COMMENT_ID` | arg | integer | required | Comment ID to remove. | Example: ```bash rootcoz comments delete job-123 42 ``` Return value/effect: Deletes the comment and prints a confirmation line. ### `mentionable-users` Lists usernames that can be mentioned in comments. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz mentionable-users ``` Return value/effect: Prints one username per line. If no users are available, it prints an empty-state message. ### `mentions` Lists the current user's mentions. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--limit`, `-l` | option | integer | `50` | Maximum mentions to return. | | `--offset`, `-o` | option | integer | `0` | Pagination offset. | | `--unread` | option | boolean | `false` | Limit results to unread mentions. | Example: ```bash rootcoz mentions --unread ``` Return value/effect: Prints the total and unread counts, then a table with `id`, `job_id`, `test_name`, `comment`, `username`, `is_read`, and `created_at`. ### `mentions-mark-read` Marks selected mentions as read. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--ids` | option | `csv` | required | Comma-separated positive comment IDs. | Example: ```bash rootcoz mentions-mark-read --ids 10,11,12 ``` Return value/effect: Marks the listed mentions as read and exits successfully when the server accepts the request. ### `mentions-mark-all-read` Marks every mention for the current user as read. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz mentions-mark-all-read ``` Return value/effect: Marks all mentions as read and exits successfully when the server accepts the request. ### `analyze-comment-intent` Runs AI intent detection on one comment string. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `COMMENT` | arg | string | required | Comment text to analyze. | | `--job-id` | option | string | empty | Job ID used to resolve AI settings from an analyzed job. | | `--ai-provider` | option | string | empty | Override AI provider. | | `--ai-model` | option | string | empty | Override AI model. | Example: ```bash rootcoz analyze-comment-intent "Fixed in PR #42" ``` Return value/effect: Prints whether the comment suggests the failure is reviewed and, when present, the returned reason string. ## Issue and Integration Commands > **Tip:** See [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) for issue workflows and [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html) for setup details. ### `capabilities` Shows server-side automation feature flags. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz capabilities ``` Return value/effect: Prints a JSON object that reports whether GitHub issue creation and Jira bug creation are enabled on the server. ### `jira-projects` Lists Jira projects available to the current credentials. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--query` | option | string | empty | Search filter applied to Jira projects. | | `--jira-token` | option | string | unset | Jira token override. If omitted, the selected profile may supply it. | | `--jira-email` | option | string | unset | Jira email override. If omitted, the selected profile may supply it. | Example: ```bash rootcoz jira-projects --query platform ``` Return value/effect: Prints a table with project `key` and `name`. If no projects match, it prints an empty-state message. ### `jira-security-levels` Lists Jira security levels for one project. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `PROJECT_KEY` | arg | string | required | Jira project key. | | `--jira-token` | option | string | unset | Jira token override. If omitted, the selected profile may supply it. | | `--jira-email` | option | string | unset | Jira email override. If omitted, the selected profile may supply it. | Example: ```bash rootcoz jira-security-levels PROJ ``` Return value/effect: Prints a table with security level `name` and `description`. If the project exposes none, it prints an empty-state message. ### `preview-issue` Generates issue content for GitHub or Jira without creating the issue. > **Warning:** `--type` accepts only `github` or `jira`. > **Note:** GitHub-only overrides are used only when `--type github` is selected. Jira-only overrides are used only when `--type jira` is selected. Core options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | | `--test`, `-t` | option | string | required | Test name to preview. | | `--type` | option | string | required | Issue target: `github` or `jira`. | | `--child-job` | option | string | empty | Child job name for pipeline child failures. | | `--child-build` | option | integer | `0` | Child build number for pipeline child failures. | | `--include-links` | option | boolean | `false` | Include full URLs in the generated text. | | `--ai-provider` | option | string | empty | Override AI provider for issue generation. | | `--ai-model` | option | string | empty | Override AI model for issue generation. | | `--issue-prompt` | option | string | empty | Extra AI instructions for issue generation. | Tracker override options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--github-token` | option | string | unset | GitHub token override. | | `--github-repo-url` | option | string | unset | GitHub repository URL override. | | `--jira-token` | option | string | unset | Jira token override. | | `--jira-email` | option | string | unset | Jira email override. | | `--jira-project-key` | option | string | unset | Jira project key override. | | `--jira-security-level` | option | string | unset | Jira security level name override. | Example: ```bash rootcoz preview-issue job-123 --test tests.TestA.test_one --type github --include-links ``` Return value/effect: Prints the generated issue title and body. When the server returns related matches, it also prints a `Similar issues` section. ### `get-issue-prompt` Shows the issue-generation prompt associated with one analysis job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | Example: ```bash rootcoz get-issue-prompt job-123 ``` Return value/effect: Prints the stored prompt text. If the job has no issue prompt, it prints an empty-state message. ### `create-issue` Creates a GitHub issue or Jira issue from an analyzed failure. > **Warning:** `--type` accepts only `github` or `jira`. Core options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID. | | `--test`, `-t` | option | string | required | Test name to create the issue from. | | `--type` | option | string | required | Issue target: `github` or `jira`. | | `--title` | option | string | required | Final issue title. | | `--body` | option | string | required | Final issue body. | | `--child-job` | option | string | empty | Child job name for pipeline child failures. | | `--child-build` | option | integer | `0` | Child build number for pipeline child failures. | Tracker override options | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--github-token` | option | string | unset | GitHub token override. | | `--github-repo-url` | option | string | unset | GitHub repository URL override. | | `--jira-token` | option | string | unset | Jira token override. | | `--jira-email` | option | string | unset | Jira email override. | | `--jira-project-key` | option | string | unset | Jira project key override. | | `--jira-security-level` | option | string | unset | Jira security level name override. | | `--jira-issue-type` | option | string | `Bug` | Jira issue type name, such as `Bug`, `Story`, or `Task`. | Example: ```bash rootcoz create-issue \ job-123 \ --test tests.TestA.test_one \ --type jira \ --title "DNS timeout in tests.TestA.test_one" \ --body "Observed in build 1542." \ --jira-issue-type Bug ``` Return value/effect: Creates the issue, then prints the created key or number, the issue URL, and an added comment ID when the server returns one. ### `validate-token` Validates a GitHub or Jira token. > **Warning:** Invalid tokens exit with status code `1`, including JSON mode. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `TOKEN_TYPE` | arg | string | required | Token target: `github` or `jira`. | | `--token` | option | string | prompted | Token value to validate. Input is hidden when prompted. | | `--email` | option | string | empty | Jira Cloud email to send with Jira token validation. | Example: ```bash rootcoz validate-token github --token "$GITHUB_TOKEN" ``` Return value/effect: Prints a valid or invalid status line. In JSON mode, it prints the validation response object. ### `push-reportportal` Pushes stored classifications into Report Portal. > **Note:** Alias: `push-rp`. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_ID` | arg | string | required | Analysis job ID to push. | | `--child-job-name` | option | string | unset | Child job name for pipeline child pushes. | | `--child-build-number` | option | integer | unset | Child build number for pipeline child pushes. | Example: ```bash rootcoz push-reportportal job-123 --child-job-name my-child --child-build-number 42 ``` Return value/effect: Prints the number of pushed classifications, the launch ID when returned, any unmatched tests, and any error count/details. ## Authentication and Admin Commands > **Tip:** See [Managing Users and API Keys](managing-users-and-api-keys.html) and [Updating Your Profile and Notifications](updating-your-profile-and-notifications.html) for workflow guidance. ### `auth login` Validates admin credentials. > **Note:** This command does not persist a login session across later CLI invocations. Persistent admin access is normally provided by the global `--api-key`, `ROOTCOZ_API_KEY`, or a profile `api_key`. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--username`, `-u` | option | string | required | Admin username to validate. | | `--api-key`, `-k` | option | string | required | Admin API key to validate. | Example: ```bash rootcoz auth login --username admin --api-key "$ROOTCOZ_ADMIN_KEY" ``` Return value/effect: Prints the returned username, role, and admin flag. ### `auth logout` Sends the logout request. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz auth logout ``` Return value/effect: Sends the logout request and exits successfully when the server accepts it. ### `auth whoami` Shows the current authenticated user record. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz auth whoami ``` Return value/effect: Prints a table with `username`, `role`, and `is_admin`. ### `admin users list` Lists known users. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz admin users list ``` Return value/effect: Prints a table with `username`, `role`, `created_at`, and `last_seen`. ### `admin users create` Creates a new admin account. > **Warning:** The generated API key is shown once. Save it before the command ends. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `USERNAME` | arg | string | required | Username for the new admin account. | Example: ```bash rootcoz admin users create release-admin ``` Return value/effect: Creates the account and prints the returned API key. ### `admin users delete` Removes an admin account by username. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `USERNAME` | arg | string | required | Admin username to remove. | | `--force`, `-f` | option | boolean | `false` | Skip the confirmation prompt. | Example: ```bash rootcoz admin users delete release-admin --force ``` Return value/effect: Deletes the named account. Without `--force`, the CLI asks for confirmation first. ### `admin users rotate-key` Rotates an admin user's API key. > **Warning:** The new API key is shown once. Save it before the command ends. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `USERNAME` | arg | string | required | Admin username whose key should be rotated. | Example: ```bash rootcoz admin users rotate-key release-admin ``` Return value/effect: Rotates the key and prints the newly issued API key. ### `admin users change-role` Changes a user's role. > **Warning:** Promoting a user to `admin` can return a new API key. Save it before the command ends. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `USERNAME` | arg | string | required | Username whose role should change. | | `ROLE` | arg | string | required | New role: `admin` or `user`. | Example: ```bash rootcoz admin users change-role alice admin ``` Return value/effect: Updates the user's role and prints the returned role. When the server returns a new admin key, the CLI prints it. ### `admin token-usage` Shows AI token usage and cost data. Mode selection | Trigger | Effect | | --- | --- | | no filters and no `--job-id` | Summary dashboard for `today`, `this_week`, and `this_month`, plus top models | | `--job-id` | Per-call records for one analysis job | | any `--period`, `--start-date`, `--end-date`, `--provider`, `--model`, `--call-type`, or `--group-by` | Aggregated totals, plus a breakdown when grouping is present | > **Note:** `--json` overrides `--format`. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--period` | option | string | unset | Preset date range: `today`, `week`, `month`, or `all`. | | `--start-date` | option | string | unset | Start date in `YYYY-MM-DD` format. | | `--end-date` | option | string | unset | End date in `YYYY-MM-DD` format. | | `--provider` | option | string | unset | Filter by AI provider. | | `--model` | option | string | unset | Filter by AI model. | | `--call-type` | option | string | unset | Filter by call type. | | `--group-by` | option | string | unset | Group by `provider`, `model`, `call_type`, `day`, `week`, `month`, or `job`. | | `--job-id` | option | string | unset | Show per-call usage for one analysis job ID. | | `--format` | option | string | `table` | Output format: `table`, `json`, or `csv`. | Example: ```bash rootcoz admin token-usage --group-by provider --format csv ``` Return value/effect: In text mode, prints either a dashboard summary, aggregated totals, or per-job call records. CSV mode prints CSV rows. JSON mode prints the raw response object. ## Metadata Commands ### `metadata list` Lists stored job metadata. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `--team` | option | string | empty | Filter by team. | | `--tier` | option | string | empty | Filter by tier. | | `--version` | option | string | empty | Filter by version. | | `--label`, `-l` | option | string[] | empty | Repeatable label filter. | Example: ```bash rootcoz metadata list --team platform --label nightly ``` Return value/effect: Prints a table with `job_name`, `team`, `tier`, `version`, and `labels`. ### `metadata get` Shows metadata for one job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_NAME` | arg | string | required | Job name to fetch. | Example: ```bash rootcoz metadata get ocp-e2e-aws ``` Return value/effect: Prints one row with `job_name`, `team`, `tier`, `version`, and `labels`. ### `metadata set` Creates or updates metadata for one job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_NAME` | arg | string | required | Job name to update. | | `--team` | option | string | empty | Team value to store. | | `--tier` | option | string | empty | Tier value to store. | | `--version` | option | string | empty | Version value to store. | | `--label`, `-l` | option | string[] | empty | Repeatable labels to store. | Example: ```bash rootcoz metadata set ocp-e2e-aws --team platform --tier critical --label nightly ``` Return value/effect: Updates the job metadata and prints a confirmation line naming the job. ### `metadata delete` Deletes metadata for one job. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_NAME` | arg | string | required | Job name whose metadata should be deleted. | Example: ```bash rootcoz metadata delete ocp-e2e-aws ``` Return value/effect: Deletes the metadata record and prints a confirmation line naming the job. ### `metadata import` Bulk imports job metadata from a local file. > **Warning:** `.yaml` and `.yml` files are parsed as YAML. Any other extension is parsed as JSON. The file must contain an array of metadata objects. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `FILE_PATH` | arg | string | required | Path to a JSON or YAML file containing metadata items. | Example: ```bash rootcoz metadata import ./metadata.yaml ``` Return value/effect: Reads the local file, uploads the parsed items, and prints the number of updated metadata entries. ### `metadata rules` Lists configured metadata auto-assignment rules. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz metadata rules ``` Return value/effect: Prints the rules file path when present, then each rule's pattern and assigned fields. If no rules are configured, it prints an empty-state message. ### `metadata preview` Shows what metadata rules would assign to one job name. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `JOB_NAME` | arg | string | required | Job name to test against the configured rules. | Example: ```bash rootcoz metadata preview test-smoke ``` Return value/effect: Prints the matched metadata fields for that job name, or an empty-state message when no rule matches. ## Configuration Commands > **Note:** `rootcoz config` runs `rootcoz config show` when no subcommand is given. > > **Note:** Configuration commands do not require a server connection. > > **Tip:** See [Configuration Reference](configuration-reference.html) for field-by-field config details. ### `config show` Shows the current config file summary. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz config show ``` Return value/effect: Prints the config file path, default server name, and configured servers. If no config file exists, it prints the expected path and a starter file snippet. ### `config completion` Prints shell-completion setup instructions. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | `SHELL` | arg | `bash` \| `zsh` | `zsh` | Target shell. | Example: ```bash rootcoz config completion bash ``` Return value/effect: Prints the shell RC snippet that calls `rootcoz --show-completion SHELL`. Unsupported shell names exit with an error. ### `config servers` Lists configured server profiles. | Name | Kind | Type | Default | Description | | --- | --- | --- | --- | --- | | none | — | — | — | No command-specific parameters. | Example: ```bash rootcoz config servers ``` Return value/effect: Prints a table with `name`, `url`, `username`, `no_verify_ssl`, and a default-server marker. JSON mode returns an object keyed by server name. ## Related Pages - [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) - [Configuration Reference](configuration-reference.html) - [API Endpoint Reference](api-endpoint-reference.html) - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Reviewing and Classifying Failures](reviewing-and-classifying-failures.html) --- Source: api-endpoint-reference.md # API Endpoint Reference > **Note:** Response `result_url` values are relative unless the server sets `PUBLIC_BASE_URL`. > **Tip:** Examples that use `-b cookies.txt -c cookies.txt` assume you already stored cookies from `POST /api/auth/login`. > **Note:** Mutating endpoints can return `403` when the current requester is blocked by the server allow list. ## Analysis ### Shared analysis body fields Shared JSON fields accepted by analysis endpoints. `POST /analyze` adds Jenkins-specific fields. `POST /analyze-failures` adds direct-failure fields. `POST /re-analyze/{job_id}` accepts only these shared fields. **Parameters** | Name | Type | Default | Description | | --- | --- | --- | --- | | `tests_repo_url` | `string \| null` | `null` | Tests repository URL. A `:ref` suffix selects a branch or tag. | | `tests_repo_token` | `string \| null` | `null` | Token for cloning a private tests repository. | | `ai_provider` | `string \| null` | `null` | AI provider override. Allowed values: `claude`, `gemini`, `cursor`. | | `ai_model` | `string \| null` | `null` | AI model override. | | `enable_jira` | `boolean \| null` | `null` | Enables or disables Jira duplicate matching for this request. | | `ai_cli_timeout` | `integer \| null` | `null` | AI CLI timeout in minutes. | | `max_concurrent_ai_calls` | `integer \| null` | `null` | Maximum concurrent AI CLI calls. | | `jira_url` | `string \| null` | `null` | Jira base URL override. | | `jira_email` | `string \| null` | `null` | Jira Cloud email override. | | `jira_api_token` | `string \| null` | `null` | Jira Cloud API token override. | | `jira_pat` | `string \| null` | `null` | Jira Server/Data Center personal access token override. | | `jira_project_key` | `string \| null` | `null` | Jira project key override. | | `jira_ssl_verify` | `boolean \| null` | `null` | Jira SSL verification override. | | `jira_max_results` | `integer \| null` | `null` | Maximum Jira matches to fetch. | | `raw_prompt` | `string \| null` | `null` | Extra AI instructions appended to the request. | | `github_token` | `string \| null` | `null` | GitHub token override used for private-repo lookups and comment enrichment. | | `peer_ai_configs` | `array \| null` | `null` | Peer-analysis model list. Omit to inherit the server default. Send `[]` to disable peer analysis for this request. | | `peer_analysis_max_rounds` | `integer` | `3` | Maximum debate rounds for peer analysis. | | `additional_repos` | `array \| null` | `null` | Extra repositories cloned into the AI workspace. Omit to inherit the server default. Send `[]` to disable. | **`peer_ai_configs[]` fields** | Name | Type | Default | Description | | --- | --- | --- | --- | | `ai_provider` | `string` | `Required` | Peer AI provider. Allowed values: `claude`, `gemini`, `cursor`. | | `ai_model` | `string` | `Required` | Peer AI model identifier. | **`additional_repos[]` fields** | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | `Required` | Repository label and clone directory name. | | `url` | `string` | `Required` | Repository URL to clone. | | `ref` | `string` | `""` | Branch or tag to check out. | | `token` | `string \| null` | `null` | Token for cloning a private repository. | **Example** ```json { "tests_repo_url": "https://github.com/example/tests:main", "ai_provider": "claude", "ai_model": "claude-sonnet-4-20250514", "enable_jira": true, "ai_cli_timeout": 15, "max_concurrent_ai_calls": 4, "peer_ai_configs": [ { "ai_provider": "gemini", "ai_model": "gemini-2.5-pro" } ], "additional_repos": [ { "name": "product", "url": "https://github.com/example/product", "ref": "release-4.18" } ] } ``` **Return value/effect** Supplies per-request analysis overrides. Omitted fields use the server defaults. ### POST /analyze Queues a Jenkins build for analysis and returns a new job ID immediately. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_name` | body | `string` | `Required` | Jenkins job name. Folder-style names such as `folder/job-name` are accepted. | | `build_number` | body | `integer` | `Required` | Jenkins build number to analyze. | | `force` | body | `boolean` | `false` | Analyze even when the Jenkins build result is `SUCCESS`. | | `wait_for_completion` | body | `boolean` | `true` | Wait for the Jenkins build to finish before analysis starts. | | `poll_interval_minutes` | body | `integer` | `2` | Delay between Jenkins status polls while waiting. | | `max_wait_minutes` | body | `integer` | `0` | Maximum wait time in minutes. `0` means no limit. | | `jenkins_url` | body | `string \| null` | `null` | Jenkins base URL override. | | `jenkins_user` | body | `string \| null` | `null` | Jenkins username override. | | `jenkins_password` | body | `string \| null` | `null` | Jenkins password or API token override. | | `jenkins_ssl_verify` | body | `boolean \| null` | `null` | Jenkins SSL verification override. | | `jenkins_timeout` | body | `integer \| null` | `null` | Jenkins API timeout in seconds. | | `jenkins_artifacts_max_size_mb` | body | `integer \| null` | `null` | Maximum artifact download size in MB. | | `get_job_artifacts` | body | `boolean \| null` | `null` | Downloads Jenkins build artifacts for AI context. | | Shared analysis body fields | body | `object` | optional | Also accepts all fields from **Shared analysis body fields** above. | **Return value** Returns `202 Accepted`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `queued`. | | `job_id` | `string` | New analysis job ID. | | `message` | `string` | Polling hint for the queued job. | | `base_url` | `string` | Empty string or the configured public base URL. | | `result_url` | `string` | Relative or absolute URL for `GET /results/{job_id}`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/analyze" \ -H "Content-Type: application/json" \ -d '{ "job_name": "folder/nightly-e2e", "build_number": 4281, "ai_provider": "claude", "ai_model": "claude-sonnet-4-20250514", "tests_repo_url": "https://github.com/example/tests:release-4.18", "wait_for_completion": true, "poll_interval_minutes": 2 }' ``` ### POST /analyze-failures Analyzes raw failure data or raw JUnit XML without Jenkins. > **Warning:** Send exactly one of `failures` or `raw_xml`. Sending both, or neither, returns `422`. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `failures` | body | `array \| null` | `null` | Raw failures to analyze directly. | | `raw_xml` | body | `string \| null` | `null` | Raw JUnit XML. Maximum size: 50 MB. | | Shared analysis body fields | body | `object` | optional | Also accepts all fields from **Shared analysis body fields** above. | **`failures[]` fields** | Name | Type | Default | Description | | --- | --- | --- | --- | | `test_name` | `string` | `Required` | Fully qualified failing test name. | | `error_message` | `string` | `""` | Failure message. | | `stack_trace` | `string` | `""` | Full stack trace. | | `duration` | `number` | `0.0` | Test duration in seconds. | | `status` | `string` | `FAILED` | Source failure status. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `job_id` | `string` | New analysis job ID. | | `status` | `string` | `completed` or `failed`. | | `summary` | `string` | Human-readable analysis summary. | | `ai_provider` | `string` | Effective AI provider. | | `ai_model` | `string` | Effective AI model. | | `failures` | `array` | Structured failure analyses. | | `enriched_xml` | `string \| null` | Enriched JUnit XML. Present only when the request used `raw_xml`. | | `token_usage` | `object \| null` | Aggregated AI token usage totals and per-call records. | | `base_url` | `string` | Empty string or the configured public base URL. | | `result_url` | `string` | Relative or absolute URL for the stored result. | **`failures[]` response fields** | Field | Type | Description | | --- | --- | --- | | `test_name` | `string` | Failed test name. | | `error` | `string` | Error message stored for the analyzed failure. | | `error_signature` | `string` | SHA-256 signature of the error and stack trace. | | `analysis.classification` | `string` | Root cause classification such as `CODE ISSUE`, `PRODUCT BUG`, or `INFRASTRUCTURE`. | | `analysis.affected_tests` | `array` | Other tests grouped with the same finding. | | `analysis.details` | `string` | Main analysis text. | | `analysis.artifacts_evidence` | `string` | Verbatim artifact evidence captured during analysis. | | `analysis.code_fix` | `object \| absent` | Code-fix payload with file, line, change, optional full-file snapshots, search keywords, and matched issues. | | `analysis.product_bug_report` | `object \| absent` | Product-bug payload with title, severity, component, description, evidence, Jira keywords, and Jira matches. | | `peer_debate` | `object \| null` | Peer-analysis consensus trail when peer review is enabled. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/analyze-failures" \ -H "Content-Type: application/json" \ -d '{ "failures": [ { "test_name": "tests.auth.test_login.TestLogin.test_valid_credentials", "error_message": "AssertionError: expected 200, got 500", "stack_trace": "Traceback (most recent call last): ..." } ], "ai_provider": "claude", "ai_model": "claude-sonnet-4-20250514" }' ``` ### POST /re-analyze/{job_id} Queues a new analysis by reconstructing the original stored request and applying fresh overrides. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Existing analysis job ID to resume from. | | body | body | `object` | optional | Accepts the **Shared analysis body fields** above. Jenkins job selection fields are taken from the stored request. | **Return value** Returns `202 Accepted`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `queued`. | | `job_id` | `string` | New analysis job ID. | | `message` | `string` | Polling hint for the queued job. | | `base_url` | `string` | Empty string or the configured public base URL. | | `result_url` | `string` | Relative or absolute URL for the new result. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/re-analyze/old-job-id-123" \ -H "Content-Type: application/json" \ -d '{ "ai_provider": "cursor", "ai_model": "gpt-5.1", "peer_ai_configs": [] }' ``` ## Results > **Note:** `GET /results/{job_id}` returns `202 Accepted` while a queued or running job is still in progress. > **Warning:** Failure-targeted result subresources can return `202` while the job is still pending and `409` if the stored job failed. ### GET /results/{job_id} Returns the stored result wrapper for an analysis job. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | **Return value** Returns `200 OK` for completed or failed jobs, and `202 Accepted` for in-progress jobs. | Field | Type | Description | | --- | --- | --- | | `job_id` | `string` | Analysis job ID. | | `jenkins_url` | `string` | Stored Jenkins build URL. | | `status` | `string` | Job status: `pending`, `waiting`, `running`, `completed`, or `failed`. | | `result` | `object \| null` | Stored analysis payload. Partial while the job is still running. | | `created_at` | `string` | Creation timestamp. | | `analysis_started_at` | `string \| null` | Timestamp when analysis execution started. | | `completed_at` | `string \| null` | Completion timestamp. | | `capabilities` | `object` | Server feature flags attached to the response. | | `base_url` | `string` | Empty string or the configured public base URL. | | `result_url` | `string` | Relative or absolute URL for this result. | **Common fields inside `result`** | Field | Type | Description | | --- | --- | --- | | `job_name` | `string` | Jenkins job name when the result came from `POST /analyze`. | | `build_number` | `integer` | Jenkins build number when the result came from `POST /analyze`. | | `status` | `string` | Stored result status when the completed payload includes it. | | `summary` | `string` | Human-readable summary. | | `ai_provider` | `string` | Effective AI provider. | | `ai_model` | `string` | Effective AI model. | | `failures` | `array` | Failure analyses using the same structure returned by `POST /analyze-failures`. | | `child_job_analyses` | `array` | Recursive child-job analyses with `job_name`, `build_number`, `failures`, `failed_children`, and optional `note`. | | `token_usage` | `object \| null` | Aggregated AI token usage totals and per-call records. | | `request_params` | `object` | Saved request parameters with sensitive credential fields stripped from the response. | | `progress_phase` | `string` | Current phase while a job is running. | | `progress_log` | `array` | Phase history with `phase` and `timestamp` entries. | | `enriched_xml` | `string \| null` | Enriched JUnit XML for direct XML analysis results. | **`capabilities` fields** | Field | Type | Description | | --- | --- | --- | | `github_issues_enabled` | `boolean` | GitHub issue creation is available. | | `jira_issues_enabled` | `boolean` | Jira issue creation is available. | | `server_github_token` | `boolean` | The server has its own GitHub token configured. | | `server_jira_token` | `boolean` | The server has Jira credentials configured. | | `server_jira_email` | `boolean` | The server has a Jira Cloud email configured. | | `server_jira_project_key` | `string` | Server Jira project key, or `""`. | | `reportportal` | `boolean` | Report Portal integration is available. | | `reportportal_project` | `string` | Configured Report Portal project, or `""`. | | `feedback_enabled` | `boolean` | Feedback preview/create endpoints are available. | **Example** ```bash curl -sS "https://rootcoz.example.com/results/7b5f0f61-0b1d-4d63-8d7a-4b2d6e5a8d7d" ``` ### GET /results Lists recent analysis jobs. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `limit` | query | `integer` | `50` | Maximum results to return. Maximum value: `100`. | **Return value** Returns `200 OK` and a JSON array. | Field | Type | Description | | --- | --- | --- | | `job_id` | `string` | Analysis job ID. | | `jenkins_url` | `string` | Stored Jenkins build URL. | | `status` | `string` | Job status. | | `created_at` | `string` | Creation timestamp. | **Example** ```bash curl -sS "https://rootcoz.example.com/results?limit=10" ``` ### GET /results/{job_id}/review-status Returns a compact review summary for one stored result. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `total_failures` | `integer` | Total failures across the result, including child jobs. | | `reviewed_count` | `integer` | Number of failures marked reviewed. | | `comment_count` | `integer` | Number of comments stored for the job. | Missing jobs return zero counts. **Example** ```bash curl -sS "https://rootcoz.example.com/results/7b5f0f61-0b1d-4d63-8d7a-4b2d6e5a8d7d/review-status" ``` ### PUT /results/{job_id}/override-classification Overrides the stored classification for a failure group. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Representative test name from the failure group. | | `classification` | body | `string` | `Required` | New classification. Allowed values: `CODE ISSUE`, `PRODUCT BUG`, `INFRASTRUCTURE`. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failure overrides. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failure overrides. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `ok` on success. | | `classification` | `string` | Applied classification. | **Example** ```bash curl -sS -X PUT "https://rootcoz.example.com/results/job-123/override-classification" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.auth.test_login.TestLogin.test_valid_credentials", "classification": "PRODUCT BUG" }' ``` ### DELETE /results/{job_id} Deletes one stored result and all related rows. > **Warning:** Admin-only endpoint. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID to delete. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `deleted` on success. | | `job_id` | `string` | Deleted job ID. | **Example** ```bash curl -sS -X DELETE "https://rootcoz.example.com/results/job-123" \ -H "Authorization: Bearer " ``` ### DELETE /api/results/bulk Deletes multiple stored results in one request. > **Warning:** Admin-only endpoint. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_ids` | body | `array` | `Required` | Job IDs to delete. Minimum `1`, maximum `500`. Duplicate IDs are ignored after the first occurrence. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `deleted` | `array` | Job IDs deleted successfully. | | `failed` | `array` | Failed deletions. Each item has `job_id` and `reason`. | | `total` | `integer` | Number of unique requested job IDs processed. | **Example** ```bash curl -sS -X DELETE "https://rootcoz.example.com/api/results/bulk" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "job_ids": ["job-123", "job-456", "job-789"] }' ``` ### GET /results/{job_id}/issue-prompt Fetches the stored issue-generation prompt file from the analyzed tests repository. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `prompt` | `string` | Prompt file contents, or `""` when the job has no tests repository, the file is missing, the job does not exist, or the fetch fails. | **Example** ```bash curl -sS "https://rootcoz.example.com/results/job-123/issue-prompt" ``` ### POST /results/{job_id}/preview-github-issue Generates a GitHub issue preview from one analyzed failure. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Failure to preview. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failure previews. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failure previews. | | `github_token` | body | `string` | `""` | GitHub token used for duplicate searching. Falls back to the server token when available. | | `github_repo_url` | body | `string` | `""` | Overrides the GitHub repository used for duplicate searching. | | `include_links` | body | `boolean` | `false` | Includes report and Jenkins links in generated content when the server can build public URLs. | | `ai_provider` | body | `string` | `""` | AI provider override for preview generation. | | `ai_model` | body | `string` | `""` | AI model override for preview generation. | | `issue_prompt` | body | `string` | `""` | Extra instructions appended to issue generation. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `title` | `string` | Generated issue title. | | `body` | `string` | Generated issue body. | | `similar_issues` | `array` | Duplicate-search results. Items can include `number`, `key`, `title`, `url`, and `status`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/preview-github-issue" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.auth.test_login.TestLogin.test_valid_credentials", "ai_provider": "claude", "ai_model": "claude-sonnet-4-20250514", "include_links": true, "issue_prompt": "Include the affected product version." }' ``` ### POST /results/{job_id}/preview-jira-bug Generates a Jira bug preview from one analyzed failure. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Failure to preview. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failure previews. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failure previews. | | `jira_token` | body | `string` | `""` | Jira token used for duplicate searching. Falls back to the server credentials when available. | | `jira_email` | body | `string` | `""` | Jira Cloud email used with `jira_token`. | | `jira_project_key` | body | `string` | `""` | Jira project key override used for duplicate searching. | | `include_links` | body | `boolean` | `false` | Includes report and Jenkins links in generated content when the server can build public URLs. | | `ai_provider` | body | `string` | `""` | AI provider override for preview generation. | | `ai_model` | body | `string` | `""` | AI model override for preview generation. | | `issue_prompt` | body | `string` | `""` | Extra instructions appended to issue generation. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `title` | `string` | Generated Jira title. | | `body` | `string` | Generated Jira body. | | `similar_issues` | `array` | Duplicate-search results. Items can include `number`, `key`, `title`, `url`, and `status`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/preview-jira-bug" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.network.TestDNS.test_lookup", "jira_project_key": "OCPBUGS", "ai_provider": "claude", "ai_model": "claude-sonnet-4-20250514", "issue_prompt": "Include the cluster version and component." }' ``` ### POST /results/{job_id}/create-github-issue Creates a GitHub issue from one analyzed failure and stores a tracker comment on success. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Failure to create the issue for. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failures. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failures. | | `github_token` | body | `string` | `""` | Personal GitHub token. Falls back to the server token when available. | | `github_repo_url` | body | `string` | `""` | Overrides the GitHub repository used for issue creation. | | `title` | body | `string` | `Required` | Issue title. | | `body` | body | `string` | `Required` | Issue body. | **Return value** Returns `201 Created`. | Field | Type | Description | | --- | --- | --- | | `url` | `string` | URL of the created GitHub issue. | | `number` | `integer` | GitHub issue number. | | `key` | `string` | Always `""` for GitHub issues. | | `title` | `string` | Created issue title. | | `comment_id` | `integer` | ID of the auto-created comment linking the issue back to the result. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/create-github-issue" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.auth.test_login.TestLogin.test_valid_credentials", "github_token": "", "title": "Login test fails with HTTP 500", "body": "## Summary\n\nThe login endpoint returns HTTP 500 in nightly CI." }' ``` ### POST /results/{job_id}/create-jira-bug Creates a Jira issue from one analyzed failure and stores a tracker comment on success. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Failure to create the bug for. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failures. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failures. | | `jira_token` | body | `string` | `""` | Jira token. Falls back to the server credentials when available. | | `jira_email` | body | `string` | `""` | Jira Cloud email used with `jira_token`. | | `jira_project_key` | body | `string` | `""` | Jira project key override. | | `jira_security_level` | body | `string` | `""` | Jira security level name. | | `title` | body | `string` | `Required` | Jira issue title. | | `body` | body | `string` | `Required` | Jira issue body. | | `jira_issue_type` | body | `string` | `Bug` | Jira issue type name. | **Return value** Returns `201 Created`. | Field | Type | Description | | --- | --- | --- | | `url` | `string` | URL of the created Jira issue. | | `key` | `string` | Jira issue key. | | `title` | `string` | Created issue title. | | `comment_id` | `integer` | ID of the auto-created comment linking the issue back to the result. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/create-jira-bug" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.network.TestDNS.test_lookup", "jira_token": "", "jira_email": "user@example.com", "jira_project_key": "OCPBUGS", "jira_security_level": "Internal", "jira_issue_type": "Bug", "title": "DNS lookup fails in nightly CI", "body": "h2. Summary\n\nDNS resolution fails during the network suite." }' ``` ### POST /results/{job_id}/push-reportportal Pushes stored classifications into Report Portal. > **Warning:** Requires Report Portal server settings and `PUBLIC_BASE_URL`. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `child_job_name` | query | `string \| null` | `null` | Child job name for a pipeline child push. | | `child_build_number` | query | `integer \| null` | `null` | Child build number for a pipeline child push. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `pushed` | `integer` | Number of Report Portal items updated successfully. | | `unmatched` | `array` | Report Portal items that could not be matched or classified. | | `errors` | `array` | Push-time errors. | | `launch_id` | `integer \| null` | Matched Report Portal launch ID. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/push-reportportal" ``` ## Comments and Review ### GET /results/{job_id}/comments Returns all comments and review states for one job. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `comments` | `array` | Stored comments for the job. | | `reviews` | `object` | Review map keyed by test name for top-level failures, or `child_job_name#child_build_number::test_name` for child jobs. | **`comments[]` fields** | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | Comment ID. | | `job_id` | `string` | Analysis job ID. | | `test_name` | `string` | Failure name. | | `child_job_name` | `string` | Child job name, or `""`. | | `child_build_number` | `integer` | Child build number, or `0`. | | `comment` | `string` | Comment text. | | `error_signature` | `string` | Stored error signature for the failure group. | | `username` | `string` | Comment author. | | `created_at` | `string` | Creation timestamp. | **`reviews` entry fields** | Field | Type | Description | | --- | --- | --- | | `reviewed` | `boolean` | Current review state. | | `username` | `string` | User who last changed the review state. | | `updated_at` | `string` | Last update timestamp. | Missing jobs return empty collections. **Example** ```bash curl -sS "https://rootcoz.example.com/results/job-123/comments" ``` ### POST /results/{job_id}/comments Adds a comment to one stored failure. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Failure to comment on. | | `comment` | body | `string` | `Required` | Comment text. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failures. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failures. | **Return value** Returns `201 Created`. | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | New comment ID. | If the comment contains `@mentions` and Web Push is configured, the server also attempts mention notifications. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/comments" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.auth.test_login.TestLogin.test_valid_credentials", "comment": "Filed a bug and linked the failing logs." }' ``` ### DELETE /results/{job_id}/comments/{comment_id} Deletes one stored comment. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `comment_id` | path | `integer` | `Required` | Comment ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `deleted` on success. | Admin users can delete any comment. Non-admin deletion is owner-scoped. **Example** ```bash curl -sS -X DELETE "https://rootcoz.example.com/results/job-123/comments/17" \ -b cookies.txt -c cookies.txt ``` ### PUT /results/{job_id}/reviewed Marks or unmarks a failure as reviewed. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | | `test_name` | body | `string` | `Required` | Failure to update. | | `reviewed` | body | `boolean` | `Required` | New review state. | | `child_job_name` | body | `string` | `""` | Child job name for pipeline failures. | | `child_build_number` | body | `integer` | `0` | Child build number for pipeline failures. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `ok` on success. | | `reviewed_by` | `string` | Username recorded for this change, or `""`. | **Example** ```bash curl -sS -X PUT "https://rootcoz.example.com/results/job-123/reviewed" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.auth.test_login.TestLogin.test_valid_credentials", "reviewed": true }' ``` ### POST /results/{job_id}/enrich-comments Scans stored comments for GitHub and Jira references and returns their current statuses. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `enrichments` | `object` | Map keyed by comment ID string. Each value is an array of enrichment records. | **Enrichment record fields** | Field | Type | Description | | --- | --- | --- | | `type` | `string` | One of `github_pr`, `github_issue`, or `jira`. | | `key` | `string` | Tracker identifier such as `owner/repo#123` or `OCPBUGS-12345`. | | `status` | `string` | Current tracker status. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/results/job-123/enrich-comments" ``` ### POST /api/analyze-comment-intent Uses AI to decide whether a comment suggests that a failure has already been reviewed or resolved. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `comment` | body | `string` | `Required` | Comment text to analyze. | | `job_id` | body | `string` | `""` | Optional job ID used to recover the original AI provider/model when the request body omits them. | | `ai_provider` | body | `string \| null` | `null` | AI provider override. | | `ai_model` | body | `string \| null` | `null` | AI model override. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `suggests_reviewed` | `boolean` | `true` when the comment implies reviewed or resolved status. | | `reason` | `string` | Short explanation from the AI, or `""`. | If the AI call fails or returns invalid JSON, the endpoint returns `suggests_reviewed: false`. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/analyze-comment-intent" \ -H "Content-Type: application/json" \ -d '{ "comment": "Filed OCPBUGS-12345 for this failure.", "job_id": "job-123" }' ``` ## History > **Note:** `GET /history/test/{test_name}` and `GET /history/stats/{job_name}` return `200 OK` with zeroed values when no matching history exists. ### GET /history/failures Returns paginated failure history across analyzed jobs. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `search` | query | `string` | `""` | Free-text search across test name, error message, and job name. | | `job_name` | query | `string` | `""` | Exact job-name filter. | | `classification` | query | `string` | `""` | Exact classification filter. | | `limit` | query | `integer` | `50` | Maximum rows to return. Maximum value: `200`. | | `offset` | query | `integer` | `0` | Pagination offset. Minimum value: `0`. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `failures` | `array` | Matching failure-history rows. | | `total` | `integer` | Total matching row count before pagination. | **`failures[]` fields** | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | Failure-history row ID. | | `job_id` | `string` | Analysis job ID. | | `job_name` | `string` | Jenkins job name. | | `build_number` | `integer` | Jenkins build number. | | `test_name` | `string` | Failed test name. | | `error_message` | `string` | Stored failure message. | | `error_signature` | `string` | Error signature hash. | | `classification` | `string` | Stored classification value. | | `child_job_name` | `string` | Child job name, or `""`. | | `child_build_number` | `integer` | Child build number, or `0`. | | `analyzed_at` | `string` | Analysis timestamp. | **Example** ```bash curl -sS "https://rootcoz.example.com/history/failures?job_name=nightly-e2e&classification=PRODUCT%20BUG&limit=25&offset=0" ``` ### GET /history/test/{test_name:path} Returns historical data for one test. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `test_name` | path | `string` | `Required` | Test name to inspect. | | `limit` | query | `integer` | `20` | Maximum recent failure rows to return. Maximum value: `100`. | | `job_name` | query | `string` | `""` | Exact job-name filter. | | `exclude_job_id` | query | `string` | `""` | Excludes one analysis job from the response. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `test_name` | `string` | Requested test name. | | `total_runs` | `integer` | Total analyzed runs used for the result. | | `failures` | `integer` | Recorded failure count. | | `passes` | `integer \| null` | Estimated pass count. `null` when the endpoint cannot infer pass totals. | | `failure_rate` | `number \| null` | Failure rate. `null` when the endpoint cannot infer pass totals. | | `first_seen` | `string \| null` | Oldest recorded failure timestamp. | | `last_seen` | `string \| null` | Most recent recorded failure timestamp. | | `last_classification` | `string` | Most recent classification seen for the test. | | `classifications` | `object` | Classification histogram keyed by classification name. | | `recent_runs` | `array` | Recent failure rows for the test. | | `comments` | `array` | Related historical comments for the test or matching signature. | | `consecutive_failures` | `integer` | Consecutive recorded failure rows. | | `note` | `string` | Availability note for the calculated pass/fail fields. | **Example** ```bash curl -sS "https://rootcoz.example.com/history/test/tests.network.TestDNS.test_lookup?job_name=ocp-4.18-nightly&limit=10" ``` ### GET /history/search Finds tests that failed with the same error signature. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `signature` | query | `string` | `Required` | Error signature hash to search for. | | `exclude_job_id` | query | `string` | `""` | Excludes one analysis job from the response. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `signature` | `string` | Requested error signature. | | `total_occurrences` | `integer` | Matching failure-history rows. | | `unique_tests` | `integer` | Number of distinct test names that share the signature. | | `tests` | `array` | Distinct tests with occurrence counts. | | `last_classification` | `string` | Most recent classification recorded for this signature. | | `comments` | `array` | Historical comments tied to the same signature. | **`tests[]` fields** | Field | Type | Description | | --- | --- | --- | | `test_name` | `string` | Matching test name. | | `occurrences` | `integer` | Failure count for this signature. | **Example** ```bash curl -sS "https://rootcoz.example.com/history/search?signature=7d8e0d1c..." ``` ### GET /history/stats/{job_name:path} Returns aggregate statistics for one Jenkins job. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_name` | path | `string` | `Required` | Job name. Folder-style names are accepted. | | `exclude_job_id` | query | `string` | `""` | Excludes one analysis job from the response. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `job_name` | `string` | Requested job name. | | `total_builds_analyzed` | `integer` | Completed analyzed builds used for the calculation. | | `builds_with_failures` | `integer` | Distinct analyzed builds that recorded failures. | | `overall_failure_rate` | `number` | `builds_with_failures / total_builds_analyzed`. | | `most_common_failures` | `array` | Top failures grouped by test name and classification. | | `recent_trend` | `string` | One of `stable`, `improving`, or `worsening`. | **`most_common_failures[]` fields** | Field | Type | Description | | --- | --- | --- | | `test_name` | `string` | Failing test name. | | `count` | `integer` | Number of matching failure rows. | | `classification` | `string` | Stored classification value for that grouped row. | **Example** ```bash curl -sS "https://rootcoz.example.com/history/stats/folder/nightly-e2e" ``` ### POST /history/classify Creates a history classification record for one test. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `test_name` | body | `string` | `Required` | Test name to classify. | | `classification` | body | `string` | `Required` | History classification. Allowed values: `FLAKY`, `REGRESSION`, `INFRASTRUCTURE`, `KNOWN_BUG`, `INTERMITTENT`. Matching is case-insensitive. | | `reason` | body | `string` | `""` | Short explanation. | | `job_name` | body | `string` | `""` | Job name context stored with the classification. | | `references` | body | `string` | `""` | External references or tracking links. Required when `classification` is `KNOWN_BUG`. | | `job_id` | body | `string` | `Required` | Analysis job ID. | | `child_build_number` | body | `integer` | `0` | Child build number for child-job classifications. | **Return value** Returns `201 Created`. | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | New classification row ID. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/history/classify" \ -H "Content-Type: application/json" \ -d '{ "test_name": "tests.network.TestDNS.test_lookup", "classification": "KNOWN_BUG", "references": "OCPBUGS-12345", "job_id": "job-123" }' ``` ### GET /history/classifications Returns stored classification records. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `test_name` | query | `string` | `""` | Exact test-name filter. | | `classification` | query | `string` | `""` | Exact classification filter. | | `job_name` | query | `string` | `""` | Exact job-name filter. | | `parent_job_name` | query | `string` | `""` | Exact parent-job filter. | | `job_id` | query | `string` | `""` | Exact analysis job ID filter. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `classifications` | `array` | Matching classification rows. | **`classifications[]` fields** | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | Classification row ID. | | `test_name` | `string` | Test name. | | `job_name` | `string` | Job name stored with the record. | | `parent_job_name` | `string` | Parent pipeline job name. | | `classification` | `string` | Stored classification value. | | `reason` | `string` | Free-form reason. | | `references_info` | `string` | Stored references string. | | `created_by` | `string` | Creator username or AI marker. | | `job_id` | `string` | Analysis job ID. | | `child_build_number` | `integer` | Child build number. | | `created_at` | `string` | Creation timestamp. | **Example** ```bash curl -sS "https://rootcoz.example.com/history/classifications?test_name=tests.network.TestDNS.test_lookup&job_id=job-123" ``` ## Auth > **Note:** Admin-only endpoints accept either an authenticated admin session or `Authorization: Bearer `. > **Note:** `GET /api/auth/me` always returns `200 OK`, even when no user is resolved. ### POST /api/auth/login Authenticates a username/API-key pair and creates a session. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `username` | body | `string` | `Required` | Username to authenticate. | | `api_key` | body | `string` | `Required` | Bootstrap admin key or a stored user API key. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `username` | `string` | Authenticated username. | | `role` | `string` | `admin` or `user`. | | `is_admin` | `boolean` | Admin flag. | The response also sets session cookies. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/auth/login" \ -H "Content-Type: application/json" \ -c cookies.txt \ -d '{ "username": "admin", "api_key": "" }' ``` ### POST /api/auth/logout Clears the active session. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `ok` | `boolean` | Always `true`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/auth/logout" \ -b cookies.txt -c cookies.txt ``` ### GET /api/auth/me Returns the user resolved by the server auth middleware. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `username` | `string` | Resolved username, or `""`. | | `role` | `string` | `admin` or `user`. | | `is_admin` | `boolean` | Admin flag. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/auth/me" \ -H "Authorization: Bearer " ``` ### GET /api/user/tokens Returns the saved GitHub and Jira credentials for the current user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `github_token` | `string` | Saved GitHub token, or `""`. | | `jira_email` | `string` | Saved Jira Cloud email, or `""`. | | `jira_token` | `string` | Saved Jira token, or `""`. | Returns `401` when no current user is available. Returns empty strings when the resolved username has no stored user record. **Example** ```bash curl -sS "https://rootcoz.example.com/api/user/tokens" \ -b cookies.txt -c cookies.txt ``` ### PUT /api/user/tokens Updates the current user's saved tracker credentials. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `github_token` | body | `string` | `""` | GitHub token update. | | `jira_email` | body | `string` | `""` | Jira Cloud email update. | | `jira_token` | body | `string` | `""` | Jira token update. | Only nonblank fields in the request body are applied. Omitted or blank fields leave existing stored values unchanged. **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `ok` | `boolean` | Always `true` on success. | Returns `401` when no current user is available. Returns `404` when the resolved username does not have a stored user record. **Example** ```bash curl -sS -X PUT "https://rootcoz.example.com/api/user/tokens" \ -H "Content-Type: application/json" \ -b cookies.txt -c cookies.txt \ -d '{ "github_token": "", "jira_email": "user@example.com", "jira_token": "" }' ``` ### POST /api/validate-token Validates a GitHub or Jira token with a live API call. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `token_type` | body | `string` | `Required` | Token type. Allowed values: `github`, `jira`. | | `token` | body | `string` | `Required` | Token value to validate. | | `email` | body | `string` | `""` | Jira Cloud email used with Jira token validation. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `valid` | `boolean` | Validation result. | | `username` | `string` | Authenticated GitHub login or Jira display name, or `""`. | | `message` | `string` | Short validation message. | Blank tokens return `valid: false` instead of an HTTP error. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/validate-token" \ -H "Content-Type: application/json" \ -d '{ "token_type": "github", "token": "" }' ``` ### POST /api/jira-projects Lists Jira projects available to the supplied Jira credentials. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `jira_token` | body | `string` | `""` | Jira token used for the lookup. | | `jira_email` | body | `string` | `""` | Jira Cloud email used with `jira_token`. | | `query` | body | `string` | `""` | Project-name search filter. | **Return value** Returns `200 OK` and a JSON array. | Field | Type | Description | | --- | --- | --- | | `key` | `string` | Jira project key. | | `name` | `string` | Jira project name. | If the caller does not provide a usable Jira token, the endpoint returns the server project key when one is configured, or an empty array otherwise. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/jira-projects" \ -H "Content-Type: application/json" \ -d '{ "jira_token": "", "jira_email": "user@example.com", "query": "CNV" }' ``` ### POST /api/jira-security-levels Lists Jira security levels for one project. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `jira_token` | body | `string` | `""` | Jira token used for the lookup. | | `jira_email` | body | `string` | `""` | Jira Cloud email used with `jira_token`. | | `project_key` | body | `string` | `Required` | Jira project key. | **Return value** Returns `200 OK` and a JSON array. | Field | Type | Description | | --- | --- | --- | | `id` | `string` | Jira security level ID. | | `name` | `string` | Jira security level name. | | `description` | `string` | Jira security level description. | The endpoint returns an empty array when the server has no Jira URL, the request omits `project_key`, or the Jira credentials are unusable. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/jira-security-levels" \ -H "Content-Type: application/json" \ -d '{ "jira_token": "", "jira_email": "user@example.com", "project_key": "OCPBUGS" }' ``` ## Admin > **Warning:** Every endpoint in this section is admin-only. ### GET /api/admin/users Lists tracked users. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `users` | `array` | Tracked user rows. | **`users[]` fields** | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | User row ID. | | `username` | `string` | Username. | | `role` | `string` | `admin` or `user`. | | `created_at` | `string` | Creation timestamp. | | `last_seen` | `string \| null` | Most recent activity timestamp. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/admin/users" \ -H "Authorization: Bearer " ``` ### POST /api/admin/users Creates a new admin user and returns a fresh API key. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `username` | body | `string` | `Required` | Username to create. Must be 2-50 characters, start with an alphanumeric character, and use only letters, digits, `.`, `_`, or `-`. The reserved username `admin` is rejected. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `username` | `string` | Created username. | | `api_key` | `string` | Newly generated API key. Returned once. | | `role` | `string` | Always `admin`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/admin/users" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "username": "release-admin" }' ``` ### DELETE /api/admin/users/{username} Deletes one admin user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `username` | path | `string` | `Required` | Admin username to delete. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `deleted` | `string` | Deleted username. | The endpoint rejects self-deletion and deleting the last remaining admin. **Example** ```bash curl -sS -X DELETE "https://rootcoz.example.com/api/admin/users/release-admin" \ -H "Authorization: Bearer " ``` ### PUT /api/admin/users/{username}/role Changes a user's role. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `username` | path | `string` | `Required` | Username to update. | | `role` | body | `string` | `Required` | New role. Allowed values: `admin`, `user`. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `username` | `string` | Updated username. | | `role` | `string` | New role. | | `api_key` | `string` | Newly generated API key. Present only when promoting a user to `admin`. | Demotion clears the old API key and invalidates that user's sessions. **Example** ```bash curl -sS -X PUT "https://rootcoz.example.com/api/admin/users/alice/role" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "role": "admin" }' ``` ### POST /api/admin/users/{username}/rotate-key Rotates an admin user's API key. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `username` | path | `string` | `Required` | Admin username. | | `new_key` | body | `string \| null` | `null` | Optional custom API key. Minimum length: `16`. When omitted, the server generates a new key. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `username` | `string` | Target admin username. | | `new_api_key` | `string` | Fresh API key. Returned once. | Key rotation invalidates existing sessions for that user. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/admin/users/release-admin/rotate-key" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{}' ``` ### GET /api/admin/token-usage Returns aggregated AI token usage. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `start_date` | query | `string \| null` | `null` | Inclusive start date or timestamp filter. | | `end_date` | query | `string \| null` | `null` | Inclusive end date or timestamp filter. Date-only values include the full day. | | `ai_provider` | query | `string \| null` | `null` | AI provider filter. | | `ai_model` | query | `string \| null` | `null` | AI model filter. | | `call_type` | query | `string \| null` | `null` | Call-type filter. | | `group_by` | query | `string \| null` | `null` | Breakdown dimension. Allowed values: `provider`, `model`, `call_type`, `day`, `week`, `month`, `job`. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `total_input_tokens` | `integer` | Summed input tokens. | | `total_output_tokens` | `integer` | Summed output tokens. | | `total_cache_read_tokens` | `integer` | Summed cache-read tokens. | | `total_cache_write_tokens` | `integer` | Summed cache-write tokens. | | `total_cost_usd` | `number` | Summed cost in USD. | | `total_calls` | `integer` | Matching AI call count. | | `total_duration_ms` | `integer` | Summed duration in milliseconds. | | `breakdown` | `array` | Optional grouped breakdown. Empty when `group_by` is omitted. | **`breakdown[]` fields** | Field | Type | Description | | --- | --- | --- | | `group_key` | `string` | Group label produced by `group_by`. | | `input_tokens` | `integer` | Summed input tokens for the group. | | `output_tokens` | `integer` | Summed output tokens for the group. | | `cache_read_tokens` | `integer` | Summed cache-read tokens for the group. | | `cache_write_tokens` | `integer` | Summed cache-write tokens for the group. | | `cost_usd` | `number` | Summed cost for the group. | | `call_count` | `integer` | AI call count for the group. | | `avg_duration_ms` | `integer` | Average duration in milliseconds for calls with recorded durations. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/admin/token-usage?start_date=2026-05-01&end_date=2026-05-31&group_by=provider" \ -H "Authorization: Bearer " ``` ### GET /api/admin/token-usage/summary Returns rolling token-usage summary cards. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `today` | `object` | Rolling summary for records created today. | | `this_week` | `object` | Rolling summary for the last 7 days. | | `this_month` | `object` | Rolling summary for the last 30 days. | | `top_models` | `array` | Highest-cost models over the last 30 days. | | `top_jobs` | `array` | Highest-cost jobs over the last 30 days. | **Period summary fields** | Field | Type | Description | | --- | --- | --- | | `calls` | `integer` | Matching AI call count. | | `tokens` | `integer` | Total tokens. | | `input_tokens` | `integer` | Input tokens. | | `output_tokens` | `integer` | Output tokens. | | `cost_usd` | `number` | Cost in USD. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/admin/token-usage/summary" \ -H "Authorization: Bearer " ``` ### GET /api/admin/token-usage/{job_id} Returns raw token-usage records for one analysis job. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_id` | path | `string` | `Required` | Analysis job ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `job_id` | `string` | Requested job ID. | | `records` | `array` | Raw token-usage records for the job. | **`records[]` fields** | Field | Type | Description | | --- | --- | --- | | `id` | `string` | Token-usage record ID. | | `job_id` | `string` | Analysis job ID. | | `ai_provider` | `string` | AI provider. | | `ai_model` | `string` | AI model. | | `call_type` | `string` | Recorded call type. | | `input_tokens` | `integer` | Input tokens. | | `output_tokens` | `integer` | Output tokens. | | `cache_read_tokens` | `integer` | Cache-read tokens. | | `cache_write_tokens` | `integer` | Cache-write tokens. | | `total_tokens` | `integer` | Input plus output tokens. | | `cost_usd` | `number \| null` | Estimated cost in USD. | | `duration_ms` | `integer \| null` | Call duration in milliseconds. | | `prompt_chars` | `integer` | Prompt character count. | | `response_chars` | `integer` | Response character count. | | `created_at` | `string` | Record timestamp. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/admin/token-usage/job-123" \ -H "Authorization: Bearer " ``` ## Metadata > **Tip:** Repeat the `label` query parameter to require multiple labels, for example `?label=nightly&label=smoke`. > **Note:** Metadata read endpoints are open. Metadata mutation endpoints are admin-only. ### GET /api/jobs/metadata Lists stored job metadata. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `team` | query | `string` | `""` | Exact team filter. | | `tier` | query | `string` | `""` | Exact tier filter. | | `version` | query | `string` | `""` | Exact version filter. | | `label` | query | `array` | `[]` | Repeated label filter. All requested labels must be present. | **Return value** Returns `200 OK` and a JSON array. | Field | Type | Description | | --- | --- | --- | | `job_name` | `string` | Jenkins job name. | | `team` | `string \| null` | Team owner. | | `tier` | `string \| null` | Service tier. | | `version` | `string \| null` | Version or release label. | | `labels` | `array` | Arbitrary labels. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/jobs/metadata?team=platform&label=nightly&label=smoke" ``` ### GET /api/jobs/{job_name:path}/metadata Returns metadata for one job. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_name` | path | `string` | `Required` | Jenkins job name. Folder-style names are accepted. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `job_name` | `string` | Jenkins job name. | | `team` | `string \| null` | Team owner. | | `tier` | `string \| null` | Service tier. | | `version` | `string \| null` | Version or release label. | | `labels` | `array` | Arbitrary labels. | Returns `404` when the job has no stored metadata. **Example** ```bash curl -sS "https://rootcoz.example.com/api/jobs/folder/subfolder/my-job/metadata" ``` ### PUT /api/jobs/{job_name:path}/metadata Creates or updates metadata for one job. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_name` | path | `string` | `Required` | Jenkins job name. Folder-style names are accepted. | | `team` | body | `string \| null` | `null` | Team owner. | | `tier` | body | `string \| null` | `null` | Service tier. | | `version` | body | `string \| null` | `null` | Version or release label. | | `labels` | body | `array` | `[]` | Arbitrary labels. | Omitted fields preserve their current stored values. Sending `null` for a scalar clears that field. Sending `[]` clears labels. **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `job_name` | `string` | Jenkins job name. | | `team` | `string \| null` | Stored team owner. | | `tier` | `string \| null` | Stored service tier. | | `version` | `string \| null` | Stored version label. | | `labels` | `array` | Stored labels. | **Example** ```bash curl -sS -X PUT "https://rootcoz.example.com/api/jobs/folder/subfolder/my-job/metadata" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "team": "platform", "tier": "critical", "labels": ["nightly", "smoke"] }' ``` ### DELETE /api/jobs/{job_name:path}/metadata Deletes one job's metadata. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_name` | path | `string` | `Required` | Jenkins job name. Folder-style names are accepted. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `deleted` on success. | | `job_name` | `string` | Deleted job name. | **Example** ```bash curl -sS -X DELETE "https://rootcoz.example.com/api/jobs/folder/subfolder/my-job/metadata" \ -H "Authorization: Bearer " ``` ### PUT /api/jobs/metadata/bulk Bulk-imports job metadata. > **Warning:** Bulk import replaces each submitted item completely. Omitted optional fields become `null` or `[]`. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `items` | body | `array` | `Required` | Metadata rows to import. Minimum `1`, maximum `1000`. | **`items[]` fields** | Name | Type | Default | Description | | --- | --- | --- | --- | | `job_name` | `string` | `Required` | Jenkins job name. | | `team` | `string \| null` | `null` | Team owner. | | `tier` | `string \| null` | `null` | Service tier. | | `version` | `string \| null` | `null` | Version or release label. | | `labels` | `array` | `[]` | Arbitrary labels. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `updated` | `integer` | Number of imported metadata rows. | **Example** ```bash curl -sS -X PUT "https://rootcoz.example.com/api/jobs/metadata/bulk" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "items": [ { "job_name": "job-a", "team": "platform", "labels": ["nightly"] }, { "job_name": "job-b", "team": "storage", "tier": "critical", "labels": ["regression"] } ] }' ``` ### GET /api/jobs/metadata/rules Returns the currently loaded metadata rules. > **Note:** When rules are evaluated, the first matching rule wins for `team`, `tier`, and `version`. `labels` accumulate across all matching rules. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `rules_file` | `string \| null` | Basename of the configured rules file, or `null`. | | `rules` | `array` | Loaded rule objects. | **`rules[]` fields** | Field | Type | Description | | --- | --- | --- | | `pattern` | `string` | Glob pattern or full regex with named groups. | | `team` | `string \| absent` | Team value assigned by the rule. | | `tier` | `string \| absent` | Tier value assigned by the rule. | | `version` | `string \| absent` | Version value assigned by the rule. | | `labels` | `array \| absent` | Labels assigned by the rule. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/jobs/metadata/rules" ``` ### POST /api/jobs/metadata/rules/preview Returns the metadata that the current rules would assign to one job name. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `job_name` | body | `string` | `Required` | Jenkins job name to test against the loaded rules. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `job_name` | `string` | Echoed job name. | | `matched` | `boolean` | `true` when at least one rule matched. | | `metadata` | `object \| null` | Previewed metadata object, or `null`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/jobs/metadata/rules/preview" \ -H "Content-Type: application/json" \ -d '{ "job_name": "test-pytest-cnv-4.18-storage-nfs" }' ``` ## Notifications and Mentions > **Warning:** Web Push endpoints return `404` when push notifications are not configured and `503` when push is enabled but the VAPID keys are unavailable. ### GET /api/notifications/vapid-public-key Returns the public VAPID key used by the browser push subscription flow. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `vapid_public_key` | `string` | Browser-visible VAPID public key. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/notifications/vapid-public-key" ``` ### POST /api/notifications/subscribe Registers a Web Push subscription for the current user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `endpoint` | body | `string` | `Required` | Push-service endpoint URL. Must use `https://`. Maximum length: `2048`. | | `p256dh_key` | body | `string` | `Required` | Browser public key used for payload encryption. Maximum length: `256`. | | `auth_key` | body | `string` | `Required` | Browser authentication secret. Maximum length: `256`. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `subscribed` on success. | The endpoint upserts the subscription and keeps only the 10 newest subscriptions for the user. **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/notifications/subscribe" \ -H "Content-Type: application/json" \ -b cookies.txt -c cookies.txt \ -d '{ "endpoint": "https://push.example.com/sub/abc123", "p256dh_key": "", "auth_key": "" }' ``` ### POST /api/notifications/unsubscribe Removes one Web Push subscription for the current user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `endpoint` | body | `string` | `Required` | Push-service endpoint URL. Must use `https://`. Maximum length: `2048`. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `status` | `string` | Always `unsubscribed` on success. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/notifications/unsubscribe" \ -H "Content-Type: application/json" \ -b cookies.txt -c cookies.txt \ -d '{ "endpoint": "https://push.example.com/sub/abc123" }' ``` ### GET /api/users/mentions Returns paginated mentions for the current user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `offset` | query | `integer` | `0` | Pagination offset. Negative values are clamped to `0`. | | `limit` | query | `integer` | `50` | Page size. Values are clamped to the range `1-200`. | | `unread_only` | query | `boolean` | `false` | When `true`, `1`, or `yes`, only unread mentions are returned. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `mentions` | `array` | Paged mention records. | | `total` | `integer` | Total mention count for the current query. | | `unread_count` | `integer` | Current unread mention count for the user. | **`mentions[]` fields** | Field | Type | Description | | --- | --- | --- | | `id` | `integer` | Comment ID. | | `job_id` | `string` | Analysis job ID. | | `test_name` | `string` | Failure name. | | `child_job_name` | `string` | Child job name, or `""`. | | `child_build_number` | `integer` | Child build number, or `0`. | | `comment` | `string` | Original comment text. | | `username` | `string` | Comment author. | | `created_at` | `string` | Comment timestamp. | | `is_read` | `boolean` | Mention read state for the current user. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/users/mentions?limit=20&unread_only=true" \ -b cookies.txt -c cookies.txt ``` ### POST /api/users/mentions/read Marks specific mentions as read. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `comment_ids` | body | `array` | `Required` | Non-empty list of comment IDs to mark as read. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `ok` | `boolean` | Always `true` on success. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/users/mentions/read" \ -H "Content-Type: application/json" \ -b cookies.txt -c cookies.txt \ -d '{ "comment_ids": [17, 18, 19] }' ``` ### POST /api/users/mentions/read-all Marks every unread mention as read for the current user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `marked_read` | `integer` | Number of mentions marked as read. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/users/mentions/read-all" \ -b cookies.txt -c cookies.txt ``` ### GET /api/users/mentions/unread-count Returns the unread mention count for the current user. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `count` | `integer` | Unread mention count. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/users/mentions/unread-count" \ -b cookies.txt -c cookies.txt ``` ### GET /api/users/mentionable Returns the tracked usernames that can be mentioned in comments. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | None | — | — | — | No query or body parameters. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `usernames` | `array` | Tracked usernames. | **Example** ```bash curl -sS "https://rootcoz.example.com/api/users/mentionable" \ -b cookies.txt -c cookies.txt ``` ## Feedback > **Note:** `POST /api/feedback/preview` requires the server to have both a GitHub token and an AI provider/model configured. `POST /api/feedback/create` requires the server GitHub token. > **Note:** Feedback preview and creation scrub sensitive strings from the submitted content before building or creating the GitHub issue. ### POST /api/feedback/preview Builds a preview GitHub issue from end-user feedback without creating the issue. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `feedback_type` | body | `string` | `feedback` | Optional feedback type hint. | | `description` | body | `string` | `Required` | Free-form feedback description. | | `console_errors` | body | `array` | `[]` | Browser console errors. Maximum 50 items. | | `failed_api_calls` | body | `array` | `[]` | Failed API call snapshots. | | `page_state` | body | `object` | `{}` | Page context captured at submission time. | | `user_agent` | body | `string` | `""` | Browser user-agent string. | **`failed_api_calls[]` fields** | Name | Type | Default | Description | | --- | --- | --- | --- | | `status` | `integer` | `0` | HTTP status code. | | `endpoint` | `string` | `""` | API path that failed. | | `error` | `string` | `""` | Error message or response body. | **`page_state` fields** | Name | Type | Default | Description | | --- | --- | --- | --- | | `url` | `string` | `""` | Current page URL. | | `active_filters` | `string` | `""` | Active filter state. | | `report_id` | `string` | `""` | Current report ID. | **Return value** Returns `200 OK`. | Field | Type | Description | | --- | --- | --- | | `title` | `string` | Generated issue title. | | `body` | `string` | Generated markdown issue body. Includes the rootcoz AI attribution footer. | | `labels` | `array` | Generated issue labels. Values are `bug` or `enhancement`. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/feedback/preview" \ -H "Content-Type: application/json" \ -d '{ "description": "The feedback dialog stops responding after I open a report.", "console_errors": [ "TypeError: Cannot read properties of undefined (reading '\''map'\'')" ], "failed_api_calls": [ { "status": 500, "endpoint": "/api/feedback/preview", "error": "Internal Server Error" } ], "page_state": { "url": "/history?job_name=nightly-e2e", "active_filters": "team=platform;classification=PRODUCT BUG", "report_id": "job-123" }, "user_agent": "Mozilla/5.0" }' ``` ### POST /api/feedback/create Creates a GitHub issue from a feedback preview. **Parameters** | Name | In | Type | Default | Description | | --- | --- | --- | --- | --- | | `title` | body | `string` | `Required` | Issue title. | | `body` | body | `string` | `Required` | Issue body in markdown. | | `labels` | body | `array` | `[]` | Issue labels. Values outside `bug` and `enhancement` are ignored. | **Return value** Returns `201 Created`. | Field | Type | Description | | --- | --- | --- | | `issue_url` | `string` | URL of the created GitHub issue. | | `issue_number` | `integer` | GitHub issue number. | | `title` | `string` | Created issue title. | **Example** ```bash curl -sS -X POST "https://rootcoz.example.com/api/feedback/create" \ -H "Content-Type: application/json" \ -d '{ "title": "Feedback dialog freezes on report page", "body": "## Description\n\nThe feedback dialog stops responding after I open a report.", "labels": ["bug"] }' ``` ## Related Pages - [Configuration Reference](configuration-reference.html) - [CLI Command Reference](cli-command-reference.html) - [Automating Common Tasks with the CLI](automating-common-tasks-with-the-cli.html) - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Creating GitHub and Jira Issues](creating-github-and-jira-issues.html) --- Source: configuration-reference.md # Configuration Reference > **Note:** This page covers configuration keys and request-body overrides only. For CLI flag syntax that consumes them, see [CLI Command Reference](cli-command-reference.html). ## Server Environment Variables > **Note:** Server settings are read from process environment and from `.env` when present. ### Core Process and Storage | Name | Type | Default | Description | | --- | --- | --- | --- | | `PORT` | integer | `8000` | Port used by the built-in server entrypoint. Must be `1`-`65535`. | | `DEBUG` | boolean | `false` | Enables autoreload when the built-in server entrypoint starts Uvicorn. | | `LOG_LEVEL` | string | `INFO` | Log level used across server modules. | | `DB_PATH` | path | `/data/results.db` | SQLite database file. The file is created if missing; the parent directory must already exist. | | `ROOTCOZ_ENCRYPTION_KEY` | string | `unset` | Secret used for at-rest encryption and HMAC hashing of stored delegated admin API keys. When unset, rootcoz creates and reuses `$XDG_DATA_HOME/rootcoz/.encryption_key` or `~/.local/share/rootcoz/.encryption_key`. | | `PUBLIC_BASE_URL` | URL | `unset` | Trusted external base URL used for `result_url`, issue-link rendering, and Report Portal push links. A trailing `/` is stripped. When unset, server-generated links stay relative. | | `METADATA_RULES_FILE` | path | `unset` | YAML or JSON metadata-rules file. Missing or invalid files load as no rules. Rules are cached for the process lifetime. | ```bash export PORT=8000 export DB_PATH=/var/lib/rootcoz/results.db export ROOTCOZ_ENCRYPTION_KEY=change-me export PUBLIC_BASE_URL=https://rootcoz.example.com export LOG_LEVEL=INFO export METADATA_RULES_FILE=/etc/rootcoz/metadata-rules.yaml ``` Effect: These variables set the server bind port, persistent data location, secret source, public link base, and metadata-rules source. > **Warning:** Rotating `ROOTCOZ_ENCRYPTION_KEY` invalidates encrypted stored credentials and delegated admin API-key hashes. Re-save stored tokens and reissue delegated admin API keys after rotation. ### Jenkins and Repository Defaults | Name | Type | Default | Description | | --- | --- | --- | --- | | `JENKINS_URL` | URL | `unset` | Default Jenkins base URL for `POST /analyze`. | | `JENKINS_USER` | string | `unset` | Default Jenkins username. | | `JENKINS_PASSWORD` | string | `unset` | Default Jenkins password or API token. | | `JENKINS_SSL_VERIFY` | boolean | `true` | Default TLS verification setting for Jenkins requests. | | `JENKINS_TIMEOUT` | integer | `30` | Default Jenkins API timeout in seconds. | | `JENKINS_ARTIFACTS_MAX_SIZE_MB` | integer | `500` | Maximum combined downloaded artifact size in MB. | | `GET_JOB_ARTIFACTS` | boolean | `true` | Downloads Jenkins build artifacts into the AI analysis context. | | `WAIT_FOR_COMPLETION` | boolean | `true` | Waits for the Jenkins build to finish before analysis begins. | | `POLL_INTERVAL_MINUTES` | integer | `2` | Minutes between Jenkins status polls while waiting. | | `MAX_WAIT_MINUTES` | integer | `0` | Maximum wait time for Jenkins completion. `0` means no limit. | | `FORCE_ANALYSIS` | boolean | `false` | Analyzes successful builds instead of returning early. | | `TESTS_REPO_URL` | string | `unset` | Default tests repository. Supports `url:ref` syntax such as `https://github.com/org/tests:develop`. | | `TESTS_REPO_TOKEN` | string | `unset` | Default token for cloning a private tests repository. | ```bash export JENKINS_URL=https://jenkins.example.com export JENKINS_USER=ci-bot export JENKINS_PASSWORD=your-jenkins-token export JENKINS_SSL_VERIFY=true export JENKINS_TIMEOUT=30 export JENKINS_ARTIFACTS_MAX_SIZE_MB=500 export GET_JOB_ARTIFACTS=true export WAIT_FOR_COMPLETION=true export POLL_INTERVAL_MINUTES=2 export MAX_WAIT_MINUTES=0 export FORCE_ANALYSIS=false export TESTS_REPO_URL=https://github.com/acme/tests:develop export TESTS_REPO_TOKEN=your-repo-token ``` Effect: These values become the default Jenkins connection, wait behavior, artifact behavior, and tests-repo context for `POST /analyze`. ### AI and Peer-Analysis Defaults | Name | Type | Default | Description | | --- | --- | --- | --- | | `AI_PROVIDER` | string | `unset` | Default AI provider. Supported values are `claude`, `gemini`, and `cursor`. | | `AI_MODEL` | string | `unset` | Default AI model identifier. | | `AI_CLI_TIMEOUT` | integer | `10` | Default AI CLI timeout in minutes. | | `MAX_CONCURRENT_AI_CALLS` | integer | `3` | Maximum concurrent AI calls for one analysis request. | | `PEER_AI_CONFIGS` | string | `unset` | Default peer-analysis list in `provider:model,provider:model` format. | | `PEER_ANALYSIS_MAX_ROUNDS` | integer | `3` | Maximum debate rounds for peer analysis. Valid range is `1`-`10`. | | `ADDITIONAL_REPOS` | string | `unset` | Default extra repositories for AI context in `name:url[:ref][@token],...` format. Duplicate names are rejected. | ```bash export AI_PROVIDER=claude export AI_MODEL=claude-opus-4-6 export AI_CLI_TIMEOUT=10 export MAX_CONCURRENT_AI_CALLS=3 export PEER_AI_CONFIGS=cursor:gpt-5.4-xhigh,gemini:gemini-2.5-pro export PEER_ANALYSIS_MAX_ROUNDS=3 export ADDITIONAL_REPOS=infra:https://github.com/acme/infra:develop@YOUR_TOKEN,product:https://github.com/acme/product ``` Effect: These values become the default provider/model pair, AI execution limits, peer-review configuration, and extra repository context for analysis requests. > **Note:** If `AI_PROVIDER` or `AI_MODEL` is unset, the request body must supply the missing field. ### Jira Analysis and Jira Issue Settings | Name | Type | Default | Description | | --- | --- | --- | --- | | `JIRA_URL` | URL | `unset` | Jira base URL. | | `JIRA_EMAIL` | string | `unset` | Jira Cloud email. When set, rootcoz uses Cloud auth handling. | | `JIRA_API_TOKEN` | string | `unset` | Jira Cloud API token. | | `JIRA_PAT` | string | `unset` | Jira Server/Data Center personal access token. | | `JIRA_PROJECT_KEY` | string | `unset` | Default Jira project key for duplicate search and Jira issue creation. | | `JIRA_SSL_VERIFY` | boolean | `true` | TLS verification setting for Jira requests. | | `JIRA_MAX_RESULTS` | integer | `5` | Maximum Jira duplicate-search results returned during analysis. | | `ENABLE_JIRA` | boolean | `auto` | Analysis-time Jira toggle. When unset, Jira enrichment runs only when `JIRA_URL`, credentials, and `JIRA_PROJECT_KEY` are configured. | | `ENABLE_JIRA_ISSUES` | boolean | `enabled` | Jira issue preview/create toggle. Independent of `ENABLE_JIRA`. Set `false` to disable Jira issue creation. | ```bash export JIRA_URL=https://your-team.atlassian.net export JIRA_EMAIL=you@example.com export JIRA_API_TOKEN=your-jira-token export JIRA_PROJECT_KEY=PROJ export JIRA_SSL_VERIFY=true export JIRA_MAX_RESULTS=5 export ENABLE_JIRA=true export ENABLE_JIRA_ISSUES=true ``` Effect: These values control Jira duplicate search during analysis and Jira issue preview/create availability. > **Note:** Jira auth mode is selected from `JIRA_EMAIL`. When `JIRA_EMAIL` is set, rootcoz uses Cloud credentials and prefers `JIRA_API_TOKEN`, then `JIRA_PAT`. When `JIRA_EMAIL` is unset, rootcoz uses Server/Data Center credentials and prefers `JIRA_PAT`, then `JIRA_API_TOKEN`. ### GitHub and Report Portal Settings | Name | Type | Default | Description | | --- | --- | --- | --- | | `GITHUB_TOKEN` | string | `unset` | Server GitHub token for issue creation, feedback, and analysis-time GitHub lookups when a request does not override it. | | `ENABLE_GITHUB_ISSUES` | boolean | `auto` | GitHub issue preview/create toggle. When unset, server-side GitHub issue creation is available when both `TESTS_REPO_URL` and `GITHUB_TOKEN` are configured. Set `false` to disable GitHub issue creation and feedback endpoints. | | `REPORTPORTAL_URL` | URL | `unset` | Report Portal base URL. | | `REPORTPORTAL_API_TOKEN` | string | `unset` | Report Portal API token. | | `REPORTPORTAL_PROJECT` | string | `unset` | Report Portal project name. | | `REPORTPORTAL_VERIFY_SSL` | boolean | `true` | TLS verification setting for Report Portal requests. | | `ENABLE_REPORTPORTAL` | boolean | `auto` | Report Portal toggle. When unset, integration is enabled only when URL, token, and project are all configured. | ```bash export GITHUB_TOKEN=ghp_your_token export ENABLE_GITHUB_ISSUES=true export REPORTPORTAL_URL=https://reportportal.example.com export REPORTPORTAL_API_TOKEN=rp_token export REPORTPORTAL_PROJECT=qe export REPORTPORTAL_VERIFY_SSL=true export ENABLE_REPORTPORTAL=true ``` Effect: These values control GitHub issue creation, feedback availability, and Report Portal push support. > **Note:** Report Portal push also requires `PUBLIC_BASE_URL` so rootcoz can generate absolute report links. ### Access Control and Cookie Settings | Name | Type | Default | Description | | --- | --- | --- | --- | | `ADMIN_KEY` | string | `unset` | Bootstrap superuser secret. The reserved `admin` user can log in with this value, and the same value is accepted in `Authorization: Bearer ...`. | | `ALLOWED_USERS` | string | `empty` | Comma-separated usernames allowed to create or modify data. Empty keeps open access. Matching is case-insensitive, and admin users bypass the list. | | `SECURE_COOKIES` | boolean | `true` | Sets the `Secure` cookie attribute on `rootcoz_session` and `rootcoz_username`. | | `TRUST_PROXY_HEADERS` | boolean | `false` | Enables trusted-proxy user identification from `X-Forwarded-User` and syncs the `rootcoz_username` cookie from that header. | ```bash export ADMIN_KEY=your-admin-bootstrap-key export ALLOWED_USERS=alice,bob,carol export SECURE_COOKIES=true export TRUST_PROXY_HEADERS=false ``` Effect: These variables control bootstrap admin access, non-admin write permissions, and browser/session cookie behavior. > **Warning:** Enable `TRUST_PROXY_HEADERS` only when `X-Forwarded-User` is injected by infrastructure you trust. ### Web Push and Alert Delivery | Name | Type | Default | Description | | --- | --- | --- | --- | | `VAPID_PUBLIC_KEY` | string | `unset` | Web Push public key. | | `VAPID_PRIVATE_KEY` | string | `unset` | Web Push private key. | | `VAPID_CLAIM_EMAIL` | string | `mailto:noreply@rootcoz.local` | Contact email used in VAPID claims. | | `SLACK_WEBHOOK_URL` | URL | `unset` | Slack incoming-webhook URL for monitoring alerts. | | `SMTP_HOST` | string | `unset` | SMTP host for email alerts. | | `SMTP_PORT` | integer | `587` | SMTP port for email alerts. | | `SMTP_USER` | string | `unset` | SMTP username. | | `SMTP_PASSWORD` | string | `unset` | SMTP password. | | `SMTP_FROM` | string | `SMTP_USER` or `rootcoz@` | Sender address for alert email. | | `ALERT_EMAIL_TO` | string | `unset` | Recipient address for alert email. | ```bash export VAPID_PUBLIC_KEY=your-public-key export VAPID_PRIVATE_KEY=your-private-key export VAPID_CLAIM_EMAIL=admin@example.com export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXX/YYY/ZZZ export SMTP_HOST=smtp.example.com export SMTP_PORT=587 export SMTP_USER=rootcoz@example.com export SMTP_PASSWORD=mail-password export ALERT_EMAIL_TO=alerts@example.com ``` Effect: These values enable browser push notifications and optional Slack/email alert delivery. > **Note:** If both `VAPID_PUBLIC_KEY` and `VAPID_PRIVATE_KEY` are unset, rootcoz auto-generates and reuses `.vapid_keys.json` next to `DB_PATH`, or under `$XDG_DATA_HOME/rootcoz/` when `DB_PATH` is unset. > **Warning:** Set both `VAPID_PUBLIC_KEY` and `VAPID_PRIVATE_KEY` together. A partial configuration is treated as invalid and the server falls back to generated keys. ## CLI `config.toml` ### File Location and Section Layout | Name | Type | Default | Description | | --- | --- | --- | --- | | `path` | path | `$XDG_CONFIG_HOME/rootcoz/config.toml` or `~/.config/rootcoz/config.toml` | Location of the CLI profile file. | | `[default].server` | string | `unset` | Default profile name used when `--server` is omitted. | | `[defaults]` | table | empty | Shared values merged into every `[servers.]` entry. | | `[servers.]` | table | none | Named server profile. `url` must be present after `[defaults]` and profile values are merged. | ```toml [default] server = "prod" [defaults] username = "alice" no_verify_ssl = false [servers.dev] url = "http://localhost:8000" [servers.prod] url = "https://rootcoz.example.com" ``` Effect: The CLI selects `[default].server` when no explicit profile is chosen, merges `[defaults]` into the selected server, and then uses the merged profile for matching commands. > **Note:** `[defaults].server` is invalid. Only `[default].server` selects the default profile. ### Connection and Authentication Keys > **Note:** The keys below are valid in both `[defaults]` and `[servers.]`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `url` | string | required after merge | RootCoz server base URL for the profile. | | `username` | string | empty | Default CLI username used for comments, reviews, and other user-attributed requests. | | `no_verify_ssl` | boolean | `false` | Disables TLS verification for the CLI's HTTP connection to the rootcoz server. | | `api_key` | string | empty | Bearer token sent on CLI requests when `--api-key` is not provided. | ```toml [servers.prod] url = "https://rootcoz.example.com" username = "alice" no_verify_ssl = false api_key = "rootcoz_example_admin_key" ``` Effect: These keys set the CLI's server target, default user identity, TLS behavior, and bearer token. ### Analysis Default Keys > **Note:** The keys below are valid in both `[defaults]` and `[servers.]`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `jenkins_url` | string | empty | Default `--jenkins-url` value for `rootcoz analyze`. | | `jenkins_user` | string | empty | Default Jenkins username for `rootcoz analyze`. | | `jenkins_password` | string | empty | Default Jenkins password or token for `rootcoz analyze`. | | `jenkins_ssl_verify` | boolean | unset | Default Jenkins TLS verification override. | | `jenkins_timeout` | integer | `0` | Default Jenkins timeout override. `0` means the CLI sends no override. | | `tests_repo_url` | string | empty | Default tests repo URL for `rootcoz analyze`. | | `tests_repo_token` | string | empty | Default tests repo token for `rootcoz analyze`. | | `ai_provider` | string | empty | Default AI provider for `rootcoz analyze`. | | `ai_model` | string | empty | Default AI model for `rootcoz analyze`. | | `ai_cli_timeout` | integer | `0` | Default AI timeout override. `0` means the CLI sends no override. | | `max_concurrent_ai_calls` | integer | `0` | Default concurrency override. `0` means the CLI sends no override. | | `peers` | string | empty | Default peer-analysis list in `provider:model,provider:model` format. | | `peer_analysis_max_rounds` | integer | `0` | Default peer-round override. `0` means the CLI sends no override. | | `additional_repos` | string | empty | Default extra-repo list in `name:url[:ref][@token],...` format. | | `wait_for_completion` | boolean | unset | Default wait behavior for `rootcoz analyze`. | | `poll_interval_minutes` | integer | `0` | Default poll-interval override. `0` means the CLI sends no override. | | `max_wait_minutes` | integer | `0` | Default max-wait override. `0` means the CLI sends no override. | | `force` | boolean | unset | Default successful-build analysis override for `rootcoz analyze`. | ```toml [defaults] jenkins_url = "https://jenkins.example.com" jenkins_user = "ci-bot" tests_repo_url = "https://github.com/acme/tests" ai_provider = "claude" ai_model = "claude-opus-4-6" peers = "cursor:gpt-5.4-xhigh,gemini:gemini-2.5-pro" additional_repos = "infra:https://github.com/acme/infra:develop@YOUR_TOKEN" wait_for_completion = true [servers.prod] url = "https://rootcoz.example.com" max_concurrent_ai_calls = 5 force = true ``` Effect: When `rootcoz analyze` runs without explicit flags, the CLI fills matching request-body fields from the selected profile. Explicit CLI flags still override the profile. > **Note:** In `config.toml`, `0` means "do not send a CLI override" for `ai_cli_timeout`, `max_concurrent_ai_calls`, `jenkins_timeout`, `jira_max_results`, `poll_interval_minutes`, `max_wait_minutes`, and `peer_analysis_max_rounds`. This is different from request-body `max_wait_minutes: 0`, which means "no limit". ### Tracker Default Keys > **Note:** The keys below are valid in both `[defaults]` and `[servers.]`. | Name | Type | Default | Description | | --- | --- | --- | --- | | `jira_url` | string | empty | Default Jira base URL for analysis and Jira-related CLI commands. | | `jira_email` | string | empty | Default Jira Cloud email. | | `jira_api_token` | string | empty | Default Jira Cloud API token for `rootcoz analyze`. | | `jira_pat` | string | empty | Default Jira Server/Data Center token for `rootcoz analyze`. | | `jira_token` | string | empty | Default generic Jira token for `rootcoz jira-projects`, `rootcoz jira-security-levels`, `rootcoz preview-issue`, and `rootcoz create-issue`. | | `jira_project_key` | string | empty | Default Jira project key for analysis and Jira issue commands. | | `jira_security_level` | string | empty | Default Jira security level name for Jira issue preview/create commands. | | `jira_ssl_verify` | boolean | unset | Default Jira TLS verification override. | | `jira_max_results` | integer | `0` | Default Jira duplicate-search override. `0` means the CLI sends no override. | | `enable_jira` | boolean | unset | Default Jira-enrichment toggle for `rootcoz analyze`. | | `github_token` | string | empty | Default GitHub token for analysis and GitHub issue commands. | | `github_repo_url` | string | empty | Default GitHub repository URL override for GitHub issue preview/create commands. | ```toml [servers.prod] url = "https://rootcoz.example.com" jira_url = "https://your-team.atlassian.net" jira_email = "you@example.com" jira_token = "your-jira-token" jira_project_key = "PROJ" jira_security_level = "Internal" enable_jira = true github_token = "ghp_your_token" github_repo_url = "https://github.com/acme/tests" ``` Effect: These keys fill tracker-related CLI request fields when matching flags are omitted. ## Authentication Modes > **Note:** `rootcoz_username` and `X-Forwarded-User` identify non-admin users. Admin privileges come from `rootcoz_session` or `Authorization: Bearer ...`. ### Username Cookie Mode | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `rootcoz_username` | cookie | absent | Non-admin username used for request attribution. The reserved username `admin` is ignored in this mode. | ```bash curl https://rootcoz.example.com/api/auth/me \ --cookie "rootcoz_username=alice" ``` Effect: The request runs as `alice` with `role=user` and `is_admin=false`. Admin-only routes still require session or Bearer auth, and non-admin write routes can still be limited by `ALLOWED_USERS`. ### Trusted-Proxy Header Mode | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `TRUST_PROXY_HEADERS` | server boolean | `false` | Enables trusted-proxy user identification. | | `X-Forwarded-User` | request header | absent | Username supplied by the trusted proxy. The reserved username `admin` is ignored. | ```bash curl https://rootcoz.example.com/api/auth/me \ -H "X-Forwarded-User: alice" ``` Effect: When `TRUST_PROXY_HEADERS=true`, rootcoz sets `username` from `X-Forwarded-User`, returns `role=user`, and writes a matching `rootcoz_username` cookie on the response. Existing session auth takes precedence. ### Session Login Mode | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `username` | JSON string | required | Login username. `admin` with `ADMIN_KEY` uses the bootstrap superuser path; stored user or admin API keys can also be used with their matching username. | | `api_key` | JSON string | required | API key for the matching user or bootstrap admin. | | `rootcoz_session` | cookie | set on success | HTTP-only session cookie with fixed 8-hour TTL. | ```bash curl -c cookies.txt \ -H "Content-Type: application/json" \ -d '{"username":"admin","api_key":"'"$ADMIN_KEY"'"}' \ https://rootcoz.example.com/api/auth/login ``` Effect: Successful login returns JSON with `username`, `role`, and `is_admin`, and sets `rootcoz_session` plus `rootcoz_username`. Active sessions are renewed when less than half of the 8-hour TTL remains. ### Bearer Token Mode | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `Authorization` | header | absent | `Bearer `. Accepts `ADMIN_KEY` or any stored API key. | ```bash curl https://rootcoz.example.com/api/auth/me \ -H "Authorization: Bearer $ADMIN_KEY" ``` Effect: `ADMIN_KEY` or an admin user's API key gives admin access. A non-admin user's API key sets `username` and `role=user` without admin privileges. ## Per-request Analysis Overrides > **Note:** Shared fields below are accepted by `POST /analyze`, `POST /analyze-failures`, and `POST /re-analyze/{job_id}`. On `POST /re-analyze/{job_id}`, omitted fields come from the original job's stored request parameters. ### Shared Override Fields | Name | Type | Default | Description | | --- | --- | --- | --- | | `tests_repo_url` | string | `null` | Overrides `TESTS_REPO_URL` for this request. Supports `url:ref` syntax. | | `tests_repo_token` | string | `null` | Overrides `TESTS_REPO_TOKEN` for this request. | | `ai_provider` | string | `null` | Overrides `AI_PROVIDER`. Supported values are `claude`, `gemini`, and `cursor`. | | `ai_model` | string | `null` | Overrides `AI_MODEL`. | | `enable_jira` | boolean | `null` | Per-request Jira-enrichment toggle. `false` disables Jira duplicate search for this request even if the server is configured. | | `ai_cli_timeout` | integer | `null` | Overrides `AI_CLI_TIMEOUT` in minutes. Must be greater than `0`. | | `max_concurrent_ai_calls` | integer | `null` | Overrides `MAX_CONCURRENT_AI_CALLS`. Must be greater than `0`. | | `jira_url` | string | `null` | Overrides `JIRA_URL` for this request. | | `jira_email` | string | `null` | Overrides `JIRA_EMAIL` for this request. | | `jira_api_token` | string | `null` | Overrides `JIRA_API_TOKEN` for this request. | | `jira_pat` | string | `null` | Overrides `JIRA_PAT` for this request. | | `jira_project_key` | string | `null` | Overrides `JIRA_PROJECT_KEY` for this request. | | `jira_ssl_verify` | boolean | `null` | Overrides `JIRA_SSL_VERIFY` for this request. | | `jira_max_results` | integer | `null` | Overrides `JIRA_MAX_RESULTS`. Must be greater than `0`. | | `raw_prompt` | string | `null` | Additional AI instructions for this request. When set, this request's value replaces the repo-level `JOB_INSIGHT_PROMPT.md` default. | | `github_token` | string | `null` | Overrides `GITHUB_TOKEN` for analysis-time GitHub lookups. | | `peer_ai_configs` | array | `null` | Structured peer list. Omit to inherit the server default; send `[]` to disable peers for this request. | | `peer_analysis_max_rounds` | integer | `3` | Peer-analysis debate rounds. Valid range is `1`-`10`. The server only treats it as an override when the field is explicitly present in the JSON body. | | `additional_repos` | array | `null` | Structured extra-repo list. Omit to inherit the server default; send `[]` to disable extra repos for this request. | #### `peer_ai_configs[]` Entries | Name | Type | Default | Description | | --- | --- | --- | --- | | `ai_provider` | string | required | Peer provider. Supported values are `claude`, `gemini`, and `cursor`. | | `ai_model` | string | required | Peer model identifier. | #### `additional_repos[]` Entries | Name | Type | Default | Description | | --- | --- | --- | --- | | `name` | string | required | Unique repository label used as the clone subdirectory name. Cannot contain `/`, `\`, `..`, a leading `.`, or reserved names. | | `url` | URL | required | Repository clone URL. | | `ref` | string | empty | Branch or tag to check out. | | `token` | string | `null` | Per-repository clone token for private repositories. | ```json { "ai_provider": "gemini", "ai_model": "gemini-2.5-pro", "enable_jira": false, "peer_ai_configs": [], "additional_repos": [ { "name": "infra", "url": "https://github.com/acme/infra", "ref": "develop" } ] } ``` Effect: These fields override shared analysis behavior for one request only. The same fields can be sent to `POST /re-analyze/{job_id}` to change selected settings while keeping the rest of the original job configuration. > **Note:** `peer_ai_configs=[]` and `additional_repos=[]` explicitly turn off a server default for one request. Omitting the field keeps the server default. ### `POST /analyze`-only Fields > **Note:** The schema defaults below are shown for lookup. `wait_for_completion`, `poll_interval_minutes`, `max_wait_minutes`, and `force` only override the server setting when the field is explicitly present in the JSON body. | Name | Type | Default | Description | | --- | --- | --- | --- | | `jenkins_url` | string | `null` | Overrides `JENKINS_URL` for this request. | | `jenkins_user` | string | `null` | Overrides `JENKINS_USER` for this request. | | `jenkins_password` | string | `null` | Overrides `JENKINS_PASSWORD` for this request. | | `jenkins_ssl_verify` | boolean | `null` | Overrides `JENKINS_SSL_VERIFY` for this request. | | `jenkins_timeout` | integer | `null` | Overrides `JENKINS_TIMEOUT` in seconds. Must be greater than `0`. | | `jenkins_artifacts_max_size_mb` | integer | `null` | Overrides `JENKINS_ARTIFACTS_MAX_SIZE_MB`. Must be greater than `0`. | | `get_job_artifacts` | boolean | `null` | Overrides `GET_JOB_ARTIFACTS` for this request. | | `wait_for_completion` | boolean | `true` | Waits for Jenkins completion before analysis. Only overrides the server when the field is explicitly present. | | `poll_interval_minutes` | integer | `2` | Poll interval while waiting. Must be greater than `0`. Only overrides the server when the field is explicitly present. | | `max_wait_minutes` | integer | `0` | Maximum wait time. `0` means no limit. Only overrides the server when the field is explicitly present. | | `force` | boolean | `false` | Overrides `FORCE_ANALYSIS` for this request. Only overrides the server when the field is explicitly present. | ```json { "job_name": "folder/nightly-suite", "build_number": 123, "jenkins_url": "https://jenkins.example.com", "jenkins_user": "ci-bot", "jenkins_password": "YOUR_JENKINS_TOKEN", "wait_for_completion": true, "poll_interval_minutes": 5, "max_wait_minutes": 0, "force": true, "get_job_artifacts": true } ``` Effect: These fields control Jenkins connectivity, artifact download, waiting behavior, and successful-build analysis for the queued job. > **Note:** In request bodies, `max_wait_minutes: 0` means "no limit". This differs from `config.toml`, where `max_wait_minutes = 0` means "do not send a CLI override". ## Related Pages - [CLI Command Reference](cli-command-reference.html) - [API Endpoint Reference](api-endpoint-reference.html) - [Submitting Jenkins Builds and JUnit XML](submitting-jenkins-builds-and-junit-xml.html) - [Connecting GitHub, Jira, and Report Portal](connecting-github-jira-and-report-portal.html) - [Managing Users and API Keys](managing-users-and-api-keys.html) ---