Agent brief — tier: mid (above-average). One PR (Closes #<this>); branch from main. House rules: AGENTS.md.
Goal
docs/suppression-and-fp-policy.md honestly marks [OwnIgnore("reason")] as designed-not-implemented — today the only working lever is --severity/--fail-on-finding. Once the alpha ships, per-site suppression becomes the first thing real users ask for. Implement the P-004 design end to end: extractor + core + output surfaces.
Sources of truth
docs/proposals/P-004-wpf-lifetime-profile.md — the [OwnIgnore("reason")] design (the reason string is mandatory by design: a suppression is a documented decision, not a silent one).
docs/suppression-and-fp-policy.md — the user-facing contract this implements; flip its "planned" markers when done.
docs/proposals/P-015-configuration-surface.md — project-wide config stays out of scope here (draft); this issue is the attribute slice only.
- SARIF 2.1.0
suppressions property — the standard representation for suppressed results.
Deliverable
- Extractor: recognize the attribute per P-004 (site granularity as designed there).
- Visibility over silence: where P-004 leaves a mechanism point open, prefer emitting the fact with a suppression marker (+ reason) over dropping it at the extractor — so reports can count suppressions, and SARIF carries them in
suppressions rather than omitting the result. A suppressed finding must not fail the run.
- An attribute without a reason must not suppress (follow P-004's exact posture for how that surfaces — never a silent accept).
- Sample(s) with suppressed/unsuppressed contrast wired into CI; bridge-level facts pinned in
tests/test_ownir.py if a new fact field is added (additive optional per spec/OwnIR.md §2 — document it in §4 + spec/ownir.schema.json like source_provenance).
- Update
docs/suppression-and-fp-policy.md from "planned" to "shipped" for the attribute, keeping P-015 config honestly marked draft.
Guardrails
- No
OWNIR_VERSION bump for an additive optional field; vocabulary changes fail loudly (IR rules).
- The C# extractor is CI-validated only (no local dotnet in agent envs).
- Gates:
python tests/run_tests.py, ruff check ., mypy strict on ownlang/.
Done when
The bad/suppressed sample is silent-but-counted (visible in SARIF suppressions), the reason-less attribute does not suppress, the FP-policy page reflects reality, and all gates + CI are green.
Agent brief — tier: mid (above-average). One PR (
Closes #<this>); branch frommain. House rules:AGENTS.md.Goal
docs/suppression-and-fp-policy.mdhonestly marks[OwnIgnore("reason")]as designed-not-implemented — today the only working lever is--severity/--fail-on-finding. Once the alpha ships, per-site suppression becomes the first thing real users ask for. Implement the P-004 design end to end: extractor + core + output surfaces.Sources of truth
docs/proposals/P-004-wpf-lifetime-profile.md— the[OwnIgnore("reason")]design (the reason string is mandatory by design: a suppression is a documented decision, not a silent one).docs/suppression-and-fp-policy.md— the user-facing contract this implements; flip its "planned" markers when done.docs/proposals/P-015-configuration-surface.md— project-wide config stays out of scope here (draft); this issue is the attribute slice only.suppressionsproperty — the standard representation for suppressed results.Deliverable
suppressionsrather than omitting the result. A suppressed finding must not fail the run.tests/test_ownir.pyif a new fact field is added (additive optional perspec/OwnIR.md§2 — document it in §4 +spec/ownir.schema.jsonlikesource_provenance).docs/suppression-and-fp-policy.mdfrom "planned" to "shipped" for the attribute, keeping P-015 config honestly marked draft.Guardrails
OWNIR_VERSIONbump for an additive optional field; vocabulary changes fail loudly (IR rules).python tests/run_tests.py,ruff check ., mypy strict onownlang/.Done when
The bad/suppressed sample is silent-but-counted (visible in SARIF
suppressions), the reason-less attribute does not suppress, the FP-policy page reflects reality, and all gates + CI are green.