Skip to content

Add deterministic experiment adjudication to analysis - #55039

Merged
pelikhan merged 7 commits into
mainfrom
copilot/core-experiment-adjudication
Aug 23, 2026
Merged

Add deterministic experiment adjudication to analysis#55039
pelikhan merged 7 commits into
mainfrom
copilot/core-experiment-adjudication

Conversation

Copilot AI commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

gh aw experiments analyze previously exposed readiness and statistics but left promotion decisions to reporting agents. This adds a deterministic, machine-readable adjudication contract without mutating experiments or rerunning analysis.

Changes

  • Core contract

    • Adds EXTEND, PROMOTE, REJECT, and INCONCLUSIVE.
    • Adds stable reason codes and explicit COLLECTING / READY readiness.
    • Preserves the legacy recommendation field.
  • Decision policy

    • Enforces minimum samples before adjudication.
    • Normalizes effects by metric direction.
    • Applies practical-effect and confidence thresholds.
    • Supports existing frequentist and Bayesian evidence.
    • Gives mandatory guardrail failures precedence.
    • Returns INCONCLUSIVE for unsupported multi-variant decisions.
  • Reporting

    • Updates the daily report to consume core decisions rather than duplicate statistical and guardrail rules.
    • Preserves sparse-interaction checks as a separate reporting safety hold.
  • Documentation and coverage

    • Defines assignment, observation, analysis, readiness, decision, and promotion as separate stages.
    • Adds decision, JSON, CLI rendering, guardrail, and grader-backed integration coverage.
{
  "readiness": "READY",
  "decision": "PROMOTE",
  "reason_code": "candidate_improved",
  "control": "control",
  "candidate": "optimized"
}

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 8.22 AIC · ⌖ 8.21 AIC · ⊞ 9.5K ·
Comment /souschef to run again

Copilot AI and others added 3 commits August 23, 2026 07:22
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…nt-adjudication

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Add deterministic core experiment adjudication Add deterministic experiment adjudication to analysis Aug 23, 2026
Copilot AI requested a review from pelikhan August 23, 2026 07:36
@pelikhan
pelikhan marked this pull request as ready for review August 23, 2026 07:39
Copilot AI balanced review requested due to automatic review settings August 23, 2026 07:39
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Reviewed PR #55039 for over-engineering. The Go changes replace bare string constants with proper named types (ExperimentDecision, ExperimentDecisionReasonCode, ExperimentReadiness), which is idiomatic Go and reduces error-proneness rather than adding complexity. The workflow markdown changes remove duplicated statistical/guardrail logic from the reporting workflow in favor of consuming the new deterministic core decision, netting fewer lines overall. No unnecessary abstractions, speculative flexibility, or hand-rolled stdlib equivalents found. Lean already. Ship.

Generated by Ponytail Reviewer for #55039

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions github-actions Bot mentioned this pull request Aug 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-23T00:00:00Z
review_event: REQUEST_CHANGES
top_themes:
  - cli output hides new readiness state
  - machine contract updated without equivalent human-facing rendering
files_reviewed:
  - .github/aw/experiments.md
  - .github/workflows/daily-experiment-report.md
  - docs/src/content/docs/experimental/experiments-specification.md
  - docs/src/content/docs/experimental/experiments.md
  - pkg/cli/experiments_analyze_statistics.go
  - pkg/cli/experiments_decision.go
  - pkg/cli/experiments_decision_test.go
  - pkg/cli/experiments_grader_observations_test.go
  - pkg/cli/experiments_render_test.go
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 29.6 AIC · ⌖ 6.91 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Request changes

The deterministic decision layer is a good direction, but the CLI path still hides one of the new core states from humans.

Blocking theme
  • The new readiness contract is serialized in JSON and documented heavily, but the stderr renderer still only surfaces the legacy recommendation string. That makes the operator-facing CLI output lag behind the machine contract and obscures the new READY vs COLLECTING distinction this PR is trying to establish.

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 29.6 AIC · ⌖ 6.91 AIC · ⊞ 7K
Comment /review to run again

Comments that could not be inline-anchored

pkg/cli/experiments_analyze_statistics.go:612

This change adds a new readiness field to the JSON contract, but the CLI stderr rendering still only prints the legacy Recommendation: line. That leaves humans unable to tell READY + INCONCLUSIVE apart from COLLECTING + EXTEND, which is exactly the distinction this PR is introducing and documenting.

