Skip to content

Normalize safe-output issue/PR constraints to required-title-prefix, add migration codemod, add required-labels#33350

Open
Copilot wants to merge 16 commits into
mainfrom
copilot/update-title-prefix-constraint
Open

Normalize safe-output issue/PR constraints to required-title-prefix, add migration codemod, add required-labels#33350
Copilot wants to merge 16 commits into
mainfrom
copilot/update-title-prefix-constraint

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 19, 2026

This change standardizes safe-output constraint syntax on require-title-prefix (with title-prefix kept as deprecated input for compatibility) and ensures title-prefix-gated operations also require label gating. It also adds an upgrade codemod so existing workflows migrate automatically.

  • Constraint key normalization + compatibility

    • Added support for require-title-prefix as the canonical key for constraint-style title filtering.
    • Kept title-prefix as a deprecated alias where it previously meant a constraint, and normalize it at parse time.
    • Important distinction preserved: creator-style title-prefix (e.g. create issue/PR title decoration) is unchanged.
  • Upgrade/codemod migration

    • Added a codemod to rewrite deprecated constraint usage from title-prefix to require-title-prefix for relevant handlers:
      • close-issue
      • close-discussion
      • close-pull-request
      • mark-pull-request-as-ready-for-review
      • push-to-pull-request-branch
    • Wired codemod into the fix/upgrade codemod registry and order assertions.
  • Hard-constraint enforcement

    • Added compile-time validation requiring label gating when title-prefix gating is configured:
      • required-title-prefix requires required-labels on close/mark handlers.
      • require-title-prefix requires labels on push-to-pull-request-branch.
  • Schema/docs/types updates

    • Updated schema to include canonical keys and deprecated aliases where appropriate.
    • Updated docs/examples to use require-title-prefix for constraint usage on push-to-PR-branch.
    • Updated JS type definitions for new canonical field.
  • Representative migration

safe-outputs:
  push-to-pull-request-branch:
    target: "*"
    require-title-prefix: "[bot] "
    labels: [automated]

pr-sous-chef: request to update branch (run id: 26122348307)

Generated by 👨‍🍳 PR Sous Chef · ● 246.4K ·

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Copilot AI changed the title [WIP] Update title prefix constraint to require-title-prefix and require-label Normalize safe-output title-prefix constraints to require-title-prefix, add migration codemod, and enforce label gating May 19, 2026
Copilot finished work on behalf of dsyme May 19, 2026 16:29
Copilot AI requested a review from dsyme May 19, 2026 16:29
*/
interface PushToPullRequestBranchConfig extends SafeOutputConfig {
target?: string;
"require-title-prefix"?: string;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot Sorry this should be required-title-prefix not require-title-prefix, also everywhere else

Also close-pull-request and close-issue should suppor both required-title-prefix and required-labels

For push-to-pull-request-branch, labels should be renamed required-labels with codemod added.

Review all other labels: in safe outputs

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.

Addressed in 451fe72.

  • Canonicalized to required-title-prefix (kept require-title-prefix and title-prefix as deprecated compatibility aliases where applicable).
  • close-issue and close-pull-request continue to support required-title-prefix + required-labels (with tests covering required-label gating for close PR as well).
  • For push-to-pull-request-branch, renamed canonical labels to required-labels, added deprecated labels alias support, updated handler emission/runtime consumption, and updated validation/error text.
  • Extended codemod to migrate:
    • title-prefix -> required-title-prefix (for targeted handlers)
    • push-to-pull-request-branch.labels -> required-labels
  • Updated schema/types/docs/tests accordingly and reviewed other safe-output labels: usages to keep non-push label fields unchanged.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot There's no need to include require-title-prefix in the deprecation or codemod because it's literally being added in this PR

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 ad8d096.

I removed require-title-prefix from deprecated/compat handling and migration paths:

