Skip to content

fix(validator): fail-closed property-coverage attribution (N-7)#8

Merged
BunsDev merged 1 commit into
mainfrom
fix/validator-coverage-display
Jul 22, 2026
Merged

fix(validator): fail-closed property-coverage attribution (N-7)#8
BunsDev merged 1 commit into
mainfrom
fix/validator-coverage-display

Conversation

@BunsDev

@BunsDev BunsDev commented Jul 22, 2026

Copy link
Copy Markdown
Member

Validator coverage-display fix (PR #4 review N-7)

Bug (display-only; exit codes were always correct): the Property Coverage block filtered violations against hardcoded field-name lists. Violations whose fields matched no list flipped nothing: approval_tiers.<tier>.blocks (the compiler checks added in v0.4.0), syntax, schema *, SOUL/IDENTITY content, missing-file variants, and cross-file. Result: a FAIL run could print all-✓ coverage — e.g. negative/09-missing-memory FAILed with two Bounded Authority tier violations while displaying Bounded Authority ✓.

Fix: per-violation property attribution with a fail-closed default — every violation marks ≥1 property; a violation no rule recognizes marks every property its source file underwrites (unknown source ⇒ all five). Targeted rules keep the display informative: schema /meta* → Human Belonging; schema /approval_tiers*, /editable*, /protected* → Bounded Authority; malformed/unreadable ward.toml → both; missing/empty SOUL.md → all three SOUL-carried properties; cross-file → Named Identity. README documents the semantics.

Not a conformance change: nothing in-tree parses the coverage block (runner greps PASS/FAIL only); no fixture, schema, or RFC text touched; no version bump needed.

Verification

  • All 36 negative fixtures: exit 1 and ≥1 property ✗ (the all-green-on-FAIL class is dead)
  • All 6 positive fixtures + both examples: exit 0, all-✓
  • bash tests/conformance/run-conformance.sh → 6/6 + 36/36, READY
  • Spot-checks: 35-malformed-toml → Bounded+Human ✗; 36-schema-invalid-meta → Human ✗; 03-no-person-binding → Human ✗; 01-missing-soul → Named+Defined+Bounded ✗

No conflict with pending PR #7 (touches validate.js banner line only; trivial either-order rebase).

Bead: threads-cgj

The coverage display filtered on hardcoded field names, so violations
with unmatched fields — approval_tiers.<tier>.blocks, TOML syntax,
schema failures, SOUL/IDENTITY content, cross-file mismatches — flipped
no property and a FAIL run could print all-green coverage (PR #4 review
N-7). Exit codes were always correct; display-only.

Replace the filters with per-violation attribution: every violation
marks >=1 property; unrecognized fields mark every property their
source file underwrites (unknown sources mark all five). Verified
across all 42 fixtures + 2 examples: 36/36 negatives flip >=1 property,
8/8 positives all-green, suite READY.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 22, 2026 06:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the validator’s Property Coverage display logic so coverage attribution is computed per-violation with fail-closed defaults, preventing “all green” coverage output on failing runs when new/unknown violation fields appear.

Changes:

  • Replace hardcoded field-list filtering with per-violation property attribution and a fail-closed fallback in validators/validate.js.
  • Document the new fail-closed attribution semantics in validators/README.md.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
validators/validate.js Reworks Property Coverage computation to attribute every violation to ≥1 property, with fail-closed defaults by source file.
validators/README.md Documents the updated Property Coverage attribution semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread validators/validate.js
Comment on lines +441 to +452
if (v.file === 'ward.toml') {
if (['meta.person', 'protected.invariants'].includes(v.field)) return ['Human Belonging'];
if (v.field.startsWith('approval_tiers.') || v.field === '[approval_tiers]'
|| v.field.startsWith('schema /approval_tiers') || v.field.startsWith('schema /editable')
|| v.field.startsWith('schema /protected')
|| ['[protected]', 'protected.files', '[editable]', 'editable.paths'].includes(v.field)) {
return ['Bounded Authority'];
}
if (v.field.startsWith('schema /meta')) return ['Human Belonging'];
// file/syntax/content/root-schema failures: ward.toml underwrites both properties
return ['Bounded Authority', 'Human Belonging'];
}
@BunsDev

BunsDev commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Fresh-context code review at 4dfd637: no significant issues. Reviewer enumerated every violation constructor + the Ajv 8.20.0 instancePath formats against the attribution rules (all pairs land in defensible buckets; no wrong-bucket falls), probed the compiled schema for prefix collisions (none possible — root additionalProperties: true, only 5 top-level paths), confirmed propertiesFor is total with non-empty returns (all-green-on-FAIL impossible), and re-confirmed PASS-path/exit-code behavior unchanged. Gate: Val merge (no version bump needed — display-only, nothing parses the coverage block).

@BunsDev
BunsDev merged commit c5f4a8a into main Jul 22, 2026
1 check passed
@BunsDev
BunsDev deleted the fix/validator-coverage-display branch July 22, 2026 09:54
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.

2 participants