Skip to content

Render grader values in collapsible step summary - #55823

Merged
pelikhan merged 3 commits into
mainfrom
copilot/update-graders-section-summary
Aug 25, 2026
Merged

pelikhan merged 3 commits into
mainfrom
copilot/update-graders-section-summary

Conversation

Copilot AI commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Graders now use progressive disclosure in the step summary and display every computed value, including built-in grader results, without emoji status indicators.

  • Summary rendering

    • Replaces the expanded Graders table with a <details> section.
    • Uses textual status labels: Pass, Fail, and Error.
  • Value coverage

    • Renders all results with computed numeric values.
    • Preserves grader name, source, value, and unit.
  • Safety

    • Escapes dynamic table cells to prevent malformed Markdown or HTML rendering.
<details>
<summary>Graders</summary>

| Status | Grader | Source | Value | Unit |
| --- | --- | --- | --- | --- |
| Pass | Tool success rate | builtin | 0.9877 | ratio |
</details>

Copilot AI and others added 2 commits August 25, 2026 16:26
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 Render grader values in step summary details Render grader values in collapsible step summary Aug 25, 2026
Copilot AI requested a review from pelikhan August 25, 2026 16:33
@pelikhan
pelikhan marked this pull request as ready for review August 25, 2026 16:33
Copilot AI balanced review requested due to automatic review settings August 25, 2026 16:33

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 collapsible grader summaries with textual statuses, computed values, and sanitized table cells.

Changes:

  • Adds grader summary rendering and progressive disclosure.
  • Adds tests for values, statuses, and escaping.
Show a summary per file
File Description
actions/setup/js/trace_graders.cjs Builds and renders the collapsible grader table.
actions/setup/js/trace_graders.test.cjs Tests summary values and sanitization.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Balanced

...rows,
]);
}
core.summary.addDetails("Graders", buildGradersSummaryBody(results));
Comment thread actions/setup/js/trace_graders.cjs
@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

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

No ADR enforcement needed: PR does not have the implementation label and has 0 new lines of code in business logic directories (default_business_additions=0).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

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

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #55823

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-25T00:00:00Z
review_event: REQUEST_CHANGES
top_themes:
  - broken step-summary table rendering inside addDetails
  - incomplete escaping for untrusted markdown table cells
files_reviewed:
  - actions/setup/js/trace_graders.cjs
  - actions/setup/js/trace_graders.test.cjs
comment_count: 2

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 7.34 AIC · ⌖ 7 AIC · ⊞ 7K · ◷
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.

Request changes

This summary rewrite introduces two rendering/correctness regressions in the changed lines: the <details> body is emitted in a form GitHub won't render as a table, and the new table-cell escaping is still bypassable by backslash-prefixed pipes.

Blocking themes
  • The step summary markup is malformed for GitHub's Markdown parser, so grader results lose their tabular rendering.
  • The new sanitizer does not fully neutralize untrusted table-cell content, so crafted grader metadata can still break the table layout.

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 7.34 AIC · ⌖ 7 AIC · ⊞ 7K
Comment /review to run again

...rows,
]);
}
core.summary.addDetails("Graders", buildGradersSummaryBody(results));

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.

This summary table is still broken in the step summary: @actions/core's addDetails() does not insert the blank lines GitHub-flavored Markdown needs before a table, so the rows render as literal text instead of a table and the closing </details> can end up glued to the last row.

💡 Why this matters

The previous addTable() implementation produced a valid table automatically. This replacement regresses the UI for every run, which defeats the purpose of surfacing grader results in a readable summary.

A safe fix is to wrap the generated body with blank lines, or build the details block manually:

core.summary
  .addRaw("<details><summary>Graders</summary>\n\n")
  .addRaw(buildGradersSummaryBody(results))
  .addRaw("\n\n</details>\n");

Alternatively, make buildGradersSummaryBody() return leading/trailing blank lines and add a regression test around the final summary markup.

