post-findings — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited post-findings (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Post structured review findings from a TOME file to a GitHub PR as a formatted, collapsible markdown comment. Supports auto-detection of TOME path and PR number, baked-in v3.x severity filtering, dry-run preview, and idempotency.
/rune:post-findings # Auto-detect latest TOME + current branch PR
/rune:post-findings tmp/reviews/abc123/TOME.md # Specific TOME, auto-detect PR
/rune:post-findings tmp/reviews/abc123/TOME.md 42 # Specific TOME + specific PR#
/rune:post-findings --dry-run # Preview comment without posting
/rune:post-findings --force # Post even if already posted (skip idempotency)const args = "$ARGUMENTS".split(/\s+/).filter(Boolean)
let tomePath = null
let prNumber = null
let dryRun = false
let forcePost = false
for (const arg of args) {
if (arg === "--dry-run") { dryRun = true; continue }
if (arg === "--force") { forcePost = true; continue }
if (arg.endsWith(".md") || arg.includes("TOME") || arg.includes("tome")) {
tomePath = arg
} else if (/^[1-9]\d*$/.test(arg)) {
prNumber = arg
}
}If no TOME path provided, auto-detect the latest TOME from known output directories.
if (!tomePath) {
// Search order: arc output → review output → audit output
const searchDirs = ["tmp/arc/", "tmp/reviews/", "tmp/audit/"]
const tomeNames = ["TOME.md", "tome.md"]
for (const dir of searchDirs) {
// Glob for TOME files, sort by modification time (newest first)
const candidates = Glob(`${dir}**/TOME.md`) || Glob(`${dir}**/tome.md`) || []
if (candidates.length > 0) {
tomePath = candidates[0] // Most recently modified
break
}
}
if (!tomePath) {
error("No TOME file found. Run /rune:appraise or /rune:arc first, or specify a path.")
return
}
log(`Auto-detected TOME: ${tomePath}`)
}
// Validate TOME exists and is non-empty
if (!exists(tomePath)) {
error(`TOME file not found: ${tomePath}`)
return
}If no PR number provided, detect from the current branch.
if (!prNumber) {
// Use gh pr view to find PR for current branch
const prResult = Bash(`GH_PROMPT_DISABLED=1 gh pr view --json number -q '.number' 2>/dev/null`).trim()
if (prResult && /^[1-9]\d*$/.test(prResult)) {
prNumber = prResult
log(`Auto-detected PR: #${prNumber}`)
} else {
error("No PR found for current branch. Specify a PR number or push your branch first.")
return
}
}
// Validate PR number format (SEC: injection guard)
if (!/^[1-9]\d*$/.test(prNumber)) {
error(`Invalid PR number: ${prNumber}`)
return
}<!-- v3.x: defaults baked from former talisman.pr_comment; see references/v3-defaults.md -->
// v3.x bakes pr_comment defaults — there is no user config layer.
const severityFilter = ["P1", "P2"]
const confidenceThreshold = 50
const maxFindings = 30
const includeTraces = true
const includeFixSuggestions = true
const collapseThreshold = 5
const showFooter = true// Use tome-parser.sh to extract structured findings as JSON
const configJson = JSON.stringify({
severity_filter: severityFilter,
confidence_threshold: confidenceThreshold,
max_findings: maxFindings,
include_traces: includeTraces,
include_fix_suggestions: includeFixSuggestions
})
// SEC-001: Validate tomePath against strict allowlist (no shell metacharacters)
if (!/^[a-zA-Z0-9._\-\/]+\.md$/.test(tomePath)) {
error(`Invalid TOME path (contains disallowed characters): ${tomePath}`)
return
}
// SEC-004: Pass configJson via env var to avoid single-quote injection
const findingsJson = Bash(`RUNE_PR_CONFIG='${configJson.replace(/'/g, "'\\''")}' bash "${RUNE_PLUGIN_ROOT}/scripts/lib/tome-parser.sh" "${tomePath}" "$RUNE_PR_CONFIG"`)
// Validate parser output
let findings
try {
findings = JSON.parse(findingsJson)
} catch (e) {
error(`TOME parser returned invalid JSON. Check ${tomePath} for valid RUNE:FINDING markers.`)
return
}
if (!Array.isArray(findings) || findings.length === 0) {
log("No findings matched the configured filters. Nothing to post.")
return
}
log(`Parsed ${findings.length} findings (filter: ${severityFilter.join("+")} >= confidence ${confidenceThreshold})`)// Use pr-comment-formatter.sh to transform findings into GitHub markdown
const findingsFile = `tmp/.rune-pr-comment-findings-${Date.now()}.json`
Write(findingsFile, findingsJson)
const commentFile = `tmp/.rune-pr-comment-body-${Date.now()}.md`
// QUAL-003: Formatter reads findings from stdin, config from $1
const formatterConfig = JSON.stringify({ collapse_threshold: collapseThreshold, footer: showFooter })
Bash(`bash "${RUNE_PLUGIN_ROOT}/scripts/lib/pr-comment-formatter.sh" '${formatterConfig.replace(/'/g, "'\\''")}' < "${findingsFile}" > "${commentFile}"`)
// Validate output
if (!exists(commentFile) || Bash(`wc -c < "${commentFile}"`).trim() === "0") {
error("Comment formatter produced empty output.")
return
}if (dryRun) {
const preview = Read(commentFile)
log("=== DRY RUN — Comment Preview ===")
log(preview)
log("=== End Preview ===")
log(`Would post to PR #${prNumber}. Run without --dry-run to post.`)
// Cleanup temp files
Bash(`rm -f "${findingsFile}" "${commentFile}"`)
return
}// Build poster arguments
const forceArg = forcePost ? "--force" : ""
const postResult = Bash(`bash "${RUNE_PLUGIN_ROOT}/scripts/lib/pr-comment-poster.sh" "${prNumber}" "${commentFile}" ${forceArg}`)
if (postResult.includes("ERROR")) {
error(`Failed to post: ${postResult}`)
// Cleanup temp files
Bash(`rm -f "${findingsFile}" "${commentFile}"`)
return
}
// Cleanup temp files
Bash(`rm -f "${findingsFile}" "${commentFile}"`)if (postResult.includes("already posted")) {
log(`Findings already posted to PR #${prNumber}. Use --force to post again.`)
} else {
// Get PR URL for user convenience
const prUrl = Bash(`GH_PROMPT_DISABLED=1 gh pr view ${prNumber} --json url -q '.url' 2>/dev/null`).trim()
log(`Review findings posted to PR #${prNumber}`)
if (prUrl) log(`View: ${prUrl}`)
log(`${findings.length} findings posted (${severityFilter.join("+")} severity, >= ${confidenceThreshold} confidence)`)
}| Error | Recovery |
|---|---|
| No TOME found | Suggest running /rune:appraise or /rune:arc first |
| No PR for branch | Suggest specifying PR# or pushing branch with gh pr create |
gh not authenticated | Suggest gh auth login or gh auth refresh -s repo |
| TOME parse failure | Check TOME for valid RUNE:FINDING markers |
| Formatter empty output | Check TOME has findings matching configured filters |
| Post failure (API error) | Check gh auth status for repo scope |
| Comment already exists | Use --force flag to override idempotency check |
| Body exceeds 65K chars | Automatic truncation by poster script |
The skill exits early (with a clear message) when:
tmp/arc/, tmp/reviews/, or tmp/audit/gh pr view fails for current branch^[1-9]\d*$--force)eval^[1-9]\d*$ (rejects injection attempts).. or outside tmp/<!-- rune-review-findings --> HTML marker prevents duplicate comments~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.