Skip to content

Add dedicated outcome evaluators for replace_label and close operations; fill spec/compliance gaps#44798

Merged
pelikhan merged 11 commits into
mainfrom
copilot/spdd-daily-spec-work-plan-2026-07-10
Jul 11, 2026
Merged

Add dedicated outcome evaluators for replace_label and close operations; fill spec/compliance gaps#44798
pelikhan merged 11 commits into
mainfrom
copilot/spdd-daily-spec-work-plan-2026-07-10

Conversation

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Outcome evaluation still had generic fallback behavior in a few high-signal paths, most notably replace_label in Go and close_issue / close_pull_request in the JS runtime. This change replaces those gaps with type-specific evaluation logic and updates the related specs/compliance fixtures to reflect the current implementation surface.

  • Outcome evaluation

    • Add Go evalReplaceLabel and route replace_label away from evalGenericSticky
    • Reuse retained-state evaluation for label replacement by comparing persisted before_state.labels / after_state.labels against current issue state
    • Add JS evaluators for:
      • close_issue
      • close_pull_request
    • Fix JS add_labels evaluation to use persisted number / repo metadata, not just URL-derived targets
  • Targeted coverage

    • Add Go coverage for retained replace_label outcomes
    • Add JS coverage for:
      • add_labels with persisted metadata
      • add_labels missing-number error path
      • close_issue
      • close_pull_request
  • Spec sync

    • Update specs/safe-output-outcome-evaluation.md to reflect:
      • replace_label as dedicated/partial in Go
      • JS-specific evaluator status for add_labels
      • implemented JS paths for close_issue and close_pull_request
    • Add RL-002 allowlist fixture and register it in replace-label compliance docs/spec references
    • Add intent-attribution compliance fixture README and requested safeguards/sync notes
    • Expand OTel §17 with concrete span-attribute conformance cases
func evalReplaceLabel(item CreatedItemReport, repoOverride string) OutcomeReport {
	return evalRetainedUpdate(item, repoOverride, "label replacement", extractCurrentIssueUpdateState, false)
}

Copilot AI linked an issue Jul 10, 2026 that may be closed by this pull request
9 tasks
Copilot AI and others added 7 commits July 10, 2026 17:00
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Resolve gaps in daily SPDD spec work plan for 2026-07-10 Add dedicated outcome evaluators for replace_label and close operations; fill spec/compliance gaps Jul 10, 2026
Copilot AI requested a review from pelikhan July 10, 2026 17:18
@pelikhan pelikhan marked this pull request as ready for review July 10, 2026 18:25
Copilot AI review requested due to automatic review settings July 10, 2026 18:25

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 type-specific outcome evaluation and aligns related specifications and compliance fixtures.

Changes:

  • Adds Go replace_label and JavaScript close evaluators.
  • Expands targeted evaluator tests.
  • Updates outcome, compliance, governance, and OTel specifications.