function sanitizeSummaryText(value) {
return String(value ?? "")
.replace(/\r?\n/g, " ")
.replace(/\|/g, "\\|")

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.

The Markdown escaping here is incomplete: if a cell already contains a backslash before a pipe (for example A\\|B), this replacement turns it into A\\\\|B, which GitHub Markdown reduces back to an escaped backslash plus a real column separator. That lets untrusted grader data still split the table and corrupt the summary.

💡 Why this matters

This helper is meant to harden untrusted grader names/sources/units before putting them into a Markdown table. Right now it only handles the simple | case, so crafted input can still break the table layout.

Escape backslashes before pipes (or avoid Markdown tables entirely for untrusted content), and add a regression test for an input like "A\\|B":

return String(value ?? "")
  .replace(/\\/g, "\\\\")
  .replace(/\|/g, "\\|")
  .replace((r/redacted)?\n/g, " ")
  ...

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

Impeccable Review — critique + audit

The refactor to wrap graders in a collapsible <details> block is a good UX improvement that reduces noise in the step summary. Two existing comments already flag the blocking issues; one additional observation below.

Summary of findings

Severity Issue Status
🔴 Blocking addDetails renders raw markdown inside <details> — table may not render correctly without surrounding blank lines Existing comment (line 838)
🔴 Blocking sanitizeSummaryText escapes | without first escaping existing backslashes — bypass possible Existing comment (line 463)
🟡 Non-blocking statusLabels["error"] and statusLabels["unavailable"] are dead keys — they can never appear in the output New (see below)

Dead keys in statusLabels

buildGradersSummaryBody filters with hasComputedValue, keeping only results where typeof result.value === "number". In practice, "error" and "unavailable" results carry value: null, so "Error" and "Unavailable" labels are unreachable. The fallback || "Unknown" would trigger first for any future unknown status. Consider removing those dead keys or adding a comment documenting the assumption.

The two blocking issues in the existing comments should be resolved before merging.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet46 · 20.5 AIC · ⌖ 9.14 AIC · ⊞ 6.2K

@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 /codebase-design — two prior comments (from Copilot) already cover the main bugs; one new comment added for test coverage.

📋 Key Themes & Highlights

Findings

  • Escaping order bug (line 463, existing comment): | is escaped before <>&, so a cell containing \| still leaks. Fix: escape backslashes first, or escape in a single pass.
  • addDetails blank-line requirement (line 838, existing comment): GitHub renders inline HTML table as literal text without blank lines around the content string. Add \n\n before and after the table in buildGradersSummaryBody.
  • Missing empty-results test (new comment): the "No grader values available." branch has no test.

Positive Highlights

  • ✅ hasComputedValue type guard is a clean, reusable predicate.
  • ✅ buildGradersSummaryBody is properly unit-tested and exported.
  • ✅ Textual status labels (Pass/Fail/Error) are more accessible than emoji-only indicators.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet46 · 25.1 AIC · ⌖ 9.93 AIC · ⊞ 7.6K
Comment /matt to run again

expect(summary).toContain("Custom \\| &lt;grader&gt;");
expect(summary).toContain("inline\\|source");
expect(summary).toContain("unit\\|&amp;");
});

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] Missing test for the empty-results branch — buildGradersSummaryBody([]) should return "No grader values available.", but there's no assertion covering that path.

💡 Suggested test
it("returns a message when no grader has a computed value", () => {
  const summary = buildGradersSummaryBody([
    { id: "no-value", name: "No value", value: null, unit: "", status: "unavailable", source: "builtin" },
  ]);
  expect(summary).toBe("No grader values available.");
});

Without this test the fallback message can silently regress.

@copilot please address this.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Ran the pr-finisher pass. Addressed both open review threads in 26c3a58:

  • Backslashes are now escaped before pipes in sanitizeSummaryText, so A\|B can no longer break out of a table cell.
  • The <details> body is wrapped in blank lines so GitHub parses the table as Markdown instead of literal text.
  • Added regression tests for both cases (78 tests pass in trace_graders.test.cjs).

Local validation: make agent-report-progress passed (fmt, lint, impacted Go tests, setup JS tests). Prior CI on the previous HEAD was green; CI on the new HEAD is unverified because agent pushes don't trigger workflows — a maintainer needs to approve/re-trigger the runs before merge.

@pelikhan
pelikhan merged commit 3947d9b into main Aug 25, 2026
10 checks passed
@pelikhan
pelikhan deleted the copilot/update-graders-section-summary branch August 25, 2026 17:47
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.87.8

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.

3 participants