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