Show a summary per file
File Description
specs/safe-output-outcome-evaluation.md Updates evaluator status matrix.
specs/replace-label-spec.md References compliance fixtures.
specs/replace-label-compliance/rl-002-allowlist-enforcement.yaml Adds allowlist scenarios.
specs/replace-label-compliance/README.md Registers RL-002 coverage.
specs/otel-observability-spec.md Adds span-attribute cases.
specs/intent-attribution-compliance/README.md Defines compliance scenarios.
specs/intent-attribution-agent-governance.md Adds safeguards and sync guidance.
pkg/cli/outcome_eval.go Registers replace_label evaluator.
pkg/cli/outcome_eval_update.go Tracks replacement labels.
pkg/cli/outcome_eval_update_test.go Tests retained replacement.
pkg/cli/outcome_eval_label.go Adds replacement evaluator.
actions/setup/js/evaluate_outcomes.test.cjs Tests label and close outcomes.
actions/setup/js/evaluate_outcomes.cjs Adds dedicated JavaScript evaluators.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 13/13 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment thread actions/setup/js/evaluate_outcomes.cjs
Comment thread pkg/cli/outcome_eval_label.go Outdated
Comment on lines +13 to +14
func evalReplaceLabel(item CreatedItemReport, repoOverride string) OutcomeReport {
return evalRetainedUpdate(item, repoOverride, "label replacement", extractCurrentIssueUpdateState, false)
Comment thread specs/safe-output-outcome-evaluation.md Outdated
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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

No ADR enforcement needed: PR #44798 does not have the 'implementation' label and has only 41 new lines of code in business logic directories (threshold: 100).

@github-actions github-actions Bot mentioned this pull request Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 82/100 — Excellent

Analyzed 8 test(s): 8 design, 0 implementation, 0 violation(s).

📊 Metrics (8 tests)
Metric Value
Analyzed 8 (Go: 6, JS: 2)
✅ Design 8 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 6 (75%)
Duplicate clusters 0
Inflation YES (Go: 32 test lines / 2 prod lines added ≈ 16:1)
🚨 Violations 0
Test File Classification Issues
TestEvalUpdateIssueRetained outcome_eval_update_test.go:11 design_test Assertions lack message context
TestEvalUpdateIssueReverted outcome_eval_update_test.go:57 design_test Assertions lack message context
TestEvalUpdatePullRequestRetainedAndMerged outcome_eval_update_test.go:92 design_test Assertions lack message context
TestEvalUpdatePullRequestReplaced outcome_eval_update_test.go:137 design_test Assertions lack message context
TestEvalRetainedUpdateMissingExecutionStateUsesEvidenceNone outcome_eval_update_test.go:182 design_test (edge)
TestEvalReplaceLabelRetained outcome_eval_update_test.go:195 design_test Assertions lack message context
evaluates close_issue using persisted repo/number metadata evaluate_outcomes.test.cjs:188 design_test
evaluates close_pull_request using persisted repo/number metadata evaluate_outcomes.test.cjs:215 design_test
⚠️ Flagged Tests (6) — soft flags only, no violations

TestEvalUpdateIssueRetained / TestEvalUpdateIssueReverted / TestEvalUpdatePullRequestRetainedAndMerged / TestEvalUpdatePullRequestReplaced / TestEvalReplaceLabelRetained / TestEvalRetainedUpdateMissingExecutionStateUsesEvidenceNone (outcome_eval_update_test.go)

All 6 Go tests use bare assert.Equal(t, expected, actual) without a descriptive failure message as the optional third argument. When a test fails, the output only shows the mismatched values without context. Recommend adding a short string like assert.Equal(t, OutcomeAccepted, report.Result, "result mismatch") to make CI failures self-explaining.

Inflation note: outcome_eval_update_test.go added 32 lines while its corresponding production file (outcome_eval_update.go) added only 2 lines in this PR (ratio ≈ 16:1). This is expected here — the tests cover evalUpdateIssue, evalUpdatePullRequest, and evalReplaceLabel functions whose logic largely pre-existed; the PR only added missing behavioral tests. This is healthy back-fill, not true inflation.

Verdict

Passed. 0% implementation tests (threshold: 30%). No coding-guideline violations. All 8 tests verify behavioral contracts (OutcomeAccepted/OutcomeRejected, EvidenceStrength, and Signal fields) against distinct scenarios — retained, reverted, replaced, merged, missing-state, and label operations. The replace_label and close evaluator coverage fills genuine spec gaps as described in the PR.

References:

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 36.1 AIC · ⌖ 9.88 AIC · ⊞ 6.8K ·
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: 82/100 — Excellent. 0% implementation tests (threshold: 30%). All 8 tests are behavioral design tests with no violations. 6 Go tests have soft-flag for missing assertion context messages (non-blocking).

@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 dedicated outcome evaluators for replace_label and close operations

The core mechanics are well-structured — new evaluators are clean, testable, and correctly routed. Two blocking correctness issues found.

Blocking

  1. evaluateCloseIssue and evaluateClosePullRequest never set outcome_status, evidence_strength, or signal (inline comments filed). All terminal return paths leave out.outcome_status = "unknown" and out.evidence_strength = "weak". Since the pipeline reads evalResult.outcome_status directly when writing to the JSONL, those fields will be wrong in every accepted/rejected case. The normalizeOutcome fallback produces the right outcome_status for the aggregated stats, but the EvalResult struct should be self-consistent — as every other evaluator in the file demonstrates.

  2. evaluateClosePullRequest merged-rejection path also leaves outcome_status at "unknown"normalizeOutcome has no dedicated branch for rejected + "merged", so that case falls to the generic rejected switch arm and emits signal: "rejected" / evidence_strength: "medium" instead of a more precise signal.

Non-blocking

  • T-RL-021 is duplicated in the test-ID mapping table in specs/replace-label-compliance/README.md. Duplicate IDs should be merged or given distinct sub-IDs.
  • Missing test coverage for the api-error and missing-reference early-exit paths in the new close evaluators.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 81.2 AIC · ⌖ 4.74 AIC · ⊞ 4.8K

Comment thread actions/setup/js/evaluate_outcomes.cjs
Comment thread actions/setup/js/evaluate_outcomes.cjs

it("evaluates update_issue retained and reverted states from persisted execution metadata", () => {
const retained = evaluateItem(
{

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.

Missing test coverage for api-error and missing-reference paths in evaluateCloseIssue and evaluateClosePullRequest. The tests cover the happy path (accepted/rejected), but not: 1) !repo or !number (missing reference detail), 2) API error path (which also calls setPendingAge, affecting pending_age_sec). The missing-number path was tested for add_labels (line 235 in this file) but not for close_issue or close_pull_request. @copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added in the same commit. Both evaluateCloseIssue and evaluateClosePullRequest now have tests covering:

  1. Missing reference (!repo || !number) → result: "unknown", detail: "missing issue/pull request reference"
  2. API error (setPendingAge path) → result: "unknown", detail: "api error", pending_age_sec is a number

The existing happy-path tests were also updated to assert outcome_status, evidence_strength, and signal on every branch, and a merged_at-only detection test was added for evaluateClosePullRequest.

|---------|---------|-------------|
| T-RL-020 | `rl-001-glob-semantics.yaml` | Star glob matches label name substring |
| T-RL-021 | `rl-001-glob-semantics.yaml` | Exact pattern matches only exact name |
| T-RL-021 | `rl-002-allowlist-enforcement.yaml` | Non-empty allowed-add accepts a matching label |

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.

T-RL-021 appears twice in the test-ID mapping table (lines 60 and 61), mapping to two different fixtures. This is not incorrect per se but test IDs are expected to be unique. If T-RL-021 is really two distinct sub-cases they should either share the same row with multiple fixtures listed, or be assigned distinct IDs (e.g., T-RL-021a / T-RL-021b). A duplicate ID will confuse test-suite harnesses that index by ID. @copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in the same commit. The two rl-002-specific rows were renamed to T-RL-021b and T-RL-022b so every row in the table has a unique ID. The rl-002 fixture header on line 15 was also updated to reference T-RL-021b and T-RL-022b.

@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 /tdd and /grill-with-docs — requesting changes on signal-precision gaps and a missing compliance cross-reference.

📋 Key Themes & Highlights

Key Issues

  1. Signal precision (/tdd)evaluateCloseIssue and evaluateClosePullRequest return out.detail = "closed" on success, but normalizeOutcome has no registered branch for accepted + "closed". The result falls through to the generic "acted_on" signal (medium evidence), silently downgrading every successfully-closed outcome in the JSONL. Similarly, out.detail = "merged" on the close_pull_request rejection path is unregistered.
  2. API-error path coverage (/tdd) — The setPendingAge branches in both new JS evaluators (lines 578, 644) have no tests. A future regression there would be invisible.
  3. Compliance cross-reference gap (/grill-with-docs)rl-003-blocklist-ordering.yaml was added separately but specs/replace-label-compliance/README.md was not updated for it in this PR. The RL-002 row was added without a companion RL-003 row, leaving the README incomplete.

Positive Highlights

  • ✅ Clean dedicated evaluators that replace generic fallbacks — the intent and logic are clear
  • evaluateClosePullRequest correctly distinguishes merged (rejected) from unmerged-closed (accepted) with a well-placed comment explaining the design decision
  • ✅ Good test coverage for the happy paths and the missing-number edge case in add_labels
  • evalReplaceLabel is a satisfying thin wrapper — reuses evalRetainedUpdate instead of duplicating logic

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 85.7 AIC · ⌖ 4.93 AIC · ⊞ 6.6K
Comment /matt to run again

Comments that could not be inline-anchored

actions/setup/js/evaluate_outcomes.cjs:591

[/tdd] out.detail = &quot;closed&quot; for an accepted close_issue is not handled by normalizeOutcome, so it falls through to the generic &quot;acted_on&quot; signal (medium evidence). The outcome JSONL loses precision on every successfully-closed issue evaluation.

<details>
<summary>💡 Suggested fix</summary>

Add a branch in normalizeOutcome:

if (result === &quot;accepted&quot; &amp;&amp; normalizedDetail === &quot;closed&quot;) {
  return { outcome_status: &quot;accepted&quot;, evidence_strength: &quot;strong&quot;, signal: &quot;closed&quot; };


</details>

<details><summary>actions/setup/js/evaluate_outcomes.cjs:664</summary>

**[/tdd]** `out.detail = &quot;merged&quot;` for a rejected PR is also unregistered in `normalizeOutcome`, so it falls through to the generic `&quot;rejected&quot;` signal (medium evidence) instead of a strong, named signal like `&quot;closed_by_merge&quot;`.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Register the `merged` rejection case in `normalizeOutcome`:

```js
if (result === &quot;rejected&quot; &amp;&amp; normalizedDetail === &quot;merged&quot;) {
  return { outcome_status: &quot;rejected&quot;, evidence_strength: &quot;strong&quot;, signal: &quot;closed_by_merge…

</details>

<details><summary>actions/setup/js/evaluate_outcomes.test.cjs:73</summary>

**[/tdd]** The new `close_issue` tests cover accepted and rejected states, but the API-error path (when `api(...)` returns `null` or lacks `state`) is not tested. This gap means the `setPendingAge` call on line 578 of `evaluate_outcomes.cjs` has no coverage, so a regression there would go undetected.

&lt;details&gt;
&lt;summary&gt;💡 Suggested test&lt;/summary&gt;

```js
it(&quot;returns unknown with pending_age when close_issue API call fails&quot;, () =&gt; {
  const item = {
    type: &quot;close_issue&quot;,
    number: 77,
    r…

</details>

<details><summary>specs/replace-label-spec.md:539</summary>

**[/grill-with-docs]** `rl-003-blocklist-ordering.yaml` is already present in the compliance directory but was not added to the README cross-reference table in this PR  the RL-002 update adds `rl-002` to the README but leaves `rl-003` undocumented there. This creates an asymmetry that makes the compliance suite harder to navigate.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Add a row in `specs/replace-label-compliance/README.md` for `rl-003-blocklist-ordering.yaml` alongside the new `rl-00

</details>

@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 — two correctness bugs block merge; one design issue needs a decision.

Blocking issues (must fix)

1. outcome_status / evidence_strength / signal never populated in JS close evaluators

Both evaluateCloseIssue and evaluateClosePullRequest initialize these fields as "unknown"/"weak"/"unknown" and never update them on any return path. The aggregation loop re-derives them via normalizeOutcome() so dashboard counts are correct, but the exported EvalResult object carries a permanently malformed schema for any direct consumer. All other evaluators set these fields explicitly.

2. evalReplaceLabel uses full atomic label-set comparison

replace_label swaps exactly one label pair, but evalRetainedUpdate compares the entire labels set against afterState.labels. Any unrelated label added/removed after execution falls into state_replaced → rejected even when the swap itself succeeded. The correctness predicate should be: target label present AND removed label absent — not entire label set unchanged.

Non-blocking concerns

3. rejected/reopened for a never-closed item is factually wrong

If close_issue fails silently, the issue stays open. The evaluator returns detail="reopened" — implying it was previously closed. These have different attribution implications.

4. Merged PR guard has no merged_at fallback

Transient GitHub API lag can briefly return merged: false. Adding || pullRequest.merged_at != null closes the race at zero cost.

5. New tests do not assert outcome_status / evidence_strength / signal

Directly caused by issue #1 — without these assertions the broken schema is invisible to tests.

🔎 Code quality review by PR Code Quality Reviewer · 114.1 AIC · ⌖ 5.03 AIC · ⊞ 5.4K
Comment /review to run again

Comments that could not be inline-anchored

actions/setup/js/evaluate_outcomes.cjs:591

outcome_status, evidence_strength, and signal are never set: all three fields stay at their initial &quot;unknown&quot;/&quot;weak&quot;/&quot;unknown&quot; on every return path, so any consumer of the raw EvalResult object gets a broken schema.

<details>
<summary>💡 Suggested fix</summary>

Set all three fields alongside result in each branch, as every other evaluator does:

if (issue.state === &quot;closed&quot;) {
  out.result = &quot;accepted&quot;;
  out.outcome_status = &quot;accepted&quot;;
  out.evidence_strength = &quot;strong…

</details>

<details><summary>actions/setup/js/evaluate_outcomes.cjs:599</summary>

**&#39;rejected&#39;/&#39;reopened&#39; is semantically wrong for an issue that was never closed**: if the action failed silently and the issue is still &#39;open&#39;, the evaluator returns `result=&#39;rejected&#39;, detail=&#39;reopened&#39;`  but the issue was never closed in the first place, so &#39;reopened&#39; is factually incorrect.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Distinguish the two cases. The same applies to `evaluateClosePullRequest`:

```js
if (issue.state !== &quot;closed&quot;) {
  // Was it ever closed? Check closed_at…

</details>

<details><summary>actions/setup/js/evaluate_outcomes.cjs:663</summary>

**Merged PR is checked via `merged === true` only — transient race with `merged_at`**: the GitHub API can briefly return `merged: false` for a PR that was just merged before the `merged_at` field propagates. A merged PR could slip through the guard and be evaluated as &#39;accepted/closed&#39; instead of &#39;rejected/merged&#39;.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Use `merged_at` as a secondary signal:

```js
if (pullRequest.merged === true || pullRequest.merged_at != null) {
  out.result = &quot;reje…

</details>

<details><summary>pkg/cli/outcome_eval_label.go:14</summary>

**`evalReplaceLabel` uses atomic label-set comparison  any unrelated label change causes a false rejection**: `evalRetainedUpdate` with `mutableTrackedFields(&quot;replace_label&quot;) = [&quot;labels&quot;]` checks whether the entire label set matches `afterState.labels`. If any unrelated label is added or removed after the `replace_label` executes, `currentState.labels != afterState.labels`, the comparison falls into the `state_replaced` branch, and the outcome is reported as `rejected`  even though the actual…

</details>

<details><summary>actions/setup/js/evaluate_outcomes.test.cjs:272</summary>

**Tests for `close_issue`/`close_pull_request` never assert `outcome_status`, `evidence_strength`, or `signal`**: only `result` and `detail` are verified, so the three fields that are structurally broken (always `&quot;unknown&quot;/&quot;weak&quot;/&quot;unknown&quot;`) are not caught by any test.

&lt;details&gt;
&lt;summary&gt;💡 Suggested fix&lt;/summary&gt;

Add assertions for the normalized fields:

```js
const r = evaluateItem(item, &quot;acme/repo&quot;, { ghAPI: closed });
expect(r.result).toBe(&quot;accepted&quot;);
expect(r.outcome_status).toBe(&quot;acce…

</details>

Copilot AI and others added 2 commits July 10, 2026 19:17
…ce_label, partial close status

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

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

pr-sous-chef
@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.
...

Addressed all three unresolved review threads:

  1. evaluate_outcomes.cjs:458evaluateAddLabels now reads item.before_state?.labels as primary (production manifest shape from add_labels.cjs), falling back to item.labelsBefore for legacy items. Added a test covering the before_state.labels path.

  2. pkg/cli/outcome_eval_label.go:13-14 — Replaced the evalRetainedUpdate delegation with a dedicated evalReplaceLabel that computes the label delta (added/removed sets) from the before/after snapshots and verifies only that delta in current state. Unrelated labels added after execution no longer cause false state_replaced outcomes. Helper functions use binary search (O(n log m)). Added tests for the extra-label and reverted cases.

  3. specs/safe-output-outcome-evaluation.md:129-130 — Changed close_issue and close_pull_request from implemented to partial since actor-based classification (§8–9) is not yet implemented.

Commits: fix: address review comments + perf: use binary search in label set helpers. Local make fmt, make lint, make test-unit all pass.

Copilot AI requested a review from gh-aw-bot July 10, 2026 19:22
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments if any, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · 7.7 AIC · ⌖ 4.78 AIC · ⊞ 7.5K ·
Comment /souschef to run again

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review comments if any, and rerun checks once the branch is up to date.

...

All unresolved review feedback has been addressed. Commit 98309c1 is ready locally but cannot be pushed — the agent token is returning 403 for this repository; a maintainer push will be needed to make it visible on the PR.

Changes in the pending commit

Blocking fixes:

  1. evaluateCloseIssue and evaluateClosePullRequestoutcome_status, evidence_strength, and signal are now set explicitly on every return path (previously left at "unknown"/"weak"/"unknown"):

    • accepted/closed → { outcome_status: "accepted", evidence_strength: "strong", signal: "closed" }
    • rejected/merged → { outcome_status: "rejected", evidence_strength: "strong", signal: "closed_by_merge" }
    • rejected/not-closed → { outcome_status: "rejected", evidence_strength: "strong", signal: "not_closed" }
  2. rejected/reopenedrejected/not_closed"reopened" implied the issue was previously closed, which is factually wrong when it was never closed. Changed to the semantically neutral "not_closed" in both evaluators.

  3. merged_at fallbackevaluateClosePullRequest merged check is now pullRequest.merged === true || pullRequest.merged_at != null to guard against transient API lag.

normalizeOutcome extended with three new branches so the aggregation loop also produces precision signals:

  • accepted + "closed"signal: "closed"
  • rejected + "merged"signal: "closed_by_merge"
  • rejected + "not_closed"signal: "not_closed"

Tests updated:

  • Existing close evaluator tests now assert outcome_status, evidence_strength, signal and use "not_closed" for the open-issue rejected path.
  • New tests added for: API-error path (setPendingAge branch) for both close_issue and close_pull_request; merged_at-only detection; not_closed PR path.

Non-blocking:

  • T-RL-021 duplicate in specs/replace-label-compliance/README.md resolved (renamed entries to T-RL-021a / T-RL-022a).

Local validation: make fmt, make lint, make test-unit all pass. evaluate_outcomes.test.cjs (51/51) passes.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, refresh the branch if needed, and rerun checks once updates are complete.

Generated by 👨‍🍳 PR Sous Chef · 7.17 AIC · ⌖ 7.25 AIC · ⊞ 7.5K ·
Comment /souschef to run again

…eturn paths; add missing tests; deduplicate T-RL IDs

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

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address any remaining review feedback, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · 12.5 AIC · ⌖ 5.63 AIC · ⊞ 7.5K ·
Comment /souschef to run again

Copilot AI commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address any remaining review feedback, and rerun checks once the branch is up to date.

...

All review feedback has already been addressed in the prior commits. Local validation confirms everything is clean:

  • Reviews — All 6 review threads have been replied to with the relevant commit hashes. Code fixes are in place for every thread:
    • before_state?.labels ?? item.labelsBefore fallback in evaluateAddLabels (PRRT_kwDOPc1QR86P-oE7)
    • Delta-based evalReplaceLabel in Go that only checks added/removed labels, ignoring unrelated label changes (PRRT_kwDOPc1QR86P-oFS)
    • Explicit outcome_status, evidence_strength, and signal on all evaluateCloseIssue / evaluateClosePullRequest return paths (PRRT_kwDOPc1QR86P-1gZ, PRRT_kwDOPc1QR86P-1gh)
    • Missing-reference and API-error test coverage for both close evaluators (PRRT_kwDOPc1QR86P-1gl)
    • Duplicate T-RL-021 IDs renamed to T-RL-021b/T-RL-022b (PRRT_kwDOPc1QR86P-1gr)
  • Checks (local)make fmt, make lint, go test ./pkg/cli/... (all pass), vitest JS tests (52/52 pass)
  • Checks (CI) — All runs on bd2aef72 show action_required with 0 jobs executed — this is the GitHub Actions approval gate for bot commits, not a test failure. CI needs a maintainer to approve the run (close/reopen the PR or approve the workflow run).
  • Mergeable — Could not be verified via API; no conflicts are expected since the branch is ahead of main with no overlapping changes.

Hand-off: A maintainer needs to approve the pending CI workflow runs (or close/reopen the PR to re-trigger them) before merge.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

pr-sous-chef

@copilot please run the pr-finisher skill, address the remaining unresolved review feedback, and rerun checks once the branch is up to date.

Unresolved review feedback to address:

Generated by 👨‍🍳 PR Sous Chef · 13.9 AIC · ⌖ 4.91 AIC · ⊞ 7.5K ·
Comment /souschef to run again

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category feature/test
Risk medium
Priority Score 73 / 100
Recommended Action fast_track

Score breakdown: Impact 38/50 · Urgency 20/30 · Quality 15/20

Rationale: Adds dedicated outcome evaluators filling spec/compliance gaps (+776/-18 lines, 13 files). CI fully passing, 11 reviews. High-value correctness improvement to the evaluation pipeline.

Generated by 🔧 PR Triage Agent · 151.2 AIC · ⌖ 7.52 AIC · ⊞ 5.4K ·

@pelikhan pelikhan merged commit de587fc into main Jul 11, 2026
39 checks passed
@pelikhan pelikhan deleted the copilot/spdd-daily-spec-work-plan-2026-07-10 branch July 11, 2026 08:01
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.82.8

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.

[spdd] Daily spec work plan - 2026-07-10

4 participants