  • removed deprecated require-title-prefix key from schema/type definitions
  • removed codemod special-casing for require-title-prefix
  • removed parser fallback to require-title-prefix (canonical required-title-prefix, with title-prefix deprecated alias retained)

Copilot AI and others added 2 commits May 19, 2026 16:51
Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
…bels

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Copilot finished work on behalf of dsyme May 19, 2026 17:06
Copilot AI requested a review from dsyme May 19, 2026 17:06
@dsyme dsyme marked this pull request as ready for review May 19, 2026 17:31
Copilot AI review requested due to automatic review settings May 19, 2026 17:31
@dsyme dsyme changed the title Normalize safe-output title-prefix constraints to require-title-prefix, add migration codemod, and enforce label gating Normalize safe-output title-prefix constraints to required-title-prefix, add migration codemod, add required-labels May 19, 2026
@dsyme dsyme changed the title Normalize safe-output title-prefix constraints to required-title-prefix, add migration codemod, add required-labels Normalize safe-output issue/PR constraints to required-title-prefix, add migration codemod, add required-labels May 19, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens safe-output constraint handling by normalizing title/label gating fields, enforcing label gating when title-prefix constraints are used, and adding migration support for deprecated field names.

Changes:

  • Adds parsing/validation support for title-prefix aliases and required label gating.
  • Updates push-to-PR-branch handler config generation/runtime consumption to use required_labels.
  • Adds a codemod, tests, schema/docs updates, and regenerated workflow locks.
Show a summary per file
File Description
pkg/workflow/safe_outputs_validation.go Adds validation requiring labels with title-prefix constraints.
pkg/workflow/safe_outputs_required_labels_validation_test.go Tests new title-prefix/label validation.
pkg/workflow/safe_outputs_parser.go Adds deprecated title-prefix alias parsing.
pkg/workflow/safe_outputs_deprecated_title_prefix_test.go Tests deprecated alias compatibility.
pkg/workflow/push_to_pull_request_branch.go Parses canonical/deprecated push title and label constraint keys.
pkg/workflow/push_to_pull_request_branch_warning_test.go Updates warning tests for required label/title fields.
pkg/workflow/push_to_pull_request_branch_validation.go Updates unconstrained push warning logic/messages.
pkg/workflow/push_to_pull_request_branch_test.go Updates push handler config tests for required labels.
pkg/workflow/config_parsing_helpers_test.go Updates expression parsing expectations for required labels.
pkg/workflow/compiler_validators.go Wires new label/title validation into compilation.
pkg/workflow/compiler_safe_outputs_handlers.go Emits required_labels in handler config.
pkg/workflow/close_entity_helpers.go Maps deprecated close-entity title-prefix to required title prefix.
pkg/parser/schemas/main_workflow_schema.json Updates schema fields and deprecation metadata.
pkg/cli/fix_codemods.go Registers the new codemod.
pkg/cli/fix_codemods_test.go Updates codemod registry/order tests.
pkg/cli/codemod_safe_output_require_title_prefix.go Adds migration logic for deprecated safe-output constraint keys.
pkg/cli/codemod_safe_output_require_title_prefix_test.go Tests the new codemod.
docs/src/content/docs/reference/safe-outputs.md Updates push-to-PR-branch examples.
docs/src/content/docs/reference/safe-outputs-pull-requests.md Updates push-to-PR-branch reference docs.
actions/setup/js/types/safe-outputs-config.d.ts Adds new push-to-PR-branch config fields.
actions/setup/js/push_to_pull_request_branch.cjs Reads required_labels with deprecated fallback.
.github/workflows/smoke-otel-backends.lock.yml Updates generated Datadog env reference.
.github/workflows/semantic-function-refactor.md Adds label gating to close-issue safe output.
.github/workflows/semantic-function-refactor.lock.yml Regenerates lock file with label gating.
.github/workflows/dependabot-go-checker.md Adds label gating to close-issue safe output.
.github/workflows/dependabot-go-checker.lock.yml Regenerates lock file with label gating.

Copilot's findings

Tip

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

