You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
feat(cli): add step-summary blocks for rendered prompt and verdict (#739)
* feat(cli): add step-summary blocks for rendered prompt and verdict
Adds `--step-summary` to `threat-detect` (writes the prompt actually
rendered, plus resolved engine/model/retries, as a collapsible block)
and to `threat-detect conclude` (writes a verdict block with per-field
booleans, reasons, conclusion, and reason code for every terminal
outcome including skipped). Both default to $GITHUB_STEP_SUMMARY, are
best-effort (a write failure never changes the exit code), and bound
the prompt size to stay within the shared per-job step summary budget.
Closes#696
Co-authored-by: David Slater <12449447+davidslater@users.noreply.github.com>
* fix(cli): escape untrusted content and reject step-summary path collisions
Addresses review feedback on #739:
- HTML-escape and render the rendered prompt inside <pre><code>
instead of a Markdown fence, since the embedded artifact content can
contain a closing fence and spoof the job summary.
- HTML-escape and render verdict reasons inside <pre><code> for the
same reason, since reasons are engine-generated from untrusted
artifacts.
- Add rejectPathCollisions and use it to reject --step-summary
aliasing --log-file/--output in `threat-detect`, and --result-file/
$GITHUB_OUTPUT/$GITHUB_ENV in `threat-detect conclude`, so a
misconfigured alias fails closed instead of corrupting another
destination.
Co-authored-by: David Slater <12449447+davidslater@users.noreply.github.com>
---------
Co-authored-by: GitHub Ace <githubnext@users.noreply.github.com>
Co-authored-by: David Slater <12449447+davidslater@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
-`--custom-prompt-file` — Path to a file with additional detection instructions. Takes precedence over `--custom-prompt` and `CUSTOM_PROMPT`
64
64
-`--output` — Path to write JSON result (defaults to stdout)
65
65
-`--log-file` — Path to write structured JSONL run logs (one JSON object per line). Env: `THREAT_DETECTION_LOG_FILE`; defaults to `detection-runlog.jsonl` beside `--output`
66
+
-`--step-summary` — Path to append the rendered prompt (engine/model/retries plus the prompt actually sent, including the resolved prompt-analysis section) as a collapsible block in the job step summary. Defaults to `GITHUB_STEP_SUMMARY`
Copy file name to clipboardExpand all lines: cmd/threat-detect/conclude.go
+41-7Lines changed: 41 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -87,10 +87,12 @@ func runConclude(args []string) int {
87
87
fs.SetOutput(os.Stderr)
88
88
var (
89
89
resultFilestring
90
+
stepSummarystring
90
91
detectionLogstring
91
92
logFilestring
92
93
)
93
94
fs.StringVar(&resultFile, "result-file", defaultConcludeResultFile, "Path to the structured detection_result.json verdict file")
95
+
fs.StringVar(&stepSummary, "step-summary", os.Getenv("GITHUB_STEP_SUMMARY"), "Path to append the verdict to the job step summary (defaults to env GITHUB_STEP_SUMMARY)")
94
96
fs.StringVar(&detectionLog, "detection-log", "", "Path to the detection run's captured log, consulted to refine agent_failure/parse_error and to render diagnostics when the result file is missing (default: <result-file dir>/detection.log)")
95
97
fs.StringVar(&logFile, "log-file", os.Getenv("THREAT_DETECTION_LOG_FILE"), "Path to write JSONL run logs (env: THREAT_DETECTION_LOG_FILE)")
96
98
iferr:=fs.Parse(args); err!=nil {
@@ -103,6 +105,23 @@ func runConclude(args []string) int {
Copy file name to clipboardExpand all lines: cmd/threat-detect/main.go
+23-13Lines changed: 23 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -107,6 +107,7 @@ func run() (code int) {
107
107
promptFilestring
108
108
outputJSONstring
109
109
logFilestring
110
+
stepSummarystring
110
111
workflowNamestring
111
112
workflowDescriptionstring
112
113
customPromptstring
@@ -125,6 +126,7 @@ func run() (code int) {
125
126
flag.StringVar(&promptFile, "prompt-template", "", "Path to custom prompt template (defaults to built-in)")
126
127
flag.StringVar(&outputJSON, "output", "", "Path to write JSON result (defaults to stdout)")
127
128
flag.StringVar(&logFile, "log-file", os.Getenv("THREAT_DETECTION_LOG_FILE"), "Path to write JSONL run logs (env: THREAT_DETECTION_LOG_FILE)")
129
+
flag.StringVar(&stepSummary, "step-summary", os.Getenv("GITHUB_STEP_SUMMARY"), "Path to append the rendered prompt to the job step summary (defaults to env GITHUB_STEP_SUMMARY)")
128
130
flag.StringVar(&workflowName, "workflow-name", "", "Workflow name for the prompt (overrides WORKFLOW_NAME)")
129
131
flag.StringVar(&workflowDescription, "workflow-description", "", "Workflow description for the prompt (overrides WORKFLOW_DESCRIPTION)")
130
132
flag.StringVar(&customPrompt, "custom-prompt", "", "Additional detection instructions appended to the prompt (overrides CUSTOM_PROMPT)")
@@ -158,19 +160,17 @@ func run() (code int) {
158
160
logFile=dir+"detection-runlog.jsonl"
159
161
}
160
162
161
-
// Reject a --log-file that collides with --output: they are opened and
162
-
// truncated independently, so sharing an inode would interleave the JSONL
163
-
// trace and the result JSON and corrupt both while still reporting success.
0 commit comments