Skip to content

Structured expected/actual evidence on violations (#69) - #99

Merged
james-d12 merged 2 commits into
mainfrom
feature/violation-evidence-69
Oct 13, 2026
Merged

james-d12 merged 2 commits into
mainfrom
feature/violation-evidence-69

Conversation

@james-d12

Copy link
Copy Markdown
Owner

Summary

Violations carried only a free-text Message. This adds optional structured evidence so agents can act on a failure without parsing prose (CORE_RULES Pillar 6, REFACTORING Ph7).

  • Model: AssertionOutcome gains optional Expected, Actual, Evidence (IReadOnlyList<string>?) and a Failure(message, expected, actual, evidence) overload. Violation and AnalyzerViolation gain the same optional fields. RuleEvaluator.CreateViolation copies them across. All existing constructors and call sites still compile.
  • Assertions: populated wherever there is a natural value. must_inherit_from gives the pattern, the actual base type and the type. Dependency assertions give the offending types or dependency names as evidence. Naming and namespace assertions give the pattern and the actual name. Count and existence assertions give expected/actual counts and the matched candidates. Quantifiers (must_all_match, must_any_match, must_none_match) aggregate nested outcomes: expected is kept only when all nested failures agree, and evidence is qualified by the match it came from (<match>: <item>). Message text is unchanged everywhere.
  • Reporting:
    • Console: indented expected: / actual: / evidence: lines, only when present.
    • JSON v1: optional additive expected, actual, evidence properties. schemaVersion stays 1.0. The schema and docs/architecture/RESULT_CONTRACT.md are updated.
    • SARIF: property bag keys expected, actual, evidence. A Metadata key with the same name takes precedence, so existing metadata is never overwritten.
    • HTML: shown under the message.
  • Docs: docs/architecture/IMPLEMENTATION_STATUS.md gets a Structured expected/actual evidence on violations #69 section.

Tests

  • AssertionEvidenceTests (new): must_inherit_from, must_not_depend_on, must_only_depend_on, must_match_name, must_match_namespace_pattern, must_have_count, must_exist, quantifiers (all/any/none), and a success-has-no-evidence check.
  • RuleEvaluatorTests: fields flow from outcome to violation, null when absent, and analyzer violations carry them.
  • ConsoleViolationReporterTests, SarifViolationReporterTests (property bag and metadata precedence), ValidationReportMapperTests, ValidationReportSchemaTests (conforms to schema with the new fields).

dotnet build has 0 warnings and 0 errors. dotnet test passes across all projects. dotnet format --verify-no-changes passes. rules test (251/251) and rules validate (132/132) pass against examples/rules. No parser descriptor or rule.schema.json changed, so sync-skill-references.sh is not affected.

Closes #69

🤖 Generated with Claude Code

james-d12 and others added 2 commits October 13, 2026 22:26
AssertionOutcome, Violation and AnalyzerViolation gain optional Expected,
Actual and Evidence fields (default null, additive). Assertions populate
them where there is a natural value; quantifiers aggregate nested
outcomes. Message text is unchanged.

Surfaced in the console reporter, the JSON v1 contract (additive
properties, schemaVersion stays 1.0), SARIF property bag (reserved keys
expected/actual/evidence, Metadata keys take precedence) and HTML.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- must_any_match makes one pass over its matches, evaluating each nested
  assertion at most once per match. Failure Expected/Evidence reuse those
  outcomes instead of re-evaluating every match a second time.
- Evidence is capped at 50 entries via CandidateDescriptor.CapEvidence, with
  a final "...and N more" entry when truncated. Applied to must_all_match,
  must_none_match, must_have_count, must_not_depend_on, must_only_depend_on
  and must_any_match. ListOrNone (list-valued actual) is capped too.
- must_not_exist materialises at most 51 candidates, so the success path
  stops at the first item and the failure evidence stays bounded.

Message text is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@james-d12
james-d12 merged commit 2682ab9 into main Oct 13, 2026
5 checks passed
@james-d12
james-d12 deleted the feature/violation-evidence-69 branch October 13, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Structured expected/actual evidence on violations

1 participant