<details><summary>💡 Why this matters and how to fix it</summary>

Right now printOneExperimentAnalysis() prints variant progress, the old recommendation, and then the decision. For a rea…

@github-actions

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate — ADR Verified

ADR reviewed: ADR-54978: Deterministic Experiment Decision Engine — implementation aligns with the stated decision. Great work! 🏗️

📋 Verification Summary

The ADR describes introducing a pure, stateless DecideExperiment(ExperimentAnalysis) ExperimentDecisionResult function emitting one of four decisions (EXTEND, PROMOTE, REJECT, INCONCLUSIVE) with stable reason codes, embedded in the existing analysis pipeline, with no I/O or state mutation.

The PR implementation matches on all key points:

  • Typed decision and reason-code constants (ExperimentDecision, ExperimentDecisionReasonCode) are exported and replace the prior unexported string constants, fulfilling the stable machine-readable contract described in the ADR.
  • DecideExperiment is a pure function with no I/O: it takes ExperimentAnalysis and returns ExperimentDecisionResult — consistent with the ADR's "no I/O, does not re-run statistical tests, does not mutate experiment state" constraint.
  • JSON contract (decision, reason_code, decision_policy, decision_guardrails) is present via struct tags on ExperimentDecisionResult, embedded in ExperimentAnalysis — consistent with the ADR's stated embedding approach.
  • Readiness field (COLLECTING/READY) is added separately from decision, formalizing what the ADR described as the pre-analysis readiness gate distinct from the post-analysis verdict.
  • Daily report workflow is updated to consume core decisions rather than re-computing statistical tests — consistent with ADR Positive consequence rejig docs #1 (stable contract for downstream tooling).
  • Unit and integration tests cover decision correctness, JSON output, CLI rendering, and grader-backed end-to-end decisions — consistent with the ADR's assertion that the pure function is independently unit-testable.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 · 65.7 AIC · ⌖ 31.2 AIC · ⊞ 9.5K ·
Comment /review to run again

@github-actions

Copy link
Copy Markdown
Contributor

Test Quality Sentinel 🧪

Score: 86/100 ✅ Excellent

Summary

This PR adds deterministic experiment adjudication logic with comprehensive test coverage. 4 test files changed, introducing 3 new behavioral tests and enhancing 2 existing tests with new assertions that validate the new readiness and decision contracts.

Coverage Breakdown

Category Count Ratio
Total test functions (new + modified) 5
Design/behavioral tests 4 80% ✅
Implementation tests 1 20%
Tests with edge cases 4 80% ✅

Test-to-Production Ratio

All modified files show healthy ratios (below 2:1 threshold):

File Test Lines Prod Lines Ratio Status
experiments_analyze_statistics_test.go +2 +16 0.125:1 ✅ Healthy
experiments_decision_test.go +16 +45 0.355:1 ✅ Healthy
experiments_grader_observations_test.go +44 n/a NEW ✅ New test file
experiments_render_test.go +20 n/a NEW ✅ New test file

Detailed Test Classification

Expand for per-test review

1. experiments_analyze_statistics_test.go (2 assertions added)

Test: TestComputeExperimentAnalysis

  • Change: Added assertion assert.Equal(t, ExperimentReadinessReady, a.Readiness, "count >= min_samples → READY")
  • Type: Existing test enhanced with new behavioral contract
  • Classification: design_test / high_value / behavioral_contract
  • Rationale: Validates that the new explicit Readiness field (new to this PR) correctly reflects "READY" state when samples meet minimum.

Test: TestExperimentAnalysisJSONOutput

  • Change: Added assertion assert.Equal(t, "COLLECTING", result["readiness"], "readiness field")
  • Type: Existing test enhanced to validate JSON schema
  • Classification: design_test / high_value / behavioral_contract
  • Rationale: Ensures JSON output includes the new readiness field as a machine-readable contract.

2. experiments_decision_test.go (14 table-driven scenarios)

