Skip to content

OSAC-959: Add internal-proposals/ directory & prd/design docs for agentic-sdlc measurement, harden docs routing - #160

Closed
tchughesiv wants to merge 1 commit into
osac-project:mainfrom
tchughesiv:chore/internal-proposals-routing
Closed

OSAC-959: Add internal-proposals/ directory & prd/design docs for agentic-sdlc measurement, harden docs routing#160
tchughesiv wants to merge 1 commit into
osac-project:mainfrom
tchughesiv:chore/internal-proposals-routing

Conversation

@tchughesiv

@tchughesiv tchughesiv commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Background

OSAC-959 ("Create metrics
and methods to evaluate the success of the agentic-sdlc process over
time") is internal engineering tooling to measure how well AI-agent-driven
development is working for the OSAC team, not an OSAC product/tenant-facing
capability.

This came up in Slack because OSAC-959's PRD/design docs had nowhere to
go: enhancement-proposals is scoped to OSAC product features with
tenant-facing surface and CRD/API footprint (see that repo's README, "Is
my proposed change an enhancement?"), and its EP Review Bot scores every
PRD/design against a rubric built for exactly that shape of work —
CRD-heavy, tied to one of OSAC's four canonical personas. OSAC-959 has
none of that by design, so submitting it there would mean either scoring
it against criteria that don't apply (most of Architecture is N/A, no
personas affected, no comparable exemplar in the reference library) or
carving out a bot-side exception for it.

Rather than stretch enhancement-proposals' scope or special-case its
bot, this PR gives internal engineering process/tooling work a durable,
reviewed home of its own — inside osac-workspace, where the rest of
this kind of work (evals/, skills/, .design/context/) already
lives. internal-proposals/ isn't scoped to agentic-SDLC work
specifically — it's a general home for any internal engineering
proposal with no tenant-facing surface and no CRD/API footprint,
regardless of subject matter. OSAC-959 is simply the first occupant and
the ticket whose ambiguity surfaced the need for it; the osac-agentic-sdlc
Jira label check in AGENTS.md is one convenience heuristic for one
initiative's tickets, not the directory's defining scope.

What's in this PR

  1. internal-proposals/ — new workspace-native directory for PRD/design
    docs that are internal engineering process/tooling, not OSAC product
    features. Includes a README.md with the location decision, naming
    convention, review process, and a rubric-calibration caveat for
    self-reviewing with prd-review/design-review. Migrates the
    OSAC-959 PRD and design
    docs here from a personal enhancement-proposals fork branch that was
    never opened as a PR there.

  2. AGENTS.md — adds an "Internal-Only Proposals" section pointing to
    internal-proposals/README.md, plus two hardening additions:

    • A mechanical routing signal for /prd:ingest//design:ingest: check
      the Jira issue's Labels (already captured in 01-requirements.md)
      for osac-agentic-sdlc as a fast first-pass default — confirmed with
      the user, not silently applied, since the label means "part of the
      agentic-SDLC initiative," not "definitely non-tenant-facing."
    • A publish-time override: /prd:publish//design:publish's "Resolve
      Docs Repo" step assumes a separate checked-out docs repo and caches
      the answer in .artifacts/prd/config.json (scoped to
      enhancement-proposals). internal-proposals/ is part of this repo,
      so that step is skipped in favor of a same-repo commit using this
      repo's own remotes.
  3. Naming validation CItools/check_internal_proposals_naming.py
    (adapted from enhancement-proposals' check_ep_naming.py), its unit
    tests (27, all passing), and a path-scoped GitHub Actions workflow
    (.github/workflows/internal-proposals-naming.yml) enforcing
    OSAC-NNNN-slug/{prd,design}.md naming on PRs touching
    internal-proposals/, with grandfathering for pre-existing paths.

Validation

  • python3 -m unittest test_check_internal_proposals_naming -v — 27/27 pass
  • actionlint .github/workflows/internal-proposals-naming.yml — clean
  • python3 -m py_compile on both new scripts — clean
  • Negative-tested the CI itself: pushed a commit with a deliberately
    non-compliant directory name (internal-proposals/bad-name-no-jira-key/),
    confirmed check-naming failed with the expected message, then reverted
    it — CI correctly returned to green.

Assisted-by: Claude Code noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Added guidance for routing and publishing internal-only proposals.
    • Added an internal proposal for measuring agentic SDLC performance.
    • Documented proposal naming conventions, review expectations, and available entries.
    • Updated PRD and design review guidance for internal proposals.
  • Bug Fixes

    • Added automated validation to identify incorrectly named internal proposal folders and files.
  • Tests

    • Added coverage for naming validation, grandfathered proposals, and advisory scenarios.

@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: tchughesiv

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds internal proposal routing and review guidance, introduces the OSAC-959 agentic SDLC measurement PRD/design, and adds tested naming validation enforced by GitHub Actions.

Changes

Internal proposals

Layer / File(s) Summary
Internal proposal routing and review guidance
AGENTS.md, internal-proposals/README.md, skills/*-review/SKILL.md
Documents proposal placement, publishing workflows, review expectations, rubric caveats, and local internal-proposal paths.
Agentic SDLC measurement proposal
internal-proposals/OSAC-959-agentic-sdlc-measurement/*
Adds phased measurement requirements covering review scoring, operational metrics, reporting, security, testing, and provenance.
Naming validation and CI enforcement
tools/check_internal_proposals_naming.py, tools/test_check_internal_proposals_naming.py, .github/workflows/internal-proposals-naming.yml
Adds Git-aware naming and filename-casing validation, comprehensive unit tests, and pull-request workflow integration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant GitHubActions
  participant Git
  participant NamingChecker
  PullRequest->>GitHubActions: trigger for internal-proposals changes
  GitHubActions->>Git: resolve base SHA and changed paths
  GitHubActions->>NamingChecker: run tests and validate paths
  NamingChecker->>Git: inspect base and live refs
  NamingChecker-->>GitHubActions: return validation status
Loading

Possibly related PRs

Suggested reviewers: adriengentil, rgolangh, jhernand

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the new internal-proposals docs, OSAC-959 content, and routing/naming hardening.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets in the PR diff; searches found no secret-like literals, embedded credentials, or private keys.
No-Weak-Crypto ✅ Passed Scanned all changed files; no weak-crypto algorithms, custom crypto, or secret-comparison patterns were present.
No-Injection-Vectors ✅ Passed No flagged injection patterns found; the workflow quotes path args, and the Python helper uses list-form subprocess calls with no shell/eval/deserialization sinks.
Container-Privileges ✅ Passed No container/K8s manifests were added; the only YAML change is a GitHub Actions workflow with no privileged/root/securityContext flags.
No-Sensitive-Data-In-Logs ✅ Passed Only emits path/base-SHA status messages; no passwords, tokens, PII, hostnames, or customer data are logged.
Ai-Attribution ✅ Passed HEAD commit includes Assisted-by: Claude Code <noreply@anthropic.com> and no Co-Authored-By trailer was found in the PR range.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tchughesiv tchughesiv changed the title Add internal-proposals/ directory and harden docs routing (OSAC-959) OSAC-959: Add internal-proposals/ directory and harden docs routing Jul 27, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 27, 2026

Copy link
Copy Markdown

@tchughesiv: This pull request references OSAC-959 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the feature to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

Resolves the OSAC-959 process ambiguity from Slack: internal engineering
process/tooling docs (agentic-SDLC measurement) don't fit
enhancement-proposals' tenant-facing/CRD-API scope, but had no durable,
reviewed, discoverable home of their own.

What's in this PR

  1. internal-proposals/ — new workspace-native directory for PRD/design
    docs that are internal engineering process/tooling, not OSAC product
    features. Includes a README.md with the location decision, naming
    convention, review process, and a rubric-calibration caveat for
    self-reviewing with prd-review/design-review. Migrates the OSAC-959
    PRD and design docs here from a personal enhancement-proposals fork
    branch that was never opened as a PR there.

  2. AGENTS.md — adds an "Internal-Only Proposals" section pointing to
    internal-proposals/README.md, plus two hardening additions:

  • A mechanical routing signal for /prd:ingest//design:ingest: check
    the Jira issue's Labels (already captured in 01-requirements.md)
    for osac-agentic-sdlc as a fast first-pass default — confirmed with
    the user, not silently applied, since the label means "part of the
    agentic-SDLC initiative," not "definitely non-tenant-facing."
  • A publish-time override: /prd:publish//design:publish's "Resolve
    Docs Repo" step assumes a separate checked-out docs repo and caches
    the answer in .artifacts/prd/config.json (scoped to
    enhancement-proposals). internal-proposals/ is part of this repo,
    so that step is skipped in favor of a same-repo commit using this
    repo's own remotes.
  1. Naming validation CItools/check_internal_proposals_naming.py
    (adapted from enhancement-proposals' check_ep_naming.py), its unit
    tests (27, all passing), and a path-scoped GitHub Actions workflow
    (.github/workflows/internal-proposals-naming.yml) enforcing
    OSAC-NNNN-slug/{prd,design}.md naming on PRs touching
    internal-proposals/, with grandfathering for pre-existing paths.

Validation

  • python3 -m unittest test_check_internal_proposals_naming -v — 27/27 pass
  • actionlint .github/workflows/internal-proposals-naming.yml — clean
  • python3 -m py_compile on both new scripts — clean

Assisted-by: Claude Code noreply@anthropic.com

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@tchughesiv tchughesiv changed the title OSAC-959: Add internal-proposals/ directory and harden docs routing OSAC-959: Add internal-proposals/ home for agentic-SDLC measurement docs, harden docs routing Jul 27, 2026
@tchughesiv tchughesiv changed the title OSAC-959: Add internal-proposals/ home for agentic-SDLC measurement docs, harden docs routing OSAC-959: Add internal-proposals/ directory for internal-only engineering docs, harden routing Jul 27, 2026
@tchughesiv tchughesiv changed the title OSAC-959: Add internal-proposals/ directory for internal-only engineering docs, harden routing OSAC-959: Add internal-proposals/ directory & prd/design docs for agentic-sdlc measurement, harden docs routing Jul 27, 2026
@tchughesiv
tchughesiv force-pushed the chore/internal-proposals-routing branch from 39882e0 to cf30c95 Compare July 27, 2026 17:24
…ring docs

Gives internal engineering process/tooling work (no tenant-facing surface,
no CRD/API footprint) a durable, reviewed home of its own inside
osac-workspace, distinct from enhancement-proposals (scoped to OSAC
product/tenant-facing features). Not scoped to any one initiative --
OSAC-959 (agentic-SDLC measurement) is simply the first occupant and the
ticket whose ambiguity surfaced the need for it.

- internal-proposals/README.md: location decision, naming convention,
  review process, and a rubric-calibration caveat for prd-review/
  design-review, validated by self-running both skills against a real
  OSAC feature PRD/design and against the OSAC-959 PRD/design here --
  design-review scored the internal design 8/8 (N/As documented, not
  penalized); prd-review failed the internal PRD 6/10, driven mostly by
  genuinely fixable writing gaps rather than the WHAT=0 auto-fail clause
  (that clause is about content-only deliverables, not internal-vs-
  tenant-facing scope, and did not fire)
- internal-proposals/OSAC-959-agentic-sdlc-measurement/{prd,design}.md:
  migrated from a personal enhancement-proposals fork branch that was
  never opened as a PR there; prd.md additionally revised post-review to
  drop internal codenames/personal-fork paths, split out a separable
  cost-telemetry capability, and sharpen scope bullets into checkable
  outcomes
- AGENTS.md: 'Internal-Only Proposals' section pointing to
  internal-proposals/README.md, a mechanical Jira-label routing signal
  (osac-agentic-sdlc) for /prd:ingest and /design:ingest, and a
  publish-time override skipping the enhancement-proposals-scoped
  docs-repo/config.json flow in favor of a same-repo commit
- tools/check_internal_proposals_naming.py (+ 27 unit tests) and
  .github/workflows/internal-proposals-naming.yml: naming validation CI
  enforcing OSAC-<key>-<slug>/{prd,design}.md, adapted from
  enhancement-proposals' check_ep_naming.py, with grandfathering for
  pre-existing paths
- skills/prd-review/SKILL.md, skills/design-review/SKILL.md: add
  internal-proposals/<slug>/{prd,design}.md as an example input path,
  pointing to the rubric caveat above -- no rubric logic changed

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Tommy Hughes <tohughes@redhat.com>
@tchughesiv
tchughesiv force-pushed the chore/internal-proposals-routing branch from cf30c95 to 8c8a986 Compare July 27, 2026 17:49
@tchughesiv
tchughesiv marked this pull request as ready for review July 27, 2026 17:50
@openshift-ci
openshift-ci Bot requested review from larsks and rgolangh July 27, 2026 17:50

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/internal-proposals-naming.yml:
- Around line 20-21: Update the workflow’s top-level permissions configuration
to add a restrictive fallback, while preserving the existing job-level contents:
read scope. Ensure future jobs inherit minimal permissions unless they
explicitly declare their own narrower requirements.

In `@AGENTS.md`:
- Around line 180-183: Update the Git workflow instructions in AGENTS.md at
lines 180-183 and internal-proposals/README.md at lines 55-57 to require the
Assisted-by: Claude Code <noreply@anthropic.com> trailer on AI-assisted commits
and prohibit AI Co-Authored-By trailers; keep both duplicated workflow
descriptions consistent.

In `@internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md`:
- Around line 169-171: Update the Security Considerations section describing
qualitative_finding_quality to remove the claim that no new exposure is
introduced. Specify classification and redaction requirements for
reference-review.md, document provider retention and access guarantees, and
explicitly exclude content not approved for external LLM processing before
characterizing the resulting exposure profile.
- Around line 129-140: Document the pinned qualitative_finding_quality judge’s
output scale and how its LLM responses are parsed and mapped to annotations
before applying the min_mean: 3.5 threshold. Clarify the alignment used for
annotation comparison and Cohen’s κ, while keeping the existing deterministic
judge definitions and thresholds unchanged.

In `@internal-proposals/OSAC-959-agentic-sdlc-measurement/prd.md`:
- Around line 49-50: Update the phased validation completion criteria in the
referenced PRD section to require a golden dataset and reproducible judge/human
agreement report only for Phases 1–2. Define phase-appropriate acceptance
criteria for Phases 3–4 based on their operational metrics, Org Pulse trends,
and reporting deliverables, avoiding a universal calibration requirement.

In `@internal-proposals/README.md`:
- Around line 45-48: Update the Markdown code block around the
internal-proposals path examples in README.md to include the text language
identifier, preserving the example contents and formatting so Markdownlint rule
MD040 passes.

In `@tools/check_internal_proposals_naming.py`:
- Around line 87-94: Return the combined grandfathering condition directly from
is_grandfathered, preserving the existing checks that require a non-None
base_sha or live_base_ref before calling path_exists_at_ref.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e83ee9d6-f555-4f46-947b-fb29b7b4fe3f

📥 Commits

Reviewing files that changed from the base of the PR and between 7b4fff2 and 8c8a986.

📒 Files selected for processing (9)
  • .github/workflows/internal-proposals-naming.yml
  • AGENTS.md
  • internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md
  • internal-proposals/OSAC-959-agentic-sdlc-measurement/prd.md
  • internal-proposals/README.md
  • skills/design-review/SKILL.md
  • skills/prd-review/SKILL.md
  • tools/check_internal_proposals_naming.py
  • tools/test_check_internal_proposals_naming.py

Comment on lines +20 to +21
permissions:
contents: read

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Optional: add a top-level permissions: fallback.

The job already scopes contents: read, which is correctly minimal. Static analysis still flags the workflow for lacking a top-level permissions: block — adding one as defense-in-depth guards against a future job being added here without its own explicit scope (which would otherwise inherit the broader default token permissions).

🔒 Proposed defense-in-depth addition
 concurrency:
   group: internal-proposals-naming-${{ github.event.pull_request.number }}
   cancel-in-progress: true
+
+permissions:
+  contents: read
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: read
permissions:
contents: read
permissions:
contents: read
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/internal-proposals-naming.yml around lines 20 - 21, Update
the workflow’s top-level permissions configuration to add a restrictive
fallback, while preserving the existing job-level contents: read scope. Ensure
future jobs inherit minimal permissions unless they explicitly declare their own
narrower requirements.

Source: Linters/SAST tools

Comment thread AGENTS.md
Comment on lines +180 to +183
2. Follow `osac-workspace`'s own [Git Workflow](#git-workflow) instead of the
skill's docs-repo git steps: `git commit -s`, push to this repo's `fork`
remote, open the PR from `fork/<branch>` against `osac-workspace`'s
`origin/main` — not the `enhancement-proposals` repo's fork/origin (the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Keep duplicated Git workflow instructions compliant with AI-attribution policy.

Both workflow descriptions require signed commits but omit the required AI-assisted commit metadata.

  • AGENTS.md#L180-L183: document the Assisted-by: Claude Code <noreply@anthropic.com> trailer and prohibit AI Co-Authored-By trailers.
  • internal-proposals/README.md#L55-L57: mirror the same requirement so the README does not contradict the root workflow.

As per coding guidelines, AI-assisted commits must include a Red Hat Assisted-by or Generated-by trailer.

📍 Affects 2 files
  • AGENTS.md#L180-L183 (this comment)
  • internal-proposals/README.md#L55-L57
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AGENTS.md` around lines 180 - 183, Update the Git workflow instructions in
AGENTS.md at lines 180-183 and internal-proposals/README.md at lines 55-57 to
require the Assisted-by: Claude Code <noreply@anthropic.com> trailer on
AI-assisted commits and prohibit AI Co-Authored-By trailers; keep both
duplicated workflow descriptions consistent.

Source: Coding guidelines

Comment on lines +129 to +140
**Scoring model.** `prd-review`: 0–2 per dimension, `/10` total, PASS ≥7 with no zero on any dimension. `design-review`: 0–2 per dimension, `/8` total, PASS ≥5 with no zero on any dimension. Primary scoring is harness-native judges declared in `eval-prd-review.yaml`/`eval-design-review.yaml`:

```yaml
judges:
- name: rubric_scoring # deterministic check judge; regex-parses the skill's own rubric table
- name: critical_findings_recall # deterministic check judge; fuzzy-matches annotated critical findings
- name: qualitative_finding_quality # LLM prompt judge; only judge affected by model-family choice
thresholds:
rubric_scoring: { min_pass_rate: 1.0 }
critical_findings_recall: { min_pass_rate: 1.0 }
qualitative_finding_quality: { min_mean: 3.5 }
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | rg 'internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md|CLAUDE.md|AGENTS.md' || true

echo "== relevant design excerpts =="
file="internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md"
if [ -f "$file" ]; then
  wc -l "$file"
  sed -n '1,230p' "$file" | cat -n
fi

echo "== search related files =="
git ls-files | rg 'eval-(prd|design)-review|kubernetes|eval|judge|scoring|rubric|criteria|metrics|measurement' || true

Repository: osac-project/osac-workspace

Length of output: 38710


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== eval config files =="
for f in evals/review/eval-prd-review.yaml evals/review/eval-design-review.yaml evals/review/harness.lock; do
  if [ -f "$f" ]; then
    echo "--- $f ($(wc -l < "$f") lines) ---"
    cat -n "$f"
  fi
done

echo "== docs around eval runner/judges =="
for f in evals/review/README.md evals/review/docs/case-schema.md evals/review/docs/measurement-taxonomy.md internal-proposals/OSAC-959-agentic-sdlc-measurement/prd.md; do
  if [ -f "$f" ]; then
    echo "--- $f ($(wc -l < "$f") lines) ---"
    rg -n "qualitative_finding_quality|Rubert|score|mean|threshold|min_mean|judge|annotations|Cohen|κ" "$f" -C 3 || true
  fi
done

echo "== all repo references to qualitative anchor =="
rg -n "qualitative_finding_quality|min_mean: 3\.5|Rubert|Rubert|Cohen|minimum mean|min_mean|score scale|annotations.yaml" . -S || true

Repository: osac-project/osac-workspace

Length of output: 28381


🌐 Web query:

opendatahub-io agent-eval-harness v1.22.0 qualitative finding quality min_mean 3.5 score.py Rubert score scale

💡 Result:

In the opendatahub-io/agent-eval-harness framework (current as of v1.22.0), the min_mean parameter is a configuration setting used in the eval.yaml file to define regression thresholds for numeric LLM-based judges [1][2]. Specifically, min_mean: 3.5 sets a requirement that the average score for a designated quality metric must be at least 3.5 to pass the regression gate [1][3]. The harness utilizes a scoring system where LLM judges provide numeric scores [4][2]. While the framework's official documentation and templates do not strictly define a global scale for all judges, the frequent use of min_mean: 3.5 in examples implies a common 1–5 scale (often used in Likert-style qualitative evaluations) [1][3][4]. Users configure these thresholds under the thresholds section of their eval.yaml to detect regressions across evaluation runs [1][2]. Key technical points regarding this configuration: - Purpose: min_mean is specifically designed for numeric judges, such as LLM-as-a-judge, to establish an average performance floor [2]. - Regression Gating: If the calculated mean score for a specified judge falls below the min_mean value, the evaluation run can be flagged as a failure, preventing regressions [1][2]. - Other Thresholds: The framework also supports min_pass_rate (for boolean/deterministic checks) and min_win_rate (for pairwise comparisons) as alternative or complementary gating mechanisms [1][2]. The score.py file mentioned is a core component of the harness responsible for executing these scoring/judging logic and aggregating results, which are then compared against the thresholds defined in the configuration [5][1].

Citations:


🌐 Web query:

"opendatahub-io/agent-eval-harness" "v1.22.0" "score.py" "Rubert" "qualitative"

💡 Result:

In the opendatahub-io/agent-eval-harness framework, score.py is the primary scoring CLI tool used to execute evaluation judges and generate results [1][2]. It processes evaluation runs by loading test case outputs and applying judges configured in an eval.yaml file [1][3]. Regarding your specific query: 1. Rubert: There is no native or explicit reference to a Rubert model or algorithm within the core score.py scoring logic of the opendatahub-io/agent-eval-harness repository [1][4][3]. The framework is designed to be model-agnostic, allowing users to configure various LLM judges via prompt files or inline definitions [4][5]. 2. Qualitative Assessment: Qualitative scoring is a core function of the framework [4][5]. This is typically handled through LLM-as-a-judge configurations where a model is prompted to provide both a quantitative score (e.g., 1–5) and a qualitative rationale [1][3]. The score.py tool manages this by: - Forcing structured output (e.g., via tool calls) to ensure the model returns both a numerical value and a text-based justification [1]. - Supporting user-defined rubrics that instruct the LLM on how to evaluate qualitative aspects such as accuracy, completeness, and adherence to guidelines [4][5]. - Facilitating human review of these outputs, where judge scores and rationales are presented to allow for the collection of qualitative feedback and pattern analysis [4][5]. If you are seeing references to Rubert, it may be a custom modification, a specific judge prompt implementation within your local eval configuration, or an external dependency used in a downstream integration [6]. The framework's modular architecture allows developers to define custom judge modules or prompt files that could integrate specific models or qualitative frameworks [4][3]. [1][4][3]

Citations:


🌐 Web query:

"agent-eval-h Harness" "qualitative_finding_quality" "Rubert" "min_mean"

💡 Result:

The terms you mentioned relate to configuration settings within the opendatahub-io/agent-eval-harness framework, which is designed to evaluate AI agents and skills [1][2]. In this framework, qualitative_finding_quality typically refers to a specific metric or evaluator category used to assess the quality of outputs or qualitative findings generated by an agent [1][2]. The configuration allows for regression detection using defined thresholds [1][2]. Regarding the specific configuration values: - min_mean: This is a threshold setting representing the minimum average score required for a judge or metric to pass regression testing [1][3]. For example, a setting of min_mean: 3.5 implies that the average quality score must be at least 3.5 to avoid triggering a failure in the CI pipeline [1][2]. - Rubert: In the context of NLP, RuBERT is a well-known Russian-language BERT model developed by DeepPavlov [4]. While RuBERT is not a native component of the agent-eval-harness core (which typically relies on LLMs as judges), it is possible that in your specific environment, a fine-tuned version of RuBERT (often used for classification or scoring tasks, such as sentiment or poem evaluation) [5][6] is being utilized as a custom judge or model provider for specific evaluation tasks. Summary of usage in agent-eval-harness: The harness supports various judge types, including LLMs and custom checkers [3]. If you see Rubert referenced alongside min_mean in a config, it indicates that an evaluation is likely being performed by a model (possibly a fine-tuned RuBERT) where its output scores are being aggregated and checked against the min_mean threshold [1][3].

Citations:


Define the qualitative judge’s output scale and annotation mapping before gating on min_mean: 3.5.

The rubric scores are documented as 0–2, but qualitative_finding_quality uses a 3.5 mean gate without stating whether the judge scores 0–5 or another range, or how the LLM output is parsed and aligned with annotations/Cohen’s κ. Record that scale/mapping for the pinned judge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md` around lines
129 - 140, Document the pinned qualitative_finding_quality judge’s output scale
and how its LLM responses are parsed and mapped to annotations before applying
the min_mean: 3.5 threshold. Clarify the alignment used for annotation
comparison and Cohen’s κ, while keeping the existing deterministic judge
definitions and thresholds unchanged.

Comment on lines +169 to +171
### Security Considerations

The harness's LLM judge (`qualitative_finding_quality`) sends the EP Review Bot's already-posted PR comment plus the case's human-authored reference review to an external LLM API (`claude-sonnet-4-6` via the configured provider) for scoring. This is a strictly smaller data-exposure footprint than an earlier iteration of this design: there is no second skill-under-test execution sending full PRD/design document content to a second LLM call — only the bot's own already-public PR comment and the golden reference review are sent. This is the same data-exposure profile the EP Review Bot already has in production today for its half of the exchange — no new exposure is introduced. No credentials, secrets, or tenant data pass through this path.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate target =="
fd -a 'design\.md$' . | sed 's#^\./##' | rg "internal-proposals/.*/design\.md|OSAC-959-agentic-sdlc-measurement/design\.md" || true

echo "== target section =="
file="internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md"
if [ -f "$file" ]; then
  nl -ba "$file" | sed -n '140,190p'
else
  echo "target not found"
fi

echo "== references to reference-review/qualitative_finding_quality/claude-sonnet =="
rg -n "reference-review|qualitative_finding_quality|claude-sonnet|external LLM|LLM judge|Experiencer" .

Repository: osac-project/osac-workspace

Length of output: 329


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md"
if [ -f "$file" ]; then
  awk '{printf "%5d\t%s\n", NR, $0}' "$file" | sed -n '140,200p'
else
  echo "target not found"
fi

echo "== references to reference-review/qualitative_finding_quality/claude-sonnet =="
rg -n "reference-review|qualitative_finding_quality|claude-sonnet|external LLM|LLM judge|Experiencer" .

Repository: osac-project/osac-workspace

Length of output: 23664


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== referenced files =="
for f in evals/review/eval-prd-review.yaml evals/review/eval-design-review.yaml evals/review/docs/case-schema.md internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    awk '{printf "%5d\t%s\n", NR, $0}' "$f" | sed -n '1,120p'
  else
    echo "missing $f"
  fi
done

echo "== find source references to reference-review content =="
rg -n "reference_review|reference-review|load_case_record|quality_finding|finding_quality|prompt|judge" evals internal-proposals/OSAC-959-agg -S || true

Repository: osac-project/osac-workspace

Length of output: 28114


Do not claim that this introduces “no new exposure.”

The qualitative_finding_quality path adds reference-review.md content to the LLM judge input. Define classification/redaction requirements, provider retention and access guarantees, and an explicit exclusion rule for content not approved for external LLM processing before saying the exposure profile is the same.

Suggested wording change
-This is the same data-exposure profile the EP Review Bot already has in production today for its half of the exchange — no new exposure is introduced.
+Reference reviews are additional data sent to the configured external LLM provider. Before scoring, classify and sanitize them, verify provider retention/access controls, and exclude any sensitive content that is not approved for external processing.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Security Considerations
The harness's LLM judge (`qualitative_finding_quality`) sends the EP Review Bot's already-posted PR comment plus the case's human-authored reference review to an external LLM API (`claude-sonnet-4-6` via the configured provider) for scoring. This is a strictly smaller data-exposure footprint than an earlier iteration of this design: there is no second skill-under-test execution sending full PRD/design document content to a second LLM call — only the bot's own already-public PR comment and the golden reference review are sent. This is the same data-exposure profile the EP Review Bot already has in production today for its half of the exchange — no new exposure is introduced. No credentials, secrets, or tenant data pass through this path.
### Security Considerations
The harness's LLM judge (`qualitative_finding_quality`) sends the EP Review Bot's already-posted PR comment plus the case's human-authored reference review to an external LLM API (`claude-sonnet-4-6` via the configured provider) for scoring. This is a strictly smaller data-exposure footprint than an earlier iteration of this design: there is no second skill-under-test execution sending full PRD/design document content to a second LLM call — only the bot's own already-public PR comment and the golden reference review are sent. Reference reviews are additional data sent to the configured external LLM provider. Before scoring, classify and sanitize them, verify provider retention/access controls, and exclude any sensitive content that is not approved for external processing. No credentials, secrets, or tenant data pass through this path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md` around lines
169 - 171, Update the Security Considerations section describing
qualitative_finding_quality to remove the claim that no new exposure is
introduced. Specify classification and redaction requirements for
reference-review.md, document provider retention and access guarantees, and
explicitly exclude content not approved for external LLM processing before
characterizing the resulting exposure profile.

Comment on lines +49 to +50
- No numeric target thresholds exist yet for MTTR improvement, RCA accuracy, or velocity change — the framework establishes baselines first; specific targets are not yet defined. [Clarify: Remaining Gaps]
- End-to-end validation against real use cases proceeds in phases rather than all at once: an initial planning-review golden set, followed later by real bug-fix outcome validation once bug-fix evaluation is integrated — full validation is not available from day one. Each phase is complete when its golden dataset and a baseline judge/human agreement report both exist and are reproducible, giving reviewers a concrete, inspectable checkpoint rather than an open-ended validation effort. [Jira: OSAC-959]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make phase completion criteria phase-specific.

This assumption requires every phase to produce a golden dataset and judge/human agreement report, but internal-proposals/OSAC-959-agentic-sdlc-measurement/design.md defines those artifacts only for Phases 1-2. Phases 3-4 instead deliver operational metrics, Org Pulse trends, and reports, so the current wording creates an impossible or ambiguous Definition of Done.

Restrict the calibration requirement to Phases 1-2 and define separate acceptance criteria for later phases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal-proposals/OSAC-959-agentic-sdlc-measurement/prd.md` around lines 49
- 50, Update the phased validation completion criteria in the referenced PRD
section to require a golden dataset and reproducible judge/human agreement
report only for Phases 1–2. Define phase-appropriate acceptance criteria for
Phases 3–4 based on their operational metrics, Org Pulse trends, and reporting
deliverables, avoiding a universal calibration requirement.

Comment on lines +45 to +48
```
internal-proposals/<jira-key>-<feature-slug>/prd.md
internal-proposals/<jira-key>-<feature-slug>/design.md
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a language identifier to the example block.

Markdownlint reports MD040 at Line 45. Use a language such as text so the README passes the documented lint checks.

🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 45-45: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal-proposals/README.md` around lines 45 - 48, Update the Markdown code
block around the internal-proposals path examples in README.md to include the
text language identifier, preserving the example contents and formatting so
Markdownlint rule MD040 passes.

Source: Linters/SAST tools

Comment on lines +87 to +94
def is_grandfathered(
path: str, base_sha: str | None, live_base_ref: str | None
) -> bool:
if base_sha is not None and path_exists_at_ref(base_sha, path):
return True
if live_base_ref is not None and path_exists_at_ref(live_base_ref, path):
return True
return False

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: return the boolean condition directly.

is_grandfathered can be simplified to a single return expression instead of two early return Trues + a fallback.

♻️ Proposed simplification
 def is_grandfathered(
     path: str, base_sha: str | None, live_base_ref: str | None
 ) -> bool:
-    if base_sha is not None and path_exists_at_ref(base_sha, path):
-        return True
-    if live_base_ref is not None and path_exists_at_ref(live_base_ref, path):
-        return True
-    return False
+    return (
+        (base_sha is not None and path_exists_at_ref(base_sha, path))
+        or (live_base_ref is not None and path_exists_at_ref(live_base_ref, path))
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def is_grandfathered(
path: str, base_sha: str | None, live_base_ref: str | None
) -> bool:
if base_sha is not None and path_exists_at_ref(base_sha, path):
return True
if live_base_ref is not None and path_exists_at_ref(live_base_ref, path):
return True
return False
def is_grandfathered(
path: str, base_sha: str | None, live_base_ref: str | None
) -> bool:
return (
(base_sha is not None and path_exists_at_ref(base_sha, path))
or (live_base_ref is not None and path_exists_at_ref(live_base_ref, path))
)
🧰 Tools
🪛 Ruff (0.15.21)

[warning] 92-94: Return the condition directly

Inline condition

(SIM103)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/check_internal_proposals_naming.py` around lines 87 - 94, Return the
combined grandfathering condition directly from is_grandfathered, preserving the
existing checks that require a non-None base_sha or live_base_ref before calling
path_exists_at_ref.

Source: Linters/SAST tools

@tchughesiv
tchughesiv marked this pull request as draft July 27, 2026 18:01
@tchughesiv

tchughesiv commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Closing without merging.

This started from a real need — Eran Cohen's Slack request to flag internal-tooling PRs (like OSAC-959, agentic-SDLC measurement) as "not an OSAC feature" before they hit the EP Review Bot's tenant-facing rubric. This PR built out a durable answer: an internal-proposals/ directory with its own naming CI, review-process docs, a prd-review/design-review rubric caveat, and a Jira-label-based routing signal + publish-time override in AGENTS.md to keep /prd:publish//design:publish from misrouting internal-only work into enhancement-proposals.

Validation (running prd-review/design-review against both a real OSAC feature and OSAC-959 side by side, then dry-running the actual /prd:ingest/prd:publish mechanics against a stale config.json) confirmed the review-skill treatment works as intended, but also surfaced that making the routing safe end-to-end would require a project-level override (.workflows/) layered onto .ai-workflows/{prd,design}/skills/{ingest,publish}.md — shared machinery whose whole job is facilitating the tenant-facing enhancement-proposals flow. Adding parallel internal-routing behavior there is more process/tooling surface than this problem warrants, and not a risk worth taking on that shared path.

Going a lighter route instead: for ad-hoc internal engineering docs like OSAC-959, skip building workspace-native process around them and just get them reviewed directly (e.g., Google Docs) — no bot, no rubric, no routing logic needed, because the doc never enters the enhancement-proposals-facing pipeline at all.

Assisted-by: Claude Code noreply@anthropic.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants