feat: add body-header message type to safe outputs#29648
Conversation
Adds a new `body-header` message type to the safe-outputs messages system.
When configured, it prepends custom text to every message body generated
by safe outputs (issues, comments, pull requests, discussions).
The header is placed after any threat-detection caution alert and before
the agent-generated content.
Changes:
- Add `body-header` field to JSON schema with placeholders {workflow_name} and {run_url}
- Add `BodyHeader string` field to `SafeOutputMessagesConfig` Go struct
- Add parser for `body-header` in safe_outputs_messages_config.go
- Add `bodyHeader` to `SafeOutputMessages` typedef in messages_core.cjs
- Create messages_header.cjs with getBodyHeader() function
- Create messages_header.test.cjs with 6 tests
- Update messages.cjs barrel file with re-export
- Apply header injection in create_issue.cjs, add_comment.cjs,
create_discussion.cjs, and create_pull_request.cjs
- Add Go unit tests for body-header parsing and serialization
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/1769a58a-3232-4313-89ce-33a6b2cfc9ef
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
When using Array.unshift, the last call places content at the very beginning of the array. Fix the ordering in create_issue.cjs, create_discussion.cjs, and create_pull_request.cjs so that the body header is unshifted first and the detection caution is unshifted second, resulting in the correct order: caution → header → user content. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/1769a58a-3232-4313-89ce-33a6b2cfc9ef Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new body-header safe-outputs message template that can be configured to prepend a rendered header (with workflow/run placeholders) to generated bodies across safe-output handlers.
Changes:
- Extend schema + Go config types/parsing/serialization to support
messages.body-header. - Add JS
getBodyHeader()helper + unit tests; update messages barrel/types. - Update safe-output consumer scripts to insert the header between threat-detection caution and the generated/user content.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/safe_outputs_messages_test.go | Adds Go tests for parsing and JSON serialization of BodyHeader. |
| pkg/workflow/safe_outputs_messages_config.go | Parses body-header from the frontmatter messages map. |
| pkg/workflow/compiler_types.go | Adds BodyHeader to SafeOutputMessagesConfig with YAML/JSON tags. |
| pkg/parser/schemas/main_workflow_schema.json | Documents messages.body-header in the workflow schema with description/examples. |
| actions/setup/js/messages_header.cjs | Introduces getBodyHeader() that reads config and renders placeholders. |
| actions/setup/js/messages_header.test.cjs | Adds Vitest coverage for default/custom and placeholder rendering behavior. |
| actions/setup/js/messages_core.cjs | Extends SafeOutputMessages typedef with bodyHeader. |
| actions/setup/js/messages.cjs | Re-exports getBodyHeader from the messages barrel. |
| actions/setup/js/create_issue.cjs | Prepends body header (after caution via unshift ordering) for created issues. |
| actions/setup/js/create_discussion.cjs | Prepends body header (after caution via unshift ordering) for created discussions. |
| actions/setup/js/create_pull_request.cjs | Prepends body header for PR bodies (caution/header/body ordering logic updated). |
| actions/setup/js/add_comment.cjs | Prepends caution + body header prefix before comment content (string concat). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
actions/setup/js/create_pull_request.cjs:1143
- In the PR body builder, the caution insertion still adds two blank separator lines and the adjacent comment says this ensures the main body follows after a full empty line. With the new body header inserted between caution and the main body, those separator lines now separate the caution from the header instead, and the comment is no longer accurate. Consider adjusting the separator logic (e.g., number/placement of blank lines) and updating the comment so the final layout matches the intended caution → header → body ordering without unintended extra spacing.
// Inject CAUTION at top of body (unshifted after header so it appears first in the final output)
const detectionCaution = getDetectionCautionAlert(workflowName, runUrl);
if (detectionCaution) {
// unshift(caution, "", "") places the caution alert at index 0 and two blank
// separator lines so the main body content follows after a full empty line.
bodyLines.unshift(detectionCaution, "", "");
}
- Files reviewed: 12/12 changed files
- Comments generated: 0
🧪 Test Quality Sentinel ReportTest Quality Score: 89/100✅ Excellent test quality
Test Classification DetailsView All Test Classifications (8 tests)
Flagged Tests — Requires Review✅ No tests flagged. All new tests enforce observable behavioral contracts. Language SupportTests analyzed:
Scoring Breakdown
Verdict
📖 Understanding Test ClassificationsDesign Tests (High Value) verify what the system does:
Implementation Tests (Low Value) verify how the system does it:
Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators. References: §25238443803
|
Summary
Adds a new
body-headermessage type to the safe-outputs messages system. When configured, it prepends custom header text to every message body generated by safe outputs (issues, comments, pull requests, discussions).The header is placed after any threat-detection caution alert and before the agent-generated content.
Usage
Available placeholders:
{workflow_name},{run_url}(both camelCase and snake_case supported)Changes
Schema & Go
body-headerfield topkg/parser/schemas/main_workflow_schema.jsonwith description and examplesBodyHeader stringfield toSafeOutputMessagesConfigGo struct incompiler_types.goextractStringFromMapcall forbody-headerinsafe_outputs_messages_config.goJavaScript
bodyHeadertoSafeOutputMessagestypedef inmessages_core.cjsmessages_header.cjswithgetBodyHeader()function — returns empty string when not configuredmessages_header.test.cjswith 6 tests covering default, custom, placeholder, and edge casesmessages.cjsbarrel file to re-exportgetBodyHeaderConsumer scripts
create_issue.cjs— body header unshifted before caution so final order is: caution → header → user contentadd_comment.cjs— prefix built withcaution + header + user content(string concat)create_discussion.cjs— same pattern ascreate_issue.cjscreate_pull_request.cjs— same pattern ascreate_issue.cjsTests
body-headerparsing and JSON serialization tosafe_outputs_messages_test.go