Test: TestDecideExperiment (table-driven)

  • Type: Refactored (strings → typed constants); no logic changes

  • Structure: 14 test scenarios covering the complete decision matrix

  • Scenarios:

    1. Below min samples → EXTEND
    2. Max direction material improvement → PROMOTE
    3. Min direction material improvement (normalized) → PROMOTE
    4. Max direction material regression → REJECT
    5. Min direction material regression → REJECT
    6. Significant tiny effect (below practical threshold) → INCONCLUSIVE ✅ (edge case)
    7. Large effect without evidence → INCONCLUSIVE ✅ (edge case)
    8. Failed guardrail → REJECT (precedence test) ✅
    9. Missing guardrail → EXTEND
    10. Passed guardrail → PROMOTE
    11. Bayesian strong evidence → PROMOTE
    12. Bayesian weak evidence → INCONCLUSIVE ✅ (edge case)
    13. Multi-variant unsupported (3 variants) → INCONCLUSIVE ✅ (edge case)
    14. Multi-variant undersampled (3 variants, 1 below min) → INCONCLUSIVE ✅ (edge case)
  • Assertions per scenario:

    • assert.Equal(t, expected_decision, result.Decision)
    • assert.Equal(t, expected_reason, result.ReasonCode)
    • assert.NotEmpty(t, result.DecisionReason) — descriptive reason always present ✅
    • Conditional: require.NotNil(t, result.Effect) and assert.InDelta(normalized_effect) when effect expected ✅
  • Classification: design_test / high_value / behavioral_contract

  • Quality signals:

    • ✅ Comprehensive decision-matrix coverage
    • ✅ Direction normalization tested (max/min with values of opposite sign)
    • ✅ Guardrail precedence validated
    • ✅ Bayesian and frequentist paths both tested
    • ✅ Multi-variant rejection enforced
    • ✅ All assertions include descriptive context

3. experiments_grader_observations_test.go - NEW TEST

Test: TestComputeGraderBackedExperimentDecision

  • Type: New integration test (46 lines)

  • What it validates: End-to-end flow: grader observations → analysis computation → decision logic

  • Setup:

    • Control variant: 3 observations at value 0.5
    • Candidate variant: 3 observations at value 0.8 (40% improvement)
    • Config: min_samples=3, minimum_effect=0.1, t_test analysis
  • Assertions:

    • assert.Equal(t, ExperimentReadinessReady, analysis.Readiness) — meets sample threshold ✅
    • assert.Equal(t, ExperimentDecisionPromote, analysis.Decision) — material improvement ✅
    • assert.Equal(t, ExperimentDecisionReasonCandidateImproved, analysis.ReasonCode) — reason code ✅
    • assert.Equal(t, "control", analysis.Control) — variant labels correct ✅
    • assert.Equal(t, "candidate", analysis.Candidate)
    • require.NotNil(t, analysis.Effect) — effect computed ✅
    • assert.InDelta(t, 0.3, analysis.Effect.NormalizedAbsolute, 0.0001) — normalized effect correct ✅
    • assert.Equal(t, map[string]int{"control": 3, "candidate": 3}, analysis.Samples) — sample tracking ✅
  • Classification: design_test / high_value / behavioral_contract

  • Why high value: Integrates grader observations (new in this PR) with decision logic; validates that the decision deterministically follows from observations.


4. experiments_render_test.go - NEW TEST

Test: TestPrintExperimentDetailsDecision

  • Type: New test (20 lines)

  • What it validates: CLI output rendering of decision results

  • Setup: Creates ExperimentDetails with:

    • Readiness: READY
    • Decision: PROMOTE
    • ReasonCode: candidate_improved
    • DecisionReason: "candidate materially improves the primary metric"
  • Assertions:

    • assert.Contains(t, output, "Decision : PROMOTE candidate") — formatted decision line ✅
    • assert.Contains(t, output, "candidate materially improves the primary metric (candidate_improved)") — reason + code ✅
  • Classification: implementation_test / medium_value / behavioral_contract

  • Rationale: Validates user-visible CLI output format. Implementation detail (output formatting) but important for UX contract.

Violations & Red Flags

No violations detected

  • ✅ No Go mock libraries (gomock, testify/mock) — uses only testify/assert and testify/require (acceptable)
  • ✅ All test files have (go/redacted):build !integration tag on line 1
  • ✅ All assertions include descriptive failure context (named parameters or assertion messages)
  • ✅ No duplicated test patterns (14 table rows test distinct decision paths, no trivial constant variations)
  • ✅ All tests contain assertions (no setup-only or no-op tests)
  • ✅ Test inflation healthy (all modified files ≤ 0.355:1 test:prod ratio)
  • ✅ Edge cases present: guardrail failure precedence, Bayesian variants, metric direction normalization, boundary conditions

Scoring Details

