Repository navigation
Conversation
…bilities
Add a 'discover' subcommand to pre_triage_security.py that runs the
triage-security Discovery-mode "Untriaged issues" JQL on the trusted
runner and prints {"issues": [{"key", "url"}]} in JQL order, capped
by --max-results (default 20). The GitLab poller uses it to dispatch
one triage-security run per issue without re-implementing the query.
Keys are validated against the configured project and any config or
Jira failure exits 1 with an ERROR on stderr. A test asserts the JQL
against the SKILL.md query so the two cannot drift.
Implements TC-6931
Assisted-by: Claude Code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pin the triage-security harness base to the discover entry point commit and re-lock triage-security only; verify-pr is unchanged. Implements TC-6931 Assisted-by: Claude Code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideThis PR introduces a trusted-runner discover entry point that validates project and Jira configuration, executes the documented untriaged Vulnerability JQL with bounded paging, and emits safely constrained issue key/URL records for the TC-6918 poller. It adds synchronization-focused tests and refreshes only the triage-security harness pin and lock metadata. Sequence diagram for discovering untriaged security issuessequenceDiagram
participant Poller as TC6918Poller
participant Runner as TrustedRunner
participant Script as pre_triage_security.py
participant Jira as JiraClient
Poller->>Runner: Run discover project_root --max-results N
Runner->>Script: discover_untriaged(project_root, max_results)
Script->>Script: parse_security_configuration(CLAUDE.md)
Script->>Script: untriaged_jql(configuration)
Script->>Jira: search_jql(--jql, --fields key, paging)
Jira-->>Script: Issues in JQL order
Script->>Script: Validate keys and trim to cap
Script-->>Runner: {issues: [{key, url}]}
Runner-->>Poller: Dispatch one triage-security run per issue
Flow diagram for fail-closed discovery validationflowchart TD
A[discover project_root] --> B{Valid cap?}
B -- No --> E[ERROR on stderr; no stdout]
B -- Yes --> C{JIRA_SERVER_URL and CLAUDE.md valid?}
C -- No --> E
C -- Yes --> D{Configuration and issue type ID valid?}
D -- No --> E
D -- Yes --> F[Build untriaged JQL]
F --> G{Jira search succeeds?}
G -- No --> E
G -- Yes --> H{Every issue key belongs to project?}
H -- No --> E
H -- Yes --> I[Emit issue key and browse URL JSON]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="plugins/sdlc-workflow/scripts/pre_triage_security.py" line_range="879" />
<code_context>
+ claude_path = Path(project_root) / "CLAUDE.md"
+ if not claude_path.is_file():
+ raise EvidenceError("target project CLAUDE.md is required")
+ configuration = parse_security_configuration(claude_path.read_text())
+ project = configuration["project_key"]
+ # One search_jql page holds at most 50 issues; page with --all only when the
</code_context>
<issue_to_address>
**Configuration read prints traceback**
When the target `CLAUDE.md` exists but is unreadable or contains invalid UTF-8, `Path.read_text()` raises `OSError` or `UnicodeDecodeError`, and `main()` catches neither exception. The command prints a traceback instead of the promised `ERROR: ...` diagnostic.
Handle read and decode errors through the same error-reporting path that prints the documented `ERROR: ...` diagnostic.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: plugins/sdlc-workflow/scripts/pre_triage_security.py:879
|
🤖 Finished Verify Pr · ✅ Success · Started 9:09 AM UTC · Completed 9:24 AM UTC Commit: Runtime: claude · Model: claude-opus-4-8 · Effort: high · Cost: $6.57 |
Eval ResultsSource head: 6abb66a Eval Results: triage-security
Pass rate: 100% · Tokens: 61,947 · Duration: 114s Baseline ( Generated by sdlc-workflow/run-evals v0.13.10 |
There was a problem hiding this comment.
Native Fullsend Eval Results
Head: df5b3dd
Merge: 1b87f12
Trusted workflow: 7ef0f3c
Reviewed eval source: 7ef0f3c
Native job: success; complete: true.
Execution evidence: valid; quality score (advisory): 26/28 passed.
| Case | Execution evidence | Quality score (advisory) |
|---|---|---|
| 033-absent | valid | 4/4 |
| 034-empty | valid | 5/5 |
| 035-malformed | valid | 3/5 |
| 036-valid | valid | 7/7 |
| 037-release | valid | 7/7 |
|
[sdlc-workflow/verify-pr] Re: @sourcery-ai[bot] review - Classified as code change request - sub-task TC-6961 created to address the single blocking finding (uncaught read/decode error for an unreadable or invalid-UTF-8 CLAUDE.md at pre_triage_security.py:879). No other actionable items in the review body. |
Verification Report for TC-6931 (commit df5b3dd)
Overall: WARNOverall WARN. The PR is in scope, proportionate, traceable, secret-free, and CI is fully green; the new discover entry point and its JQL match the triage-security Discovery-mode query, with additive, well-documented tests. One confirmed reviewer finding remains: an unreadable or invalid-UTF-8 target CLAUDE.md makes pre_triage_security.py read_text() raise OSError/UnicodeDecodeError that main() does not catch, printing a traceback instead of the contract-promised 'ERROR: ...' exit (a partial gap against acceptance criterion 3). A review-feedback sub-task tracks the fix (covering the sibling collect/parse-configuration call sites too), and a root-cause task targets the implement-task skill so future implementations route file read/decode failures through the documented error path. No code was modified and the PR was not merged - a human reviewer decides whether to merge. This comment was AI-generated by sdlc-workflow/verify-pr v0.13.10. |
Path.read_text() raises OSError or UnicodeDecodeError for an unreadable or non-UTF-8 file, and main() caught neither, so discover, collect and parse-configuration printed a traceback instead of 'ERROR: ...'. Route every CLAUDE.md and security-matrix read through a _read_text helper that raises EvidenceError, mirroring validate_bundle's read idiom. Implements TC-6961 Assisted-by: Claude Code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🤖 Finished Verify Pr · ✅ Success · Started 9:36 AM UTC · Completed 9:47 AM UTC Commit: Runtime: claude · Model: claude-opus-4-8 · Effort: high · Cost: $5.59 |
Verification Report for TC-6931 (commit 9fabe0e)
Overall: WARNTwo advisory WARNs, no FAIL. Review Feedback - one sourcery-ai finding (uncaught CLAUDE.md read/decode error at This comment was AI-generated by sdlc-workflow/verify-pr v0.13.10. |
There was a problem hiding this comment.
Native Fullsend Eval Results
Head: 9fabe0e
Merge: 0033cb0
Trusted workflow: 7ef0f3c
Reviewed eval source: 7ef0f3c
Native job: success; complete: true.
Execution evidence: valid; quality score (advisory): 28/28 passed.
| Case | Execution evidence | Quality score (advisory) |
|---|---|---|
| 033-absent | valid | 4/4 |
| 034-empty | valid | 5/5 |
| 035-malformed | valid | 5/5 |
| 036-valid | valid | 7/7 |
| 037-release | valid | 7/7 |
Pin the triage-security harness base to the CLAUDE.md read-error fix so fullsend runs serve the updated pre_triage_security.py. Re-lock triage-security only; verify-pr is unchanged. Implements TC-6961 Assisted-by: Claude Code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🤖 Finished Verify Pr · ✅ Success · Started 9:55 AM UTC · Completed 10:04 AM UTC Commit: Runtime: claude · Model: claude-opus-4-8 · Effort: high · Cost: $5.17 |
Verification Report for TC-6931 (commit 6abb66a)
Overall: WARNThe PR implements the This comment was AI-generated by sdlc-workflow/verify-pr v0.13.10. |
There was a problem hiding this comment.
Native Fullsend Eval Results
Head: 6abb66a
Merge: c1f76fd
Trusted workflow: 7ef0f3c
Reviewed eval source: 7ef0f3c
Native job: success; complete: true.
Execution evidence: valid; quality score (advisory): 27/28 passed.
| Case | Execution evidence | Quality score (advisory) |
|---|---|---|
| 033-absent | valid | 4/4 |
| 034-empty | valid | 5/5 |
| 035-malformed | valid | 4/5 |
| 036-valid | valid | 7/7 |
| 037-release | valid | 7/7 |
PR RHEcosystemAppEng#344 was rebase-merged, so the pinned 9fabe0e is not on main and only resolves through refs/pull/344/head. Re-pin the triage-security base to c489134, the same content as it landed on main, and re-lock triage-security only. Pinned file hashes are unchanged; verify-pr is untouched. Refs TC-6931 Assisted-by: Claude Code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
discoversubcommand topre_triage_security.py:python3 pre_triage_security.py discover <project_root> [--max-results N]runs the triage-security SKILL.md Discovery-mode "Untriaged issues" JQL on the trusted runner and prints{"issues": [{"key", "url"}]}in JQL order (default cap 20). The TC-6918 GitLab poller uses it to dispatch one triage-security run per issue.JIRA_SERVER_URL, a non-numeric issue type ID, a non-positive cap, a Jira failure, or a key outside the configured project all exit 1 withERROR: ...on stderr and print nothing on stdout.9fabe0ef(latest, after the TC-6961 fix; triage-security only;.fullsend/harness/verify-pr.yamland its lock entry are untouched).ERROR: cannot read ...instead of a traceback, indiscover,collectandparse-configuration(new_read_texthelper).Notes for review
_jql_escaped (project = "TC"), the same waycollectdoes it. The SKILL.md template has it unquoted, so the drift test fills in the quoted form.jira-client.pyhas no separatesearch_jql_allsubcommand;search_jql_allis reached throughsearch_jql --all. A cap of 50 or less uses one page (--max-results N). Above 50 it uses--alland then trims to the cap. The JQL itself does the filtering; nothing is filtered afterwards.Merge with a merge commit (not squash/rebase):
.fullsend/pins the commit SHA9fabe0ef.Test plan
python3 -m pytest plugins/sdlc-workflow/scripts/ -q: 704 passed, 3 skippeduvx skillsaw: 0 errors (triage-security SKILL.md at 15,875 tokens, under the 16k budget)git diff main -- .fullsend/harness/verify-pr.yaml: emptyImplements TC-6931
🤖 Generated with Claude Code
Summary by Sourcery
Enable secure automated discovery of untriaged vulnerability issues for downstream triage dispatch.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Chores: