Table of Contents generated with DocToc

skill-reconciler-diff

Capability: substrate:framework-dev

Harness: agnostic

A deterministic uv tool that parses two SKILL.md skill trees into normalised structural representations and emits a JSON diff. The output grounds the skill-reconciler skill’s ALLOWED / DRIFT / SAFETY-BASELINE classification decisions in a structured object rather than a raw text comparison.

The tool is read-only: it never modifies either skill file.

Prerequisites

  • Runtime: Python 3.11+ run via uv; stdlib-only (no runtime dependencies). The dev group pulls pytest.
  • CLIs: None beyond the runtime.
  • Credentials / auth: None.
  • Network: Runs fully offline; reads skill files from the local filesystem.

Usage

# Pass paths to SKILL.md files:
uv run --project tools/skill-reconciler-diff \
    skill-reconciler-diff skills/skill-a/SKILL.md skills/skill-b/SKILL.md

# Or pass parent directories — the tool resolves SKILL.md inside:
uv run --project tools/skill-reconciler-diff \
    skill-reconciler-diff skills/skill-a skills/skill-b

Output is written to stdout as JSON. Exit 0 on success; non-zero on parse errors (e.g. a path that does not resolve to a readable SKILL.md).

Output format

{
  "skill_a_path": "skills/skill-a/SKILL.md",
  "skill_b_path": "skills/skill-b/SKILL.md",
  "identical": false,
  "frontmatter_diff": {
    "only_in_a": {},
    "only_in_b": {},
    "changed": {
      "capability": {"a": "capability:triage", "b": "capability:fix"}
    }
  },
  "section_headings_diff": {
    "only_in_a": [],
    "only_in_b": ["New section"],
    "order_changed": false
  },
  "step_diff": {
    "only_in_a": [],
    "only_in_b": [],
    "body_changed": ["1"]
  },
  "placeholder_diff": {
    "only_in_a": [],
    "only_in_b": ["upstream"]
  },
  "support_files_diff": {
    "only_in_a": ["extra.md"],
    "only_in_b": []
  },
  "safety_baseline_diff": {
    "clause_1_injection_guard": {"a_present": true, "b_present": false, "diverges": true},
    "clause_2_collaborator_trust": {"a_present": true, "b_present": true, "diverges": false},
    "clause_3_confidentiality_posture": {"a_present": true, "b_present": true, "diverges": false}
  }
}

Fields:

Field Description
identical true when no structural difference was detected across all dimensions.
frontmatter_diff Keys present only in A, only in B, or with different values.
section_headings_diff Headings present only in A, only in B, or whose relative order differs.
step_diff ## Step N sections added, removed, or with changed bodies.
placeholder_diff <placeholder> tokens present only in A or only in B.
support_files_diff Sibling .md files (support docs) present only in A or only in B.
safety_baseline_diff Per-clause presence comparison for the three safety-baseline clauses.

Safety-baseline detection

The tool detects the three clauses defined in skills/skill-reconciler/safety-baseline-checklist.md:

  • Clause 1 — Untrusted content is never instructions: searches for wording establishing that external content is data, not a directive (e.g. “external content … never an instruction”, “prompt-injection attempt”).
  • Clause 2 — Collaborator / identity-resolution caveats: searches for the collaborator-trust gate (“only collaborators of <tracker> may direct the agent”, “non-collaborator”).
  • Clause 3 — Confidentiality posture is not weakened: searches for the confidentiality rule (“never reproduce … on a public surface”, “embargoed”, “private … content”).

Detection is heuristic (regex pattern matching on the skill body); it surfaces absence or presence for the skill-reconciler skill to judge. A diverges: true result is a strong signal that the reconciler should classify the difference as SAFETY-BASELINE.

Integration with skill-reconciler

This tool is intended to be used as an optional Step 1 enhancement to the skill-reconciler skill (the skill does not yet wire it in — that reference lands separately). To use it, run the tool before invoking the skill and pass its JSON output as context:

uv run --project tools/skill-reconciler-diff \
    skill-reconciler-diff skills/skill-a skills/skill-b \
    > /tmp/structural-diff.json
# Then reference /tmp/structural-diff.json in the skill invocation.

Without the tool the skill reasons from raw text; with it the skill grounds ALLOWED / DRIFT / SAFETY-BASELINE decisions in the deterministic diff object, reducing false positives on large or complex skill pairs.

Run tests

cd tools/skill-reconciler-diff
uv run --group dev pytest
Suggest a change