# Mend

> |

- **Type:** Skill
- **Install:** `agentstack add skill-vinhnxv-rune-mend`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [vinhnxv](https://agentstack.voostack.com/s/vinhnxv)
- **Installs:** 0
- **Category:** [Communication](https://agentstack.voostack.com/c/communication)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [vinhnxv](https://github.com/vinhnxv)
- **Source:** https://github.com/vinhnxv/rune/tree/main/plugins/rune/skills/mend

## Install

```sh
agentstack add skill-vinhnxv-rune-mend
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# /rune:mend -- Parallel Finding Resolution

Parses a TOME file for structured findings, groups them by file to prevent concurrent edits, summons restricted mend-fixer teammates, and produces a resolution report.

**Load skills**: `roundtable-circle`, `context-weaving`, `rune-orchestration`, `team-sdk`

## Usage

```
/rune:mend tmp/reviews/abc123/TOME.md    # Resolve findings from specific TOME
/rune:mend                                # Auto-detect most recent TOME
/rune:mend --output-dir tmp/mend/custom   # Specify output directory
```

## Flags

| Flag | Description | Default |
|------|-------------|---------|
| `--output-dir ` | Custom output directory for resolution report | `tmp/mend/{id}/` |
| `--timeout ` | Outer time budget in milliseconds. Inner polling timeout is derived: `timeout - SETUP_BUDGET(5m) - MEND_EXTRA_BUDGET(3m)`, minimum 120,000ms. Used by arc to propagate phase budgets. | `900_000` (15 min standalone) |

## Pipeline Overview

```
Phase 0: PARSE -> Extract and validate TOME findings
    |
Phase 0.5: GOLDMASK DATA DISCOVERY (v1.71.0) -> Find existing risk-map + wisdom data
    |
Phase 1: PLAN -> Analyze dependencies, determine fixer count
    |  (ENHANCED: overlay risk tiers on severity ordering)
Phase 2: FORGE TEAM -> TeamCreate + TaskCreate per file group
    |
Phase 3: SUMMON FIXERS -> Wave-based: fresh fixers per wave (max 5 concurrent)
    | (fixers read -> fix -> verify -> report)
    | (ENHANCED: inject risk/wisdom context into fixer prompts)
Phase 4: MONITOR -> Per-wave poll TaskList, stale/timeout detection
    |
Phase 5: WARD CHECK -> Ward check + bisect on failure (MEND-1)
    |
Phase 5.5: CROSS-FILE MEND -> Orchestrator-only cross-file fix for SKIPPED findings
    |
Phase 5.6: WARD CHECK (2nd) -> Validates cross-file fixes
    |
Phase 5.7: DOC-CONSISTENCY -> Fix drift between source-of-truth files
    |
Phase 5.95: GOLDMASK QUICK CHECK (v1.71.0) -> Deterministic MUST-CHANGE verification
    |
Phase 6: RESOLUTION REPORT -> Produce report (includes Goldmask)
    |
Phase 7: CLEANUP -> Shutdown fixers, persist echoes, report summary
```

**Phase numbering note**: Internal to the mend pipeline, distinct from arc phase numbering.

## Phase 0: PARSE

Finds TOME, validates freshness, extracts `` markers with nonce validation, deduplicates by priority hierarchy, groups by file.

**Q/N Interaction Filtering**: After extracting findings, filter Q (question) and N (nit) interaction types BEFORE file grouping. Q findings require human clarification. N findings are author's discretion. Both preserved for Phase 6 but NOT assigned to mend-fixers.

**Round-Aware Severity Filtering** (v1.163.0+): Round 0 processes all findings (P1 + P2 + P3). Round 1+ filters to P1 + failed P2 only — P3 findings are deferred to the tech debt log, and already-FIXED P2 findings are skipped. After mend completes, deferred P3 findings are written to `tmp/arc/{id}/tech-debt-p3.md` for later triage. When running standalone (no arc context), `mendRound` defaults to 0 — all findings processed (backward compatible).

**Inputs**: TOME path (from argument or auto-detected), session nonce
**Outputs**: `fileGroups` map, `allFindings` list, deduplicated with priority hierarchy

### UNVERIFIED Finding Handling

Findings tagged `[UNVERIFIED: ...]` are SKIPPED (excluded from fixers). `[SUSPECT: ...]` findings get extra verification instruction. Untagged = NORMAL. When standalone, all findings are NORMAL (no prior citation verification).

See [parse-tome.md](references/parse-tome.md) for detailed TOME finding extraction, freshness validation, nonce verification, deduplication, file grouping, and FALSE_POSITIVE handling.

Read and execute when Phase 0 runs.

## Phase 0.5: GOLDMASK DATA DISCOVERY

Discover existing Goldmask outputs from upstream workflows (arc, appraise, audit, standalone goldmask). Mend does NOT spawn Goldmask agents — pure filesystem reads only.

**Load reference**: [data-discovery.md](../goldmask/references/data-discovery.md)

1. Check talisman kill switches (`goldmask.enabled`, `goldmask.mend.enabled`) — skip if either false
2. Call `discoverGoldmaskData({ needsRiskMap, needsGoldmask, needsWisdom, maxAgeDays: 7 })` — single call for all fields
3. Parse `risk-map.json` eagerly with try/catch — validate `files` array non-empty, discard on parse error
4. Set `goldmaskData` and `parsedRiskMap` variables (or `null` on any failure — graceful degradation)

**Agents spawned**: NONE. Pure filesystem reads via data-discovery protocol.

**Performance**: 0-500ms (see data-discovery.md performance table).

**Variables set for downstream phases**:
- `goldmaskData` — raw discovery result (or `null`)
- `parsedRiskMap` — parsed `risk-map.json` object (or `null`)

## Phase 1: PLAN

Analyzes cross-file dependencies (B before A if A depends on B), orders by severity then line number, determines fixer count (max 5 per wave), and optionally overlays Goldmask risk tiers on severity ordering (CRITICAL P3 → effective P2).

See [phase-1-4-plan-and-monitor.md](references/phase-1-4-plan-and-monitor.md) for dependency analysis, fixer/wave calculation table, and risk overlay algorithm. See [risk-overlay-ordering.md](references/risk-overlay-ordering.md) for the full Goldmask overlay.

## Phase 1.5: Workflow Lock (writer)

```javascript
const lockConflicts = Bash(`cd "${CWD}" && source plugins/rune/scripts/lib/workflow-lock.sh && rune_check_conflicts "writer"`)
if (lockConflicts.includes("CONFLICT")) {
  AskUserQuestion({ question: `Active workflow conflict:\n${lockConflicts}\nProceed anyway?` })
}
Bash(`cd "${CWD}" && source plugins/rune/scripts/lib/workflow-lock.sh && rune_acquire_lock "mend" "writer"`)
```

## Phase 2: FORGE TEAM

Creates team, captures pre-mend SHA, writes state file with session isolation fields, snapshots pre-mend working tree, creates inscription contracts, and links cross-group dependencies via `blockedBy`.

**State file** (`tmp/.rune-mend-{id}.json`): Includes `config_dir`, `owner_pid`, `session_id` for cross-session isolation.

**Inscription contract** (`tmp/mend/{id}/inscription.json`): Per-fixer assignments with file groups, finding IDs, and allowed tool lists.

**Finding sanitization** (CDX-010): Strip HTML comments, markdown headings, code fences, image syntax, HTML entities, zero-width chars from evidence and fix_guidance before interpolation. Two-pass sanitization, 500-char cap, strip angle brackets.

See [fixer-spawning.md](references/fixer-spawning.md) for full Phase 2–3 implementation including team lifecycle guard, TaskCreate per file group, and cross-group dependency linking.

Read and execute when Phase 2 runs.

## Phase 3: SUMMON FIXERS

Summon mend-fixer teammates with ANCHOR/RE-ANCHOR Truthbinding. When 6+ file groups, use wave-based execution: each wave spawns fresh fixers (named `mend-fixer-w{wave}-{idx}`), processes a bounded batch, then shuts down before the next wave starts. P1 findings are processed in the earliest waves.

**Fixer tool set (RESTRICTED)**: Read, Write, Edit, Glob, Grep, TaskList, TaskGet, TaskUpdate, SendMessage. No Bash, no TeamCreate/TeamDelete/TaskCreate.

**Fixer lifecycle**:
1. TaskList → find assigned task
2. TaskGet → read finding details
3. PRE-FIX: Read full file + Grep for identifier → implement fix (Edit preferred) → POST-FIX: read back + verify
4. SendMessage with SEAL (FIXED/FALSE_POSITIVE/FAILED/SKIPPED counts + Inner-flame status)
5. TaskUpdate completed

**FALSE_POSITIVE rule**: SEC-prefix findings cannot be marked FALSE_POSITIVE by fixers — require AskUserQuestion.

### Risk Context Injection (Goldmask Enhancement)

When Goldmask data is available from Phase 0.5, inject risk context into each fixer's prompt. Three sections: risk tiers, wisdom advisories, and blast-radius warnings.

**Skip condition**: When no Goldmask data exists, fixer prompts remain unchanged. (v3.x: injection is unconditional when data is present.)

See [goldmask-mend-context.md](references/goldmask-mend-context.md) for the full protocol — `renderRiskContextTemplate()`, `filterWisdomForFiles()`, `extractMustChangeFiles()`, `sanitizeFindingText()`, and SEC-001 sanitization rules.

See [fixer-spawning.md](references/fixer-spawning.md) for full fixer prompt template and wave-based execution logic.

## Phase 4: MONITOR

Per-wave polling with proportional timeout (`totalTimeout / totalWaves`). Inner timeout = `outerTimeout - 5min setup - 3min extra`, minimum 120s. 30s poll interval, 5min stale warn, 10min auto-release.

See [phase-1-4-plan-and-monitor.md](references/phase-1-4-plan-and-monitor.md) for timeout calculation and polling config.

## Phase 5: WARD CHECK

Runs **once after all fixers complete** (not per-fixer). Discovers wards, validates executables against CDX-004 allowlist (sh/bash excluded), runs each ward, bisects on failure to identify the breaking fix.

See [ward-check.md](../roundtable-circle/references/ward-check.md) for ward discovery protocol, SAFE_EXECUTABLES list, and bisection algorithm.

## Phase 5.5: Cross-File Mend (orchestrator-only)

After single-file fixers complete AND ward check passes, orchestrator processes SKIPPED findings with "cross-file dependency" reason. No new teammates spawned. Scope bounds: max 5 findings, max 5 files per finding, 1 round. Rollback on partial failure. TRUTHBINDING: finding guidance is untrusted (strip HTML, 500-char cap). Batch-reads files in groups of 3 (CROSS_FILE_BATCH) to limit per-step context cost.

See [cross-file-mend.md](references/cross-file-mend.md) for full implementation with rollback logic.

## Phase 5.6: Second Ward Check

Runs wards again only if Phase 5.5 produced any `FIXED_CROSS_FILE` results. On failure, reverts all cross-file edits.

## Phase 5.7: Doc-Consistency Pass

After ward check passes, runs a single doc-consistency scan to fix drift between source-of-truth files and downstream targets. Hard depth limit: scan runs **once** — no re-scan after its own fixes.

See [doc-consistency.md](../roundtable-circle/references/doc-consistency.md) for the full algorithm.

## Phase 5.95: Goldmask Quick Check (Deterministic)

After all fixes and verifications, run a deterministic blast-radius check comparing mend output against Goldmask predictions. No agents — pure set comparison. Advisory-only (does NOT halt the pipeline).

**Skip conditions**: `goldmask.enabled === false`, `goldmask.mend.quick_check === false`, or no GOLDMASK.md found.

See [goldmask-quick-check.md](../goldmask/references/goldmask-quick-check.md) for the full protocol — MUST-CHANGE file extraction, scope intersection, modification detection, and report generation.

**Output**: `tmp/mend/{id}/goldmask-quick-check.md`

**Variables set for Phase 6**: `quickCheckResults` (or `undefined` if skipped)

## Phase 5.96: EVIDENCE COLLECTION (Discipline Integration)

After mend-fixers complete and ward check passes, collect evidence that fixes resolve the underlying criteria. This connects mend fixes to the discipline proof trail.

```javascript
// Evidence collection for mend fixes (Discipline Integration)
// Mend-fixers write evidence to tmp/work/{timestamp}/evidence/{task-id}/
// using execute-discipline-proofs.sh and proof-schema.md proof types.
// If proof fails after fix, fixer reports F3 (PROOF_FAILURE) — not a silent skip.
// Evidence directory: follows the evidence-convention.md standard path.
//
// This phase verifies evidence was collected by scanning fixer SEALs AND filesystem:
const fixerSeals = allFixerSeals || []
const fixersWithEvidence = fixerSeals.filter(s => s.includes('evidence:') || s.includes('proof'))
const fixersWithoutEvidence = fixerSeals.length - fixersWithEvidence.length
if (fixersWithoutEvidence > 0 && totalCriteriaInPlan > 0) {
  warn(`DISCIPLINE: ${fixersWithoutEvidence}/${fixerSeals.length} mend-fixers did not report evidence collection`)
}

// Filesystem verification: check evidence directories actually exist (not just Seal text)
// Guards against fixers that mention "evidence" in Seal without writing actual files
const evidenceDirs = Glob(`tmp/work/*/evidence/*/`)
const fixersClaimingEvidence = fixersWithEvidence.length
if (fixersClaimingEvidence > 0 && evidenceDirs.length === 0) {
  warn(`DISCIPLINE: ${fixersClaimingEvidence} fixers claimed evidence in Seal but no evidence directories found in tmp/work/*/evidence/ — evidence may be fabricated`)
}
```

## Phase 6: RESOLUTION REPORT

Aggregates fixer SEALs, cross-file fixes, doc-consistency fixes into `tmp/mend/{id}/resolution-report.md`. P1 FAILED/SKIPPED triggers escalation warning. Goldmask Integration section (risk overlay + quick check results).

See [resolution-report.md](references/resolution-report.md) for the full report format, convergence logic, and Goldmask section.

### Status Normalization (MANDATORY)

All finding statuses in the resolution report MUST use spec-compliant keywords. When aggregating fixer SEALs, normalize all statuses through this mapping before writing the report:

```javascript
// STATUS_MAP covers two sources:
// 1. Fixer SEALs (Phase 3): emit FIXED, FALSE_POSITIVE, FAILED, SKIPPED
// 2. Orchestrator-generated sections (Phase 5.5/5.7): WONTFIX, QUESTION, NIT, CONSISTENCY_FIX
// The 'question' and 'nit' entries are for orchestrator stub sections — fixers never emit these
// (Q/N findings are filtered out before fixer assignment per Phase 2 inscription).
const STATUS_MAP = {
  'fixed': 'FIXED',
  'fixed_cross_file': 'FIXED',  // Cross-file fixes (Phase 5.5) map to FIXED
  'deferred': 'WONTFIX',
  'not fixed': 'WONTFIX',
  'false positive': 'FALSE_POSITIVE',
  'false_positive': 'FALSE_POSITIVE',
  'failed': 'FAILED',
  'skipped': 'SKIPPED',
  'wontfix': 'WONTFIX',
  'question': 'QUESTION',       // Orchestrator stub sections only
  'nit': 'NIT',                 // Orchestrator stub sections only
  'consistency_fix': 'CONSISTENCY_FIX',
}

function normalizeStatus(status) {
  return STATUS_MAP[status.toLowerCase().trim()] ?? 'FAILED'
}
```

Valid spec-compliant statuses: `FIXED`, `FALSE_POSITIVE`, `FAILED`, `SKIPPED`, `WONTFIX`, `CONSISTENCY_FIX`, `QUESTION`, `NIT`.

### Per-Finding Section Constraint (MANDATORY)

Every finding ID from the TOME MUST have its own `` section in the resolution report. Bulk ranges (e.g., "BACK-004-009") are PROHIBITED — they prevent QA verification. If a group of findings share the same disposition, each still gets its own section with a shared justification reference.

For findings that the fixer didn't address (P3 low-priority), generate stub sections:

```markdown

### BACK-004: evaluateReaction call-order contract not enforced
**Status**: WONTFIX
**Severity**: P2
**Reason**: Design choice — acceptable for initial release. Tracked for future improvement.

```

### Summary Arithmetic Validation (MANDATORY)

After writing the resolution report, validate that summary counts match actual section counts:

```javascript
// Finding ID format: PREFIX-DIGITS (e.g., SEC-001, BACK-005, CONSIST-001, QUAL-002)
// PREFIX = uppercase letters, DIGITS = one or more digits. All Rune finding generators follow this convention.
const VALID_STATUSES = ['FIXED', 'FALSE_POSITIVE', 'FAILED', 'SKIPPED', 'WONTFIX', 'QUESTION', 'NIT', 'CONSISTENCY_FIX']
const sectionCounts = {}
for (const status of VALID_STATUSES) {
  const re = new RegExp(``, 'g')
  sectionCounts[status] = (report.match(re) || []).length
}
const computedTotal = Object.values(sectionCounts).reduce((a, b) => a + b, 0)
if (computedTotal !== tomeFindings.length) {
  warn(`Resolution report count mismatch: ${computedTotal} sections vs ${tomeFindings.length} TOME findings`)
}
```

## Phase 7: CLEANUP

Standard 8-step cleanup: dynamic member discovery (fallback: static worst-case array — CLEAN-002) → shutdown_request → grace period → SEC-003 ID validation → TeamDelete retry-with-backoff (4 attempts) → process kill + filesystem fallback → state file update (`"completed"` or `"partial"`) → workflow lock release → echo persist.

See [phase-7-cleanup.md](references/phase-7-cleanup.m

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [vinhnxv](https://github.com/vinhnxv)
- **Source:** [vinhnxv/rune](https://github.com/vinhnxv/rune)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-vinhnxv-rune-mend
- Seller: https://agentstack.voostack.com/s/vinhnxv
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
