Repository navigation
v0.1.0
The first release: the Contract layer for Impatient Programming in Elixir.
# mix.exs
{:covenant, "~> 0.1", only: [:dev, :test], runtime: false}On Hex: https://hex.pm/packages/covenant/0.1.0. Docs: https://hexdocs.pm/covenant/0.1.0. Needs Elixir 1.18 or later.
Covenant.Contractreads acontracts/directory: heavy-form intents with their nine sections, light-form obligations files, decision records, the system intent and scope ceilings. Every problem carries its file and line. Parsing is strict: a malformed obligation block (a heading at the wrong level, an unclosed fence, a misspelled or repeated field) is an error at its line, and a YAML file with several documents, merge keys or repeated keys is rejected.contracts/is trusted input, likemix.exs; Covenant refuses to call into Elixir or OTP, andfileconditions and exception targets must stay under the project root.Covenant.Casebinds contract tests to obligations when they compile. An untagged test, an unknown or retired obligation, or another component's obligation is a compile error at the test's line.Covenant.Formatterrecords which obligations passed, one results file per Mix app, so an umbrella's apps don't overwrite each other.mix covenant.checkruns the contract suite and fails on malformed blocks, dangling references, an obligation with no passing test, a stale exception or a scope ceiling exceeded. An obligation whose tagged tests were all skipped or excluded has no passing test. It prints contract coverage and writescontracts/coverage.json. Each run writes its results to a private subdirectory, and--results-dirdeletes only Covenant's own files.--staticapplies the same checks with nothing compiled, loaded or run, and writescontracts/coverage.static.json; it credits no test insidefor,Enum.each,if,case,condorunless.mix covenant.conditionsre-checks the premises of decision records:dep,env,file,otp,elixir, andvalue, which calls a function of the project and compares the result with the value the record decided.mix covenant.regen <component>writes a regeneration pack: the intent, records, contract tests and public-surface stubs, with the implementation left out. Stubs are written only for modules the component owns.--outclears only a directory that holds the.covenant-packmarker and refuses any other non-empty one. Tests are found by readinguse Covenant.Casefrom the syntax tree.mix covenant.mutate <component>mutates the component's modules in memory with thirteen operators, runs its contract tests against each mutant and writes a kill matrix that credits every kill to the obligations whose tests caught it. Survivors are sorted in<component>.survivors.yml; an unsorted survivor or a stale entry fails the run. An entry'sat,operatorandmutationare all required, so it names one mutant.--fail-fasttrades exact credit for speed,--jobs Nruns several workers, and the per-test timeout is measured from the baseline. Every worker runs the tests from a private copy of the project, so a mutant's relative-path writes never reach it. A watchdog turns a hung mutant into atimeout, workers die with their parent, and a health check after each mutant ends the run with an error if the VM is broken.defstructanddefexceptionfields are not mutated, and a run with nothing to mutate is an error.- The sibling layout that flinch, qualm and exhale read:
contract/<primitive>/with- **A1**obligations and acoversblock in its README, Contract tests beside it that name their obligations in# Contract: calc/A1comments, and an optionalmutants.mdofequivalentandunpromiseddeclarations.Covenant.Casereads the comments at compile time;mix covenant.checkapplies the rules offlinch contract;mix covenant.mutateandmix covenant.regentake a primitive by name. A project can use either layout or both. The survivor sorts gainunpromised. Eachmutants.mdline names exactly one mutant:#kpicks one when several of a unit's mutants share a change, and a line they share without it is ambiguous. - Covenant governs itself: 96 obligations across ten components, each proved by a
Covenant.Casetest. - Hardened before release by adversarial review (Claude and GPT): false greens from skipped tests, parameterized failures, malformed or unread Contract files and a project root moved by
--contracts; destructive--outand--results-dir; mutants writing into the real project; and hangs, false "unreliable" verdicts from slow teardowns, and orphaned workers.