design_tests / total_tests:        4/5 = 80%  →  (0.80 × 40 points) = 32.0
edge_case_coverage / total_tests:  4/5 = 80%  →  (0.80 × 30 points) = 24.0
no_duplicates:                     0 clusters → (20 - 0×5 points)     = 20.0
inflation_ratio ≤ 2:1:            ALL pass   →                      = 10.0
                                                         TOTAL SCORE = 86/100 ✅

Thresholds:

  • >=80: Excellent ✅
  • 60-79: Acceptable
  • 40-59: Needs improvement
  • <40: Poor

Pass criteria:

  • ✅ Implementation tests ≤ 30%: 20% (1/5) — Pass
  • ✅ No coding-guideline violations — Pass
  • ✅ No hard violations — Pass

Recommendations

This is a well-tested PR. The addition of 3 new behavioral tests and 2 enhanced assertions provides solid coverage for the new deterministic decision logic. The table-driven test in experiments_decision_test.go is especially strong, covering the complete decision matrix including edge cases and guardrail precedence.

No changes requested. ✅

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 25.3 AIC · ⌖ 7.82 AIC · ⊞ 8.3K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 86/100. 80% design/behavioral tests (threshold: ≥80%), 20% implementation tests (threshold: ≤30%). No coding-guideline violations.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /codebase-design and /tdd — requesting changes on two issues.

📋 Key Themes & Highlights

Key Themes

  • Partial typing: ExperimentDecision and ExperimentDecisionReasonCode are now typed constants, but GuardrailStatus.Status remains an untyped string. The PR's stated goal is a stable machine-readable contract — guardrail status codes should follow the same pattern to complete that contract.
  • Degenerate test data: TestComputeGraderBackedExperimentDecision uses constant observation values (0.5 / 0.8), producing zero-variance samples. The test exercises an edge-case guard rather than the primary t-test code path.

Positive Highlights

  • ✅ Clean promotion of decision and reason-code strings to typed constants — excellent API hygiene.
  • ExperimentReadiness enum (COLLECTING / READY) gives consumers a stable gate without requiring p-value parsing.
  • report_action vs core_decision separation in the daily-report workflow correctly isolates the interaction safety hold from the core adjudication — well-designed boundary.
  • ✅ Good test coverage added for JSON output, CLI rendering, and grader-backed decision paths.
  • INCONCLUSIVE preserved as a distinct outcome from REJECT — important for downstream consumers.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 59.5 AIC · ⌖ 11.3 AIC · ⊞ 7.6K
Comment /matt to run again

