Kernel: what happens to a Finding that does not gate

Merged
DO
8d ago
+527-27

Part of the epic "Epic: nine gaps in the Kernel, found in review". Closes #55.

Convergence read only Findings of severity blocking or major, so a minor or info Finding could be open, with no Disposition, when its item merged, against FR-33 and I-15. The Maintainer ruled on 2026-10-14: a Finding that does not gate is an annotation on its Lens's check run, exempt from FR-33 and I-15, and a security Finding gates at any severity.

The rule

A required model Lens's open threadReading
security, any severity (blocking, major, minor, info)gates: addressing / findings_open; queued, dequeue / gate_open
Any other category, blocking or majorgates, as before
Any other category, minor or infodoes not gate
Category or severity missing, null, or outside the schemathread_unreadable, needs_you; queued, dequeue
  • A Lens that is not required gates only when a required Lens adopts its Finding (FR-32), whatever the category. Its thread may carry nulls.
  • A deterministic Lens gates through its check's conclusion. Code scanning fails by default only on high or higher, so a lower security alert passes it: that is "Code scanning fails on a security alert of any severity" (#95), recorded in §9.9.
  • A thread's category and severity come from the required Lens's own Finding record in its Run's result.json, joined by surface.key, never from the comment text, which anyone with write access can edit. The join waits on adapters/.
  • Refusing a non-gating Finding posted on a thread waits on harness/ (acceptance criterion 3), recorded in decision 0012, design §3.7, §4.3 and §9.9.

Acceptance criteria

  1. category is required on threads in schemas/facts.schema.json, examples/facts.json, tests/support.py and sim/world.py, with counter-examples for a missing category and one nobody owns. tools/check_authority.py checks that a thread's categories, and the Kernel's CATEGORIES and SEVERITIES, are exactly a Finding's.
  2. test_a_minor_security_finding_gates, test_a_minor_security_finding_opened_while_queued_takes_it_out_of_the_queue, test_a_security_finding_from_a_lens_that_is_not_required_does_not_gate and test_a_required_lens_thread_that_cannot_be_read_defers; test_minor_finding_and_unrequired_lens_do_not_gate still passes. Mutants for reading security by severity, a non-required Lens gating, and each unreadable case: 146 of 146 killed.
  3. Waiting on harness/, as above.
  4. PRD FR-33; design §1.1, §3.3, §3.7, §4.2 item 2, §4.3, I-15 and §9.9; decision 0012; config/apps.json (the reader App reads records.artifacts under the actions: read it already holds).

Read by

A fresh-context review and a separate security pass (Claude), on the first commit; the second commit answers them. Both found that a required Lens's thread with a null category was read as not security, so a minor security Finding could merge; it now defers. AGY (Gemini) to follow; Codex and CodeRabbit are at their usage limits. make verify passes on a git archive export (343 tests), and python3 -m tools.mutants kills 146 of 146.

🤖 Generated with Claude Code