appraise — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited appraise (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.
Runtime context (preprocessor snapshot):
find tmp -maxdepth 1 -name '.rune-*-*.json' -exec grep -l '"running"' {} + 2>/dev/null | wc -l | tr -d ' 'git branch --show-current 2>/dev/null || echo "unknown"Orchestrate a multi-agent code review using the Roundtable Circle architecture. Each Ash gets its own dedicated context window via Agent Teams.
Load skills: roundtable-circle, context-weaving, rune-orchestration, team-sdk
When a plan_file_path is available (passed via arc Phase 6, or set in the inscription context), reviewers receive plan acceptance criteria in their inscription context. This enables spec-aware review — checking "does code match spec" in addition to "is code good".
Plan context injection (3 items added to reviewer inscription):
Review findings can reference plan criteria IDs (AC-N) when applicable:
BACK-003 (P2): AC-2.3 (rate limiting) not fully implemented — missing 429 response codeWithout plan: Standard code quality review ("Code is clean, LGTM") With plan: Spec-aware review ("AC-3 timeout handling not implemented in src/api.ts")
Activation: Automatic when plan_file_path is in the orchestration params or inscription context. No flag needed — the presence of plan context activates spec-aware behavior.
Appraise sets these parameters before delegating to the shared orchestration-phases.md:
const params = {
scope: "diff", // Always diff for appraise (changed files only)
depth: flags['--deep'] ? "deep" : "standard", // Standard by default, deep with --deep
teamPrefix: "rune-review",
outputDir: `tmp/reviews/${identifier}/`,
stateFilePrefix: "tmp/.rune-review",
identifier, // "{gitHash}-{shortSession}"
timeoutMs: 600_000, // 10 min
label: "Review",
workflow: "rune-review",
focusArea: "full", // Appraise has no --focus flag
// + configDir, ownerPid, sessionId (session isolation)
// + selectedAsh, fileList, maxAgents, flags
}Standard depth (default): Single-pass review with up to 7 Wave 1 Ashes. Identical to pre-deep behavior.
Deep depth (--deep): Multi-wave review. Phase 3 loops over waves from selectWaves(). Each wave creates its own team, tasks, and monitor cycle. See orchestration-phases.md for the full wave execution loop.
| Flag | Description | Default |
|---|---|---|
--deep | Run multi-wave deep review: Wave 1 (core, up to 7 Ashes) + Wave 2 (investigation, 4 Ashes) + Wave 3 (dimension, up to 7 Ashes). Each wave runs as a full Roundtable Circle pass. | Off |
--partial | Review only staged files (git diff --cached) instead of full branch diff | Off |
--dry-run | Execute Phase 0 (Pre-flight) and Phase 1 (Rune Gaze) only. Display changed files, Ash selections, chunk plan, then exit. Does NOT create teams, tasks, state files, or spawn agents. | Off |
--max-agents <N> | Limit total Ash summoned (1-7 in standard mode; up to 18 in --deep). Priority: Ward Sentinel > Forge Warden > Veil Piercer > Pattern Weaver > Glyph Scribe > Knowledge Keeper > Doubt Seer | All selected |
--no-chunk | Force single-pass review (disable chunking) | Off |
--chunk-size <N> | Override chunk threshold — file count that triggers chunking (default: 20) | 20 |
--no-converge | Disable convergence loop — single review pass per chunk | Off |
--cycles <N> | Run N standalone review passes with TOME merge (1-5, numeric only) | 1 |
--scope-file <path> | Override changed_files with a JSON file { focus_files: [...] }. Used by arc convergence controller | None |
--no-lore | Disable Phase 0.5 Lore Layer (git history risk scoring) | Off |
--auto-mend | Automatically invoke /rune:mend after review if P1/P2 findings exist | Off |
Partial mode is useful for reviewing a subset of changes before committing.
Deep mode runs 3 waves of review with up to 18 Ashes total. See orchestration-phases.md for the wave execution pattern and wave-scheduling.md for wave selection logic.
Dry-run mode executes Phase 0 (Pre-flight) and Phase 1 (Rune Gaze) only, then displays changed files classified by type, which Ash would be summoned, file assignments per Ash, estimated team size, and chunk plan if file count exceeds CHUNK_THRESHOLD. No teams, tasks, state files, or agents are created. If --deep + --partial is used, displays a warning about sparse findings from investigation Ashes.
| Combination | Behavior |
|---|---|
--deep + --partial | Warning: "Deep review on staged-only changes may produce sparse findings from investigation Ashes." Proceeds (not a hard error). |
--deep + --cycles N (N > 1) | Warning: "Deep review with N cycles runs N x 3 waves (up to {N*18} agent invocations). This is expensive." Proceeds. |
--deep + --max-agents N | Applies to Wave 1 only. Wave 2/3 agents are not subject to --max-agents cap (they are deepOnly). |
--deep + --no-converge | Deep waves still execute. --no-converge affects per-chunk convergence, not wave scheduling. |
const lockConflicts = Bash(`cd "${CWD}" && source plugins/rune/scripts/lib/workflow-lock.sh && rune_check_conflicts "reader"`)
if (lockConflicts.includes("CONFLICT")) {
AskUserQuestion({ question: `Active workflow conflict:\n${lockConflicts}\nProceed anyway?` })
} else if (lockConflicts.includes("ADVISORY")) {
// ADVISORY = reader/planner + writer coexistence (see workflow-lock.sh compatibility matrix)
// SEC-6 FIX: sanitize lockConflicts output before interpolation
const sanitizedConflicts = lockConflicts.replace(/[<>&"']/g, '')
log(`Other workflow(s) detected in separate session(s):\n${sanitizedConflicts}\nCross-session concurrency is supported — proceeding normally.`)
}
Bash(`cd "${CWD}" && source plugins/rune/scripts/lib/workflow-lock.sh && rune_acquire_lock "appraise" "reader"`)Collect changed files and generate diff ranges. For detailed scope algorithms, staged/unstaged/HEAD~N detection, chunk routing, and --scope-file override logic — see review-scope.md.
Core steps:
default_branch from git remote/fallbackchanged_files — committed + staged + unstaged + untracked (or staged-only for --partial)Abort conditions:
After file collection — route to chunked path if changed_files.length > CHUNK_THRESHOLD and --no-chunk is not set. Route to multi-pass if --cycles N with N > 1. Note: --cycles N is an alternative to chunking — it runs N standalone review passes with TOME merge between passes, useful for catching issues that require multiple passes.
Gathers PR metadata and linked issue context. Injects contextIntel into inscription.json (Phase 2). Includes sanitizeUntrustedText() for CDX-001/CVE-2021-42574 protection. Skipped when no gh CLI or --partial. Always enabled in v3.x.
Discovers project linters (eslint, prettier, ruff, clippy, etc.) to suppress duplicate findings. SEC-/VEIL- findings are NEVER suppressed. Always enabled in v3.x.
See phase-0.3-0.4-context-and-linter.md for full pseudocode and sanitization function.
Runs BEFORE team creation. Summons lore-analyst as a bare Agent (no team yet — ATE-1 exemption). Outputs risk-map.json and lore-analysis.md. Re-sorts changed_files by risk tier (CRITICAL → HIGH → MEDIUM → LOW → STALE).
Skip conditions: non-git repo, --no-lore, fewer than 5 commits in lookback window (G5 guard). Lore layer is enabled by default in v3.x.
<!-- v3.x: defaults baked from former talisman.review; see references/v3-defaults.md -->
Runs BEFORE team creation. Spawns context-builder as a bare Agent (no TaskCreate, no team_name — same pattern as Phase 0.5 Lore Layer). Produces context-map.md for injection into Ash prompts.
Gate logic (hardcoded in v3.x):
const contextBuilding = "auto"
const threshold = { lines: 500, files: 5 }
const timeoutMs = 60000
if (flags['--dry-run']) → skip
if (diffLineCount > threshold.lines || fileCount >= threshold.files) → run
else → skip("[Context] Skipped — diff below threshold ({diffLineCount} lines, {fileCount} files)")Execution (blocking bare Agent with elapsed-time timeout check; note the timeout is a post-hoc elapsed-time warning, not a hard preemptive kill — the Agent tool does not support explicit timeouts):
const contextOutputPath = `${outputDir}context-map.md`
// Sanitize file paths before injecting into prompt (SEC-002)
// Strip newlines/carriage returns that could inject instructions, truncate long paths
const sanitizedFiles = changedFiles.map(f =>
f.replace(/[\n\r]/g, '').slice(0, 256)
)
// Use blocking Agent call; elapsed-time check below is advisory only (not a hard timeout)
const contextStartTime = Date.now()
Agent({
subagent_type: "rune:research:context-builder",
prompt: `Build a LIGHTWEIGHT context map for code review (not full audit).
SCOPE: Only analyze these changed files and their direct imports:
${sanitizedFiles.map(f => '- ' + f).join('\n')}
OUTPUT: Write to ${contextOutputPath}. Format:
## Trust Boundaries (max 5 entries)
- [BOUNDARY-N] {description} at {file:line} via {mechanism}
## Data Flow Paths (max 5 entries)
- [FLOW-N] {source} → {transform} → {sink} (files: {list})
## State Invariants (max 5 entries)
- [INV-N] {description} — ENFORCED|ASSUMED at {file:line}
## Entry Points (max 5 entries)
- [ENTRY-N] {route/handler} at {file:line} — reaches changed code via {path}
## Key Dependencies (max 5 entries)
- [DEP-N] {module} — guarantees: {what it provides}
CONSTRAINTS:
- Total output MUST be under 80 lines (2000 token budget)
- ONLY map architecture relevant to the changed files
- Cite file:line for every claim
- COMPREHENSION ONLY — do NOT report vulnerabilities
- Time budget: 45 seconds (leave 15s buffer for I/O)`,
model: "sonnet"
})
// Check timeout after blocking call returns (timeoutMs hardcoded to 60000 in v3.x)
// Known limitation: context_building_timeout is a soft budget advisory via prompt instruction,
// not a hard platform-level timeout. The Agent tool does not support explicit timeouts.
const contextElapsed = Date.now() - contextStartTime
if (contextElapsed > timeoutMs) {
warn(`[Context] Context building exceeded ${timeoutMs}ms (took ${contextElapsed}ms)`)
}
// Read output with existence check
contextMap = null
try {
const content = Read(contextOutputPath)
if (content && content.trim().length >= 100) {
contextMap = content
log(`[Context] Built context map — ${countEntries(content)} entries (${contextElapsed}ms)`)
} else {
log("[Context] Context map too small or empty — proceeding without context")
}
} catch {
log("[Context] Context builder timed out or failed — proceeding without context")
}Skip conditions: --dry-run, diff below auto thresholds (500 lines / 5 files).
Classifies changed files by extension → selects Ashes. Custom Ash discovery (agent-backed + CLI-backed) happens here. --dry-run exits after this phase.
See phase-1-rune-gaze.md for full classification table, UX gate, and dry-run exit. See rune-gaze.md for the base algorithm.
Creates session-scoped identifier ({gitHash}-{shortSession}), writes state file with session isolation, generates inscription.json (diff_scope + context_intelligence + linter_context), runs teamTransition protocol, creates signal dir, and creates one task per Ash.
See phase-2-forge-team.md for full pseudocode. See engines.md for teamTransition protocol.
Read and execute ash-summoning.md for the full prompt generation contract, inscription contract, custom Ashes, CLI-backed Ashes, and elicitation sage security context.
Key rules:
../../agents/{category}/{role}.mdroundtable-circle/references/custom-ashes.mdtmp/reviews/{identifier}/changed-files.txt — do NOT embed raw paths in prompts (SEC-006)Poll TaskList with timeout guard until all tasks complete. Uses the shared polling utility — see skills/roundtable-circle/references/monitor-utility.md.
POLL_INTERVAL = 30 // seconds
MAX_ITERATIONS = 20 // ceil(600_000 / 30_000) = 20 cycles = 10 min timeout
STALE_WARN = 300_000 // 5 minutes
for iteration in 1..MAX_ITERATIONS:
1. Call TaskList tool ← MANDATORY every cycle
2. Count completed vs ashCount
3. If completed >= ashCount → break
4. Check stale: any task in_progress > 5 min → log warning
5. Call Bash("sleep 30", { run_in_background: true })Stale detection: If a task is in_progress for > 5 minutes, log a warning. No auto-release — review Ash findings are non-fungible.
Read and execute tome-aggregation.md for the full Runebinder aggregation, Doubt Seer cross-examination, diff-scope tagging, and Truthsight verification protocols.
Summary of phases:
doubt_seer.enabled = false). When enabled, cross-examines P1/P2 findings with 5-min timeout. VERDICT: BLOCK sets workflow_blocked flag.SEC > BACK > VEIL > DOUBT > PY > TSR > RST > PHP > FAPI > DJG > LARV > SQLA > TDD > DDD > DI > API > DOM > PERF > FLOW > DOC > QUAL > FRONT > DES > AESTH > UXF > UXC > CDX (hardcoded — see references/v3-defaults.md settings.dedup_hierarchy). Writes TOME.md. Every finding MUST be wrapped in <!-- RUNE:FINDING ... --> markers for mend parsing. (UXH/UXI retired in v3.0.0-alpha.3 — see CHANGELOG.)scope="in-diff" or scope="pre-existing".Dynamic member discovery → shutdown_request → grace period → TeamDelete with retry-with-backoff (4 attempts) → filesystem fallback → release workflow lock → update state file → present TOME → auto-mend or interactive prompt.
See phase-7-cleanup.md for full pseudocode.
| Error | Recovery |
|---|---|
| Ash timeout (>5 min) | Proceed with partial results |
| Total timeout (>10 min) | Final sweep, collect partial results, report incomplete |
| Ash crash | Report gap in TOME.md |
| ALL Ash fail | Abort, notify user |
| Concurrent review running | Warn, offer to cancel previous |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.