Comment thread pkg/cli/experiments_decision.go Outdated
func pendingGuardrailDecision(guardrails []GuardrailStatus) (string, string, bool) {
func pendingGuardrailDecision(guardrails []GuardrailStatus) (ExperimentDecisionReasonCode, string, bool) {
for _, guardrail := range guardrails {
if guardrail.Status == "insufficient_observations" || guardrail.Status == "missing" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/codebase-design] GuardrailStatus.Status comparisons still use raw string literals while the surrounding code was upgraded to typed constants — this is the main consistency gap the PR leaves unresolved.

💡 Suggested fix

Introduce a typed GuardrailStatusCode string type (parallel to ExperimentDecisionReasonCode) and replace the raw comparisons:

type GuardrailStatusCode string

const (
    GuardrailStatusInsufficientObservations GuardrailStatusCode = "insufficient_observations"
    GuardrailStatusMissing                  GuardrailStatusCode = "missing"
    GuardrailStatusUnsupported              GuardrailStatusCode = "unsupported"
    GuardrailStatusFail                     GuardrailStatusCode = "fail"
    GuardrailStatusPass                     GuardrailStatusCode = "pass"
)

Then GuardrailStatus.Status becomes GuardrailStatusCode, and pendingGuardrailDecision/firstFailedGuardrail compare against the constants. The PR explicitly states its goal is a "stable machine-readable" contract — leaving guardrail status as untyped strings undermines that.

@copilot please address this.

Direction: "higher_is_better",
ByVariant: map[string][]GraderMetricObservation{
"control": {
{RunID: "1", Variant: "control", Value: 0.5},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] All observations in the new grader-backed decision test use constant values (0.5 / 0.8), producing zero variance per variant. A t-test on zero-variance data yields a degenerate result — the test passes incidentally via an edge-case guard, not by exercising the normal statistical path.

💡 What to do

Add a small amount of variance so the test exercises the real t-test code path:

"control": {
    {RunID: "1", Variant: "control", Value: 0.48},
    {RunID: "2", Variant: "control", Value: 0.50},
    {RunID: "3", Variant: "control", Value: 0.52},
},
"candidate": {
    {RunID: "4", Variant: "candidate", Value: 0.78},
    {RunID: "5", Variant: "candidate", Value: 0.80},
    {RunID: "6", Variant: "candidate", Value: 0.82},
},

Also add a separate, intentional zero-variance case that asserts the expected fallback behaviour explicitly.

@copilot please address this.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds deterministic experiment adjudication while preserving legacy recommendations.

Changes:

  • Introduces typed readiness, decisions, and reason codes.
  • Updates reporting to consume canonical decisions.
  • Expands documentation and test coverage.
Show a summary per file
File Description
pkg/cli/experiments_decision.go Defines and applies decision contracts.
pkg/cli/experiments_decision_test.go Tests adjudication scenarios.
pkg/cli/experiments_analyze_statistics.go Adds readiness and typed rendering.
pkg/cli/experiments_analyze_statistics_test.go Verifies readiness JSON output.
pkg/cli/experiments_grader_observations_test.go Tests grader-backed promotion.
pkg/cli/experiments_render_test.go Tests decision rendering.
docs/src/content/docs/experimental/experiments.md Documents decision stages and API.
docs/src/content/docs/experimental/experiments-specification.md Extends normative decision requirements.
.github/aw/experiments.md Updates guardrail guidance.
.github/workflows/daily-experiment-report.md Consumes canonical core decisions.
.github/workflows/daily-experiment-report.lock.yml Regenerates the compiled workflow.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Suppressed comments (2)

.github/workflows/daily-experiment-report.md:584

  • A sparse-interaction hold changes report_action to EXTEND, yet this rule still applies the additive experiment:concluded label for the underlying PROMOTE. Because labels are not automatically removed, the issue is marked concluded while the report explicitly requests continued collection. Exclude held promotions from this label.
| `experiment:concluded`         | Core `decision` is `PROMOTE` or `REJECT`                                      |

docs/src/content/docs/experimental/experiments-specification.md:753

  • READY can also pair with EXTEND: after the primary sample gate passes, missing/unsupported guardrails, an absent comparison, or an uncomputable analysis all produce EXTEND. Omitting that state makes the normative contract contradict both R-STAT-016 and DecideExperiment.
**R-STAT-018**: Structured analysis output MUST expose readiness independently from decision.
Readiness is `COLLECTING` until every variant reaches `min_samples`, then `READY`. `READY` does not
imply `PROMOTE`; a ready experiment may be `PROMOTE`, `REJECT`, or `INCONCLUSIVE`. The legacy
`recommendation` field MAY remain `EXTEND` / `READY_FOR_ANALYSIS` for backward compatibility.
  • Files reviewed: 11/11 changed files
  • Comments generated: 4
  • Review effort level: Balanced

Comment on lines 98 to +100
comparison := decisionComparison(analysis.Comparisons)
if comparison == nil {
return result.withDecision(experimentDecisionExtend, "insufficient_observations",
return result.withDecision(ExperimentDecisionExtend, ExperimentDecisionReasonInsufficientObservations,
- `<metric_name>` expected `<threshold>`, got `<actual_value>` for variant `<variant>`

Recommendation: **ABANDON** — investigate immediately.
Decision: **REJECT** (`guardrail_failed`) — investigate immediately.
Comment thread .github/aw/experiments.md Outdated
- `start_date:` / `end_date:` — ISO-8601 `YYYY-MM-DD`. Outside this window, control variant is returned and counters do not increment.
- `description:`, `metric:`, `issue:`, `hypothesis:` — governance metadata (no runtime effect).
- `guardrail_metrics:` — array; if any guardrail fails for any variant, experiment is auto-abandoned. Each entry:
- `guardrail_metrics:` — array; if any guardrail fails for any variant, the deterministic core decision is `REJECT`. Each entry:
Comment on lines +683 to +686
**R-STAT-007**: Reporting tools **MUST NOT** issue a PROMOTE decision for any variant
until all variants in the experiment have accumulated at least `min_samples` runs (or 20 if
`min_samples` is not declared). When any variant is below threshold, the recommendation
**MUST** be EXTEND.
`min_samples` is not declared). When any variant is below threshold, readiness **MUST** be
`COLLECTING` and the decision **MUST** be `EXTEND`.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review: Add deterministic experiment adjudication to analysis

This is a clean, well-scoped PR that makes two cohesive improvements:

1. Type-safe decision constants (Go)

Replacing untyped string constants (experimentDecisionExtend, etc.) with proper exported types (ExperimentDecision, ExperimentDecisionReasonCode) is a solid improvement. It catches mismatches at compile time and makes API consumers easier to read. The refactor is complete — no leftover raw string literals found.

2. Decoupled Readiness from Decision

Adding ExperimentReadiness as a separate field (COLLECTING/READY) distinct from decision correctly models R-STAT-018: a ready experiment can still be INCONCLUSIVE. The initialization to ExperimentReadinessCollecting in newExperimentAnalysis and the two-branch update in applyExperimentReadiness are correct and consistent.

Workflow prompt changes

The prompt correctly:

  • Delegates canonical decisions to gh aw experiments analyze rather than re-deriving them from p-values
  • Preserves the interaction safety hold as a presentation layer concern (report_action: EXTEND) without mutating core_decision
  • Distinguishes INCONCLUSIVE from REJECT throughout

Test coverage

New tests in experiments_grader_observations_test.go and experiments_render_test.go cover the grader-backed decision path and the decision rendering path with typed constants. The JSON output test for readiness: "COLLECTING" is a good regression guard.

No blocking issues found. ✅

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 49.7 AIC · ⌖ 9.08 AIC · ⊞ 6.2K

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

pr-sous-chef
@copilot this PR is close, but it still has open reviewer requests blocking maintainer investigation.

Please address the newest blocking review feedback first:

After updating the branch, refresh with the latest base changes if GitHub offers it, rerun any needed checks, and then run the pr-finisher skill to bring this PR to a maintainer-ready state.

Run: https://github.com/github/gh-aw/actions/runs/32627776751

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 8.22 AIC · ⌖ 8.21 AIC · ⊞ 9.5K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

pr-sous-chef
@copilot this PR is close, but it still has open reviewer requests blocking maintainer investigation.
...

Addressed the newest blocking reviews in cd85cbb: CLI output now renders readiness, guardrail statuses use typed constants, and grader-backed tests cover normal variance plus the explicit zero-variance fallback. The branch already contains the latest base commit; formatting, standalone lint, full Go tests, targeted tests, and workflow recompilation pass.

@github-actions

Copy link
Copy Markdown
Contributor

Triage: pr-type:feature · pr-risk:medium · Score: 62/100

Impact Urgency Quality Total
28 16 18 62

Recommended action: fast_track

Adds deterministic experiment-adjudication logic across analysis/decision code with docs and lock-file regen; 11 files, +324/-198. Review history shows mixed signals: 2× CHANGES_REQUESTED and 3× APPROVED from github-actions[bot], plus a COMMENTED review from copilot-pull-request-reviewer[bot] — verify latest requested changes were addressed before merge. CI status unknown (no check runs returned).

Generated by 🔧 PR Triage Agent · auto · 49.7 AIC · ⌖ 4.44 AIC · ⊞ 8.4K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

pr-sous-chef
@copilot this PR is close, but it still has open reviewer requests blocking maintainer investigation.

Please address the newest blocking review feedback first:

After updating the branch, refresh with the latest base changes if GitHub offers it, rerun any needed checks, and then run the pr-finisher skill to bring this PR to a maintainer-ready state.

Run: https://github.com/github/gh-aw/actions/runs/32642933803

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 17.1 AIC · ⌖ 8.25 AIC · ⊞ 7.1K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

pr-sous-chef
@copilot this PR is close, but it still has open reviewer requests blocking maintainer investigation.
...

Addressed the newest blocking feedback in 8577ca9: guardrails now adjudicate before primary comparison lookup with no-comparison regression coverage, workflow notifications render the canonical decision tuple, and readiness documentation uses usable observations. Targeted tests and workflow compilation pass; the aggregate validation target only reports unrelated pre-existing custom-lint debt.

@pelikhan

Copy link
Copy Markdown
Collaborator

…nt-adjudication

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main
Fix https://github.com/github/gh-aw/actions/runs/32643779797/job/97207620585#step:4:1

Merged latest main in d3dcdc1. The merge includes the regenerated agentic-workflows skill entry that caused the linked CI failure; the exact failing test and make test-impacted-go now pass.

@pelikhan
pelikhan merged commit 7b2adec into main Aug 23, 2026
34 checks passed
@pelikhan
pelikhan deleted the copilot/core-experiment-adjudication branch August 23, 2026 15:15
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.

4 participants