  • Files reviewed: 25/26 changed files
  • Comments generated: 3

push-to-pull-request-branch:
target-repo: "org/target-repo"
title-prefix: "[bot] "
required-title-prefix: "[bot] "
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot We have this wrong. We shouldn't require required-labels if required-title-prefix is present - we should instead simply support both required-title-prefix and required-labels as two separate, orthogonal hard constraints.

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.

Implemented in e1965c6. I removed the compile-time validation that required required-labels when required-title-prefix is present, so these are now orthogonal constraints for safe-output handlers.

Description: "Renames deprecated constraint fields to required-title-prefix/required-labels for applicable safe-outputs handlers.",
IntroducedIn: "1.0.0",
Apply: func(content string, frontmatter map[string]any) (string, bool, error) {
handlersToRename := safeOutputsHandlersNeedingTitlePrefixMigration(frontmatter)
Comment on lines +110 to +118
if inSafeOutputs && isDescendant(indent, safeOutputsIndent) && strings.HasSuffix(trimmed, ":") && !strings.HasPrefix(trimmed, "#") {
key := strings.TrimSuffix(trimmed, ":")
if handlersToRename[key] {
activeHandler = key
activeHandlerIndent = indent
} else {
activeHandler = ""
activeHandlerIndent = ""
}
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

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 /improve-codebase-architecture based on the constraint normalization + codemod migration in this PR.


Key Themes

✅ Strong Points

  • Excellent codemod test coverage: The codemod tests comprehensively cover positive/negative cases and edge cases (rename vs. no-rename scenarios)
  • Thoughtful backward compatibility: The multi-stage fallback chain (required-title-prefixrequire-title-prefixtitle-prefix) prevents breaking changes while guiding users to the canonical naming
  • Hard constraint enforcement: The new validation requiring labels when title-prefix is set prevents misconfiguration at compile time—excellent defensive design
  • Seamless migration path: The automated codemod makes upgrades effortless for existing workflows

🔍 Areas for Improvement

1. Missing edge case tests/tdd

  • Validation logic lacks tests for nil config pointers (comment on line 190)
  • Parser fallback chain not covered by dedicated tests (comment on line 80)
  • JavaScript handler fallback (config.required_labels ?? config.labels) not tested (comment on line 112)
  • Three-stage parsing fallback in push_to_pull_request_branch.go lacks test coverage (comment on line 133)

Rationale: While the implementation is correct, fallback logic and edge cases are common sources of regressions. Explicit tests provide confidence during future refactoring.

2. Structural inconsistency/improve-codebase-architecture

  • PushToPullRequestBranchConfig defines RequiredLabels + Labels as separate fields
  • Other handlers use SafeOutputFilterConfig which already has these fields
  • This creates two different mental models for the same "title-prefix + labels constraint" pattern

Suggestion: Consider whether PushToPullRequestBranchConfig should embed SafeOutputFilterConfig to unify constraint handling across all safe-output handlers. This would reduce duplication and make the domain language more consistent.


Overall Verdict

The core implementation is solid and well-designed. The migration strategy is exemplary. The requested changes are minor improvements to test coverage and architectural consistency—not blockers, but they would strengthen the codebase.

Recommended next steps:

  1. Add the missing edge case tests (should take ~15-20 minutes)
  2. Consider the structural refactor as a follow-up (optional, but worthwhile)

Skills Applied

  • /tdd — Identified missing test coverage for fallback chains and edge cases
  • /improve-codebase-architecture — Highlighted structural inconsistency in constraint field definitions

Great work on this PR! The naming normalization and validation enforcement are important improvements to the safe-outputs system. 🎯

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 7.5M

Comment thread pkg/workflow/safe_outputs_validation.go Outdated
// validateSafeOutputsRequiredLabelsWithTitlePrefix validates that title-prefix
// constraints are always paired with label constraints.
func validateSafeOutputsRequiredLabelsWithTitlePrefix(config *SafeOutputsConfig) error {
if config == nil {
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] The new validation function validateSafeOutputsRequiredLabelsWithTitlePrefix lacks tests for nil config pointers in the validation test file.

The validation logic correctly handles nil config, but there is no explicit test case verifying this behavior. Consider adding:

t.Run("nil config passes validation", func(t *testing.T) {
    err := validateSafeOutputsRequiredLabelsWithTitlePrefix(nil)
    require.NoError(t, err)
})

This ensures the guard clause at the start works as expected and prevents future regressions if the logic changes.

// Parse required-title-prefix (preferred) with fallback to deprecated title-prefix
config.RequiredTitlePrefix = extractStringFromMap(configMap, "required-title-prefix", safeOutputParserLog)
if config.RequiredTitlePrefix == "" {
config.RequiredTitlePrefix = extractStringFromMap(configMap, "title-prefix", safeOutputParserLog)
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] The parser fallback chain (required-title-prefixtitle-prefix) lacks dedicated test coverage.

While the codemod tests verify the migration, there are no parser-level tests confirming:

  1. required-title-prefix takes precedence when both are present
  2. title-prefix is used as fallback when required-title-prefix is missing

Consider adding to safe_outputs_deprecated_title_prefix_test.go:

t.Run("parser prefers required-title-prefix over title-prefix", func(t *testing.T) {
    config := ParseFilterConfig(map[string]any{
        "required-title-prefix": "[new] ",
        "title-prefix": "[old] ",
    })
    assert.Equal(t, "[new] ", config.RequiredTitlePrefix)
})

const target = config.target || "triggering";
const titlePrefix = config.title_prefix || "";
const envLabels = config.labels ? (Array.isArray(config.labels) ? config.labels : config.labels.split(",")).map(label => String(label).trim()).filter(label => label) : [];
const rawRequiredLabels = config.required_labels ?? config.labels;
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] The JavaScript handler fallback logic (config.required_labels ?? config.labels) lacks test coverage.

The .cjs file correctly implements the fallback, but there are no tests verifying:

  1. required_labels takes precedence when both are present
  2. labels is used as fallback when required_labels is undefined

While this logic mirrors the Go implementation, JavaScript has different null/undefined semantics that warrant explicit testing. Consider adding tests to a new push_to_pull_request_branch.test.cjs file if one doesn't already exist.

@@ -14,7 +14,8 @@ type PushToPullRequestBranchConfig struct {
BaseSafeOutputConfig `yaml:",inline"`
Target string `yaml:"target,omitempty"` // Target for push-to-pull-request-branch: like add-comment but for pull requests
TitlePrefix string `yaml:"title-prefix,omitempty"` // Required title prefix for pull request validation
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.

[/improve-codebase-architecture] Inconsistent naming creates two mental models for the same concept.

The struct has both:

  • RequiredLabels (canonical, line 16)
  • Labels (deprecated alias, line 17)

But other safe-output handlers use SafeOutputFilterConfig which already defines both fields. This PR introduces push-to-pull-request-branch.required-labels as the canonical name, but the struct doesn't embed SafeOutputFilterConfig.

Suggestion: Consider embedding SafeOutputFilterConfig here or extracting a shared constraint struct. This would unify the "title-prefix + labels constraint" pattern across all handlers and eliminate duplicate field definitions.

if pushToBranchConfig.TitlePrefix == "" {
pushToBranchConfig.TitlePrefix = extractStringFromMap(configMap, "require-title-prefix", pushToPullRequestBranchLog)
}
if pushToBranchConfig.TitlePrefix == "" {
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] The three-stage fallback chain here (required-title-prefixrequire-title-prefixtitle-prefix) is not covered by tests.

The parsing logic correctly implements the precedence order, but tests only verify the canonical required-title-prefix case. Add test cases for:

t.Run("falls back to require-title-prefix when required-title-prefix missing", func(t *testing.T) {
    config := parsePushToPullRequestBranchConfig(map[string]any{
        "push-to-pull-request-branch": map[string]any{
            "require-title-prefix": "[bot] ",
        },
    })
    assert.Equal(t, "[bot] ", config.TitlePrefix)
})

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 72/100

⚠️ Acceptable, with suggestions

Metric Value
New/modified tests analyzed 5
✅ Design tests (behavioral contracts) 5 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 2 (40%)
Duplicate test clusters 0
Test inflation detected YES (2 files exceed 2:1 ratio)
🚨 Coding-guideline violations 0 (hard failures)
⚠️ Missing assertion messages 4 assertions

Test Classification Details

Test File Classification Issues Detected
TestSafeOutputRequireTitlePrefixCodemod pkg/cli/codemod_safe_output_require_title_prefix_test.go:12 ✅ Design 3 missing assertion messages; test inflation OK (0.61:1)
TestPushToPullRequestBranchWithRequiredLabels pkg/workflow/push_to_pull_request_branch_test.go:801 ✅ Design Renamed existing test (minimal new code); happy path only
TestPushToPullRequestBranchWithTitlePrefixAndRequiredLabels pkg/workflow/push_to_pull_request_branch_test.go:848 ✅ Design Renamed existing test; happy path only; minimal assertions
TestDeprecatedTitlePrefixAliasForCloseIssue pkg/workflow/safe_outputs_deprecated_title_prefix_test.go:14 ✅ Design Test inflation 9.0:1 (36 test lines / 4 production lines); single scenario only
TestValidateSafeOutputsRequiredLabelsWithTitlePrefix pkg/workflow/safe_outputs_required_labels_validation_test.go:11 ✅ Design Test inflation 2.34:1 (103 test lines / 44 production lines); 1 missing assertion message

Flagged Tests — Requires Review

⚠️ Test Inflation: TestDeprecatedTitlePrefixAliasForCloseIssue

File: pkg/workflow/safe_outputs_deprecated_title_prefix_test.go:14

Classification: Design test (behavioral contract)
Issue: Test file added 36 lines while production file added only 4 net lines (9.0:1 ratio, threshold: 2:1)

What design invariant does this test enforce?
Backward compatibility — verifies that the deprecated title-prefix field in close-issue config is still accepted and correctly mapped to the new required-title-prefix field during parsing.

What would break if deleted?
A breaking change could slip through: existing workflows using the old title-prefix field would suddenly fail to parse, breaking backward compatibility.

Why the inflation?
The test includes full YAML frontmatter setup, file I/O, and multiple assertions. The production change is a small alias mapping in the parser.

Suggested improvement:
Consider whether the test setup can be simplified (e.g., testing the parser directly without file I/O if possible), or accept the ratio as justified for this critical backward-compatibility test. The test itself covers an important behavioral contract.

⚠️ Test Inflation: TestValidateSafeOutputsRequiredLabelsWithTitlePrefix

File: pkg/workflow/safe_outputs_required_labels_validation_test.go:11

Classification: Design test (behavioral contract)
Issue: Test file added 103 lines while production file added 44 lines (2.34:1 ratio, threshold: 2:1)

What design invariant does this test enforce?
Validation rule: When required-title-prefix (or deprecated title-prefix) is set for close/push handlers, required-labels must also be specified. This prevents agents from creating issues/PRs that can't be distinguished from human-created ones.

What would break if deleted?
Invalid configurations (title-prefix without labels) would pass validation and reach production, leading to unsafe agent behavior where agents could modify any issue/PR regardless of labels.

Why the inflation?
Table-driven test with 8 comprehensive test cases covering all 4 affected handlers (close-issue, close-pull-request, push-to-pull-request-branch, mark-ready) with both error and success scenarios.

Suggested improvement:
The comprehensive coverage is valuable for this security-relevant validation. The ratio is borderline (2.34:1 vs 2:1 threshold). Consider whether any test cases are redundant, but the test itself is well-structured and covers critical behavioral contracts.

Additional issue: 1 assertion missing descriptive message.

i️ Missing Assertion Messages: TestSafeOutputRequireTitlePrefixCodemod

File: pkg/cli/codemod_safe_output_require_title_prefix_test.go:12

Classification: Design test (behavioral contract) — Well-structured overall
Issue: 3 assertions lack descriptive failure messages

What this test does well:

  • ✅ Table-driven with 3 subtests covering transformation, negative cases, and idempotency
  • ✅ 12 assertions with proper error handling
  • ✅ Tests observable codemod behavior (YAML transformation)

What would break if deleted?
Incorrect codemod transformations would go undetected, potentially breaking automated migrations.

Suggested improvement:
Add descriptive messages to assertions for better failure diagnostics. Example:

// Before
assert.True(t, applied)
assert.Contains(t, result, "required-title-prefix: \"[bot] \"")

// After  
assert.True(t, applied, "Codemod should be applied when title-prefix is present")
assert.Contains(t, result, "required-title-prefix: \"[bot] \"", "Result should contain renamed field")

Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 5 tests (3 new files, 4 modified files)
    • Unit tests (//go:build !integration): All 3 new files ✅
    • Integration tests: 0 files

i️ No JavaScript/vitest tests found in this PR.


Test Inflation Analysis Details

Test File Production File Test Lines Prod Lines Ratio Status
codemod_safe_output_require_title_prefix_test.go codemod_safe_output_require_title_prefix.go 89 146 0.61:1 ✅ Pass
safe_outputs_deprecated_title_prefix_test.go safe_outputs_parser.go 36 4 9.0:1 Exceeds 2:1
safe_outputs_required_labels_validation_test.go safe_outputs_validation.go 103 44 2.34:1 Exceeds 2:1

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected.

Score breakdown:

  • Behavioral Coverage (40 pts): 40/40 — All tests verify behavioral contracts ✅
  • Edge Case Coverage (30 pts): 12/30 — 40% of tests include error/edge cases ⚠️
  • Low Duplication (20 pts): 20/20 — No duplicate test patterns ✅
  • Proportional Growth (10 pts): 0/10 — 2 files exceed 2:1 inflation ratio ❌

Strengths:

  • 🎯 100% behavioral coverage — all tests verify what the system does, not how
  • ✅ Proper build tags on all new Go test files
  • ✅ No forbidden mock libraries (gomock/testify mock)
  • ✅ Good use of table-driven patterns (2 out of 5 tests)
  • ✅ Tests cover critical features: codemods, validation, backward compatibility

Recommendations for improvement:

  1. Add descriptive assertion messages to the 4 flagged assertions for better failure diagnostics
  2. Increase edge case coverage — 3 of 5 tests only cover happy paths; consider adding error scenarios
  3. Review test inflation — 2 files exceed the 2:1 ratio (though both tests verify important behavioral contracts)

📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

Test Inflation: When test files grow disproportionately faster than production code (>2:1 ratio), it may indicate verbose test setup, redundant test cases, or opportunities for helper functions.


References:

🧪 Test quality analysis by Test Quality Sentinel · ● 8.6M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 72/100. Test quality is acceptable — 0% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected.

All 5 new/modified tests verify behavioral contracts. See detailed analysis in comment above.

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Copilot finished work on behalf of dsyme May 19, 2026 17:49
Copilot AI requested a review from pelikhan May 19, 2026 18:52
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot apply codemod to current repo (gh aw fix --write).

Copilot AI and others added 3 commits May 19, 2026 19:29
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>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 19, 2026

@copilot apply codemod to current repo (gh aw fix --write).

Done in 003961c.

I ran gh aw fix --write in this repo and committed the resulting codemod updates under .github/workflows/*.md.

@github-actions
Copy link
Copy Markdown
Contributor

`@copilot` review all comments Please address unresolved review feedback and post a short completion plan summarizing blockers and next steps.

Generated by 👨‍🍳 PR Sous Chef · ● 246.4K ·

@pelikhan
Copy link
Copy Markdown
Collaborator

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 19, 2026

@copilot fix https://github.com/github/gh-aw/actions/runs/26120377833/job/76827227837

Fixed in 31deaba.

I investigated the linked job logs, reproduced the failure locally (TestHashConsistencyAcrossLockFiles), recompiled the workflow lock files, and verified with:

  • go test ./pkg/parser -run TestHashConsistencyAcrossLockFiles -count=1
  • make lint-lock

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot merge main, recompile, fix conflicts

Copilot AI and others added 2 commits May 19, 2026 22:55
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 19, 2026

@copilot merge main, recompile, fix conflicts

Done in cd8e491b35.

Merged origin/main, resolved conflicts, recompiled workflows, and validated with:

  • go test ./pkg/parser -run TestHashConsistencyAcrossLockFiles -count=1
  • make lint-lock

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot the codemod is too aggressive at changing the workflows. Revert the changes in agentic workflows and review the codemod to be more selective

Copilot AI and others added 3 commits May 19, 2026 23:30
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>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 19, 2026

@copilot the codemod is too aggressive at changing the workflows. Revert the changes in agentic workflows and review the codemod to be more selective

Fixed in be9139a and fc81bcd.

I reverted the agentic workflow markdown/lock changes back to main, and tightened the codemod so it only rewrites direct safe-outputs.<handler> keys (not nested keys). Added regression coverage and verified with:

  • go test ./pkg/cli -run 'TestSafeOutputRequireTitlePrefixCodemod|TestFixCodemods' -count=1
  • go test ./pkg/parser -run TestHashConsistencyAcrossLockFiles -count=1
  • make lint-lock

@pelikhan
Copy link
Copy Markdown
Collaborator

/review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

⚠️ PR Code Quality Reviewer failed to deliver outputs during code quality review.

@github-actions github-actions Bot mentioned this pull request May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"title-prefix" constraint --> "required-title-prefix" for consistency, also add "required-label"

4 participants