Coming in Podlite 3.0: a specification that tests itself
Podlite is a semantic language: a document says what its parts are, not how they look. Its specification is prose, and when an implementation reads it differently, you find out from a document that renders wrong. Podlite 3.0, due in mid-November, gives the rules tests, written in Podlite and placed right in the specification text, each next to the rule it checks. The tests are semantic too: they check the structure a parser makes of a document, its blocks with their names and configuration, and no output format, HTML or any other.
The same blocks check any document, not only the specification. A set of tests becomes a schema of your own, written from your requirements and extended as they change: say, every invoice in a knowledge base carries a number. It can lint one document or a whole group of them, and it gives an agent that edits the files a way to keep the documents and the structure of the knowledge base intact.
Rules that carry their own tests
A test is a block. It may hold a piece of source, the fixture, and it holds one or more assertions about what a parser makes of it:
=begin test :id<heading-carries-its-level>
=begin fixture
=head2 Overview
=end fixture
=for assert :caption('a second-level heading is recognised as such')
head2
=end test
Each assertion carries a selector. Without :absent, it holds when the selector matches at
least one block; with :absent, when it matches none. So "every invoice has a number" is
written as "no invoice lacks one":
=for assert :absent
Invoice[ :!?number ]
The specification now carries around ninety of these tests, kept next to the rules they check. On podlite.org/v3.0/specification a test shows as a label beside its rule and opens in place. One sentence settles which side wins: "If a test of this specification differs from the rule it checks, the rule governs."

Assertions carry ordinary selectors, and the same selectors work with podlite
query on any document, for example in a build script.
Selectors gain predicates
A pattern may now carry a predicate in square brackets. It tests the configuration in effect
for the block, including options from =config and =set. The universal pattern *
matches a block of any name, so a selection can go by configuration alone:
=include file:./guide.podlite | *[ :platform<arm> ]
The operators cover the usual questions: is the attribute set, is it missing, does it equal a value, is it one of several. A selected block keeps all of its content.
What else changes
3.0 also tightens the rules for =include, tables and attribute values, and
notification blocks now use :notice. Some of these changes alter how existing
documents read from 3.0 on; the change log lists them all.
The scope of the release is tracked in podlite-specs#42, and questions go to Discussions. If an example is wrong, a rule reads two ways, or a test checks the wrong thing, now is the time to say so.