Prevent placeholder discussion posts in daily compiler quality reports#31252
Conversation
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/625b4883-e50b-4978-a6a4-a55380399c1a Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
This reverts commit ac1c8f4. Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
…workflow Agent-Logs-Url: https://github.com/github/gh-aw/sessions/625b4883-e50b-4978-a6a4-a55380399c1a Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/625b4883-e50b-4978-a6a4-a55380399c1a Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
|
@copilot update schemas, instructions |
There was a problem hiding this comment.
Pull request overview
Hardens daily-compiler-quality discussion publishing by adding an explicit “one final discussion output” contract and enforcing a minimum discussion body length at safe-outputs runtime to prevent placeholder posts (e.g., test) from being published.
Changes:
- Added
min-body-lengthsupport to thecreate_discussionsafe-output config and validated it in the workflow schema/docs. - Implemented a
min_body_lengthguard in theactions/setup/js/create_discussion.cjshandler to fail safe-outputs on too-short bodies. - Added targeted tests for config propagation and the new runtime rejection behavior.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/create_discussion.go | Adds MinBodyLength to the create-discussion workflow config struct. |
| pkg/workflow/compiler_safe_outputs_handlers.go | Emits min_body_length into handler config when configured. |
| pkg/workflow/compiler_safe_outputs_config_test.go | Tests handler config propagation for min_body_length. |
| pkg/parser/schemas/main_workflow_schema.json | Validates safe-outputs.create-discussion.min-body-length in workflow schema. |
| docs/src/content/docs/reference/safe-outputs.md | Documents min-body-length usage for create-discussion. |
| actions/setup/js/create_discussion.cjs | Enforces min_body_length at runtime and fails on too-short bodies. |
| actions/setup/js/create_discussion_sanitization.test.cjs | Adds test ensuring too-short bodies fail and do not call GitHub API. |
| .github/workflows/daily-compiler-quality.md | Adds safe-outputs config + explicit output contract for discussions. |
| .github/workflows/daily-compiler-quality.lock.yml | Regenerates locked workflow with new safe-outputs config (and includes an env export change). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 9/9 changed files
- Comments generated: 2
| export GH_AW_ENGINE="copilot" | ||
| export GH_AW_MCP_CLI_SERVERS='["safeoutputs","serena"]' | ||
| echo 'GH_AW_MCP_CLI_SERVERS=["safeoutputs","serena"]' >> "$GITHUB_ENV" | ||
| echo GH_AW_MCP_CLI_SERVERS='["safeoutputs","serena"]' >> "$GITHUB_ENV" |
| TitlePrefix string `yaml:"title-prefix,omitempty"` | ||
| Category string `yaml:"category,omitempty"` // Discussion category ID or name | ||
| MinBodyLength int `yaml:"min-body-length,omitempty"` // Minimum required discussion body length before footer/markers | ||
| Labels []string `yaml:"labels,omitempty"` // Labels to attach to discussions and match when closing older ones |
🧪 Test Quality Sentinel ReportTest Quality Score: 75/100
Test Classification DetailsView all test classifications
Flagged Tests — Suggestions for Improvement
|
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /diagnose and /tdd — this is a bug fix (placeholder bodies being posted) with targeted new runtime guard and test coverage.
[/diagnose] Root cause assessment
The root cause (first emitted create_discussion accepted regardless of content) is addressed at two independent layers: prompt contract and runtime min_body_length guard. This defence-in-depth is good engineering — a single guard at either layer alone would be insufficient.
One concern: the check in create_discussion.cjs measures length from processedBody.trim() and names the variable preSanitizeBodyLength. If processedBody has already been through normalisation (whitespace stripping, header/footer injection, etc.) before this point, the measured length may differ meaningfully from the raw user-supplied body. The schema description says "before footer/metadata" — a comment or test making the measurement point explicit would prevent future confusion.
[/tdd] Test coverage gaps
The new test "should fail when body is below configured minimum length" is a solid tracer bullet, but several boundary and edge cases are missing:
-
Boundary at exactly
minBodyLength— a body of exactly 200 characters should pass. The current tests don't verify this boundary, which is where off-by-one errors hide. -
Guard-disabled path (
min_body_length: 0) — a handler configured withmin_body_length: 0should skip the check entirely. The implementation evaluatesconfig.min_body_length ? parseInt(...) : 0, so a configured0is falsy and falls through correctly — but there is no test asserting this path. -
Invalid config (negative value) — the handler throws when
minBodyLength < 0, but there is no test verifying the error message and failure path formin_body_length: -1. -
Go test naming — the new test case for
MinBodyLengthis added insideTestHandlerConfigBooleanFields. Integer fields and boolean fields have different semantics; this makes the test name misleading. Consider a dedicatedTestHandlerConfigIntegerFieldstable or renaming the parent to something neutral likeTestHandlerConfigFieldEmission.
[/diagnose] Parsing defensiveness
const minBodyLength = config.min_body_length ? parseInt(String(config.min_body_length), 10) : 0;The String(...) conversion defends against non-string inputs, but the config value arrives from JSON where numbers are always number type. parseInt(String(200), 10) is correct but redundant. A cleaner form: Number(config.min_body_length ?? 0) (or Math.trunc(...) if floats need guarding), which also pushes NaN naturally into the downstream validation check. Minor readability point only.
Positive highlights
- ✅ Defence-in-depth: both prompt contract and runtime enforcement guard against the bug — neither layer alone would be reliable.
- ✅ The test verifies that no GraphQL
createDiscussionmutation is called on rejection — asserting at the correct integration seam. - ✅ Schema, Go struct, handler config emission, docs, and compiled lock file are all updated consistently.
- ✅
min-body-lengthis a reusable feature, not a hard-coded hack for one workflow.
Verdict
The fix is correct and the approach is sound. The main gap is boundary and edge-case tests on the new guard itself (body at exactly 200 chars, guard disabled at 0, negative config). These are quick to add and would lock in the guard's contract. Happy to merge once those boundary tests are in place, or they can be tracked as an immediate follow-up.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 4.4M
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Updated in commits |
daily-compiler-qualitywas intermittently publishing discussions with a literal placeholder body (test) because the first emittedcreate_discussionitem was accepted and posted. This change hardens both the workflow prompt contract and safe-outputs enforcement so short/draft bodies fail instead of being published.Workflow contract + policy (daily-compiler-quality)
create_discussionitem and avoid draft/placeholder emissions.safe-outputs.create-discussion.min-body-length: 200in the workflow to enforce a non-trivial report body.Safe-outputs runtime guard (create_discussion handler)
min_body_lengthinactions/setup/js/create_discussion.cjs.Compiler/config/schema plumbing
min-body-lengthtoCreateDiscussionsConfigand handler config emission.main_workflow_schema.json) to validatesafe-outputs.create-discussion.min-body-length.Targeted coverage
min_body_lengthcreate_discussionruntime rejection for too-short bodies