/dpd-verify-edge — External verification of necessary edges (#42, v0.6)
Announce: "Using dpd-verify-edge skill."
This skill implements the verification half of proof-tree discipline (see the main /dpd skill, "Proof-tree discipline" section). It checks edges classified layer='necessary' — the claim "these premises necessarily imply this conclusion" — by handing a context-stripped prompt to an independent verifier.
It is the opposite-incentive companion to /fcot: /fcot constructs an argument using full context; this skill checks one necessary step in isolation, skeptically. Compose them, don't merge — run /fcot while building, /dpd-verify-edge after, on the necessary edges that resulted.
When to invoke
- User invokes
/dpd-verify-edge [edge_id?]. - Claude MAY suggest it at a natural pause when
list_unverified_edgesreturns a non-empty set — custodially ("necessary edge が N 本未検証です。verify する?"), never auto-firing the external call.
Step 1 — Select the target edge(s)
- If
edge_idis given, use it (confirm it islayer='necessary'; if not, ask whether to proceed anyway). - Otherwise call
list_unverified_edges(session_id)(necessary edges with no verification record, ordered critical→standard→low→unset). Present the queue and confirm which edge to verify. Default to the highest-priority one.
Step 2 — Build the context-stripped prompt (the core asset)
Fetch the edge and its endpoints (list_edges / get_node). Build a prompt for an independent verifier. One prompt_builder — this exact construction is reused whether delivered by paste or auto-invoke.
The stripping line: include what is needed to UNDERSTAND the proposition; strip what ARGUES for it.
- INCLUDE: the from-node text, the to-node text, the claimed relationship (
fromnecessarily implies / supports / requiresto), the edgetype, local definitions needed to interpret the terms, and any explicit domain assumptions already encoded as nodes in the graph. If a node is shorthand for a formal premise, include that premise. - STRIP: the agent's chain-of-thought or proof attempt, the surrounding sibling/parent derivation, why the agent believes the edge holds, author confidence /
verification_priority/ prior verdicts, and downstream consequences.
Prompt skeleton:
You are verifying a single logical-implication claim, in isolation.
Do not assume the claim is true; judge it on its own merits.
CLAIM: <from-node text> ⟹ (necessarily implies) <to-node text>
[edge type: <type>]
DEFINITIONS / EXPLICIT ASSUMPTIONS (only those needed to read the claim):
- <local definition or graph-encoded assumption>
- ...
QUESTION: Does the premise NECESSARILY imply the conclusion as stated?
Answer with a first line exactly of the form:
VERDICT: holds | holds-with-caveat | refuted
If holds-with-caveat, add a second line:
CAVEAT: <the explicit assumption/definition/qualifier it depends on>
Then a short justification.
Step 3 — Deliver (paste baseline, optional auto-invoke)
Two transports, same prompt, same parser — they differ only at the edge:
- Paste (always available): emit the rendered prompt in a code block and ask the user to run it in whatever model they trust, then paste back the verifier's reply.
- Auto-invoke (optional): if an external verifier CLI is configured/available (e.g.
codex exec), you MAY run the prompt directly and capture the reply. If it is missing or errors, fall back to paste — do not hard-fail. Not vendor-hardwired.
Record which transport was used: method = 'external:<tool>' (auto-invoke) or method = 'paste'. verified_by is the verifier identity (the model name, or a human name in paste mode) — distinct from method.
Step 4 — Parse the verdict
Parse the reply's first line: VERDICT: then one of holds / holds-with-caveat / refuted (case-insensitive). If a CAVEAT: line is present, fold it into the notes. Everything after is the justification → notes.
holds-with-caveat is distinct from holds — never collapse it to "holds + a note". A caveated necessary edge is operationally different (it follows only under an explicit assumption) and warrants a structural fix in Step 5.
Step 5 — Record + act on the verdict
Always: record_edge_verification(session_id, edge_id, verdict, verified_by?, method?, notes?, prompt_hash?) — verdict is required and comes right after edge_id; the rest are optional. Append-only — re-verification adds a row, preserving history. Compute prompt_hash from the rendered Step-2 prompt (drift audit).
Then, by verdict — propose, never auto-mutate the graph's epistemic structure:
- holds → done. The necessary claim stands.
- holds-with-caveat → propose one of: (a) rewrite the from-node to fold in the assumption, (b) add an intermediate
assumptionnode + edge making the dependency explicit, or (c) weaken the edge tolayer='selective'viaset_edge_layer. Let the user choose. - refuted → the necessary claim failed. Do NOT auto-downgrade (a verifier can misread terms, miss an implicit assumption, or be weaker than the original model). Instead: the record is written (marking the edge as having a refutation = "needs adjudication"), and you propose downgrading via
set_edge_layer(layer='selective')orset_edge_layer(layer='invalid')(kept for audit, not deleted). Only auto-apply a downgrade if the user has set an explicit policy (e.g. two independent refutations).
Composition & boundaries
- Separate from
/fcot(construct vs. check have opposite incentives). A higher-level flow may chain construct→verify, but the primitives stay separate. - This skill never edits End nodes (§5.0 End modification gate still applies to any proposed structural fix).
- The verification obligation is edge-local: this skill only ever concerns the specific edge(s) selected, never an inferred surrounding region.
Feedback footer
After completing a meaningful response (not for trivial status output), print exactly one line at the very end:
💬 Hit a bug or have feedback on DPD? Run
/dpd-feedback "<short description>"or open an issue at https://github.com/o3co/agent-dpd/issues/new
Keep it to one line. Once per skill invocation is enough.