Skip to content

Test parity between coding-agent (MCP) audit path and harness audit path #366

Description

@mlieberman85

Context

Feature 026 (#365) ships darnit harness, an async driver that calls the same run_sieve_audit code path as the audit_openssf_baseline MCP tool. In principle, the raw audit results from both paths should be identical -- the harness is a fleet-driver wrapper, not a re-implementation.

During feature 026 manual testing against a real repo, we confirmed this at the raw layer:

  • Direct MCP tool call (audit_openssf_baseline): PASS 51, FAIL 5, WARN 7, ERROR 2, PENDING_LLM 1
  • darnit harness output: PASS 51, FAIL 5, WARN 8, ERROR 2, PENDING_LLM 0
    • (Same totals; harness resolved 1 PENDING_LLM to WARN via its own LLM step, which is correct per RFC-0001 Stage 1 authority rule.)

However, the /darnit-audit skill's user-facing summary showed PASS 56, FAIL 4, WARN 3 for the same repo. That is not what the tool returned. The skill is silently re-interpreting the audit results: Claude Code reads files, applies contextual judgment, and demotes some WARNs to PASS in its summary.

The concern

A user reading the skill's summary sees a headline like 56/66 PASS, 85% and reasonably believes that's what the audit found. It isn't; the audit found 51/66. The audit is faithful; the skill layer is not.

Constitution IV ("Never Guess User Values") is the sharper edge of this. If a control is FAIL because a user-judgment key is unconfirmed, and the skill infers the value from repo contents and reports the control as PASS, then the tool's safety property is being undone by the presentation layer.

What needs to happen

Not a fix. A test surface. We need to know when parity holds, when it doesn't, and where the drift lives.

  • A parity harness: given a fixture repo, run (a) the MCP tool directly, (b) darnit harness, and (c) the /darnit-audit skill in a scripted mode. Diff their reported summaries and per-control statuses.
  • A corpus of real repos (with permission) exercised across all three paths -- start with 3-5 known-good and 3-5 known-bad projects.
  • Explicit taxonomy of allowed vs disallowed drift:
    • Allowed: harness resolving PENDING_LLM (documented Stage 1 behavior)
    • Disallowed: any status change on a control whose Check step didn't have dispositive authority evidence
  • Regression tests that fail if the skill's summary drifts from the tool output on the fixture corpus without a corresponding audit-logic change
  • Decide whether the skill's aggregator should present tool output faithfully, or explicitly separate audit says X from Claude thinks Y

Relationship to #365

#365 does not change any of this -- it exposes the substrate that makes it testable. The harness's report is a machine-readable artifact you can diff against MCP tool JSON, which is the mechanical part of building this parity suite.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions