My closest equivalent to “specs” are test trees.

Test trees are seriously battle-tested. They are already used to describe and test the behaviour of popular FinTech apps. I’ve personally spent thousands of hours working with test trees and other engineers to describe, reason about, and verify our software.

Test trees are a living, verifiable description of all behaviour. They are best explained by the test tree for test trees in my own Claude Code plugin, which are at the bottom of this post.

If you think test trees should work differently, you can propose a change:
> "then the tree must exist before implementation starts"
No, TDD is dumb! "then Claude should just go nuts and I'll figure it out later"

We can reason about changes to behaviour very easily this way, which is important when changing real products with millions of users over _years_.

Also, they are verifiable – they prove that the software has upheld them, because they map to tests that in turn _drove_ the implementation. Here I go again with the TDD 😂

test-trees-as-requirements (unit: test/test-trees-as-requirements.bats)
when a project uses contree
then CLAUDE.md identifies TEST_TREES.md as the definition of functional and cross-functional requirements
and TEST_TREES.md defines functional requirements using EARS syntax
and each behavioural unit has its own tree in TEST_TREES.md
and trees are flat subsections — not grouped by kind or layer
and every tree reifies exactly one test file
and every test file reifies exactly one tree
and every tree names its coverage in parenthesised labelled pairs on the tree-name line, covering the categories src, unit, integration, functional
and gaps are declared explicitly — "none" for expected-but-uncovered categories, omission for not-applicable ones
and the EARS rule is embedded in skills that use it
when a behaviour change is needed
then the tree must exist before implementation starts
when implementation reveals new understanding
then the tree is updated to reflect reality