Commit 74256e7
authored
feat(check): grade architectural change from the CLI, not only over MCP (#161)
The delta that diff_snapshot serves to an agent could not gate anything.
internal/diff had a complete engine — comparability, structural-cause
attribution, incidental-drift separation, renderers — reachable only from
an MCP tool call, so closing the loop depended on the agent remembering to
ask. Enforcement was a nudge in a tool response.
Add pkg/check: a pure Evaluate(*diff.SnapshotDiff, Policy) Verdict, and an
`enola check` subcommand that exits 0 clean / 1 regression / 2 could-not-run
/ 3 declined. 3 is deliberately not 1: when two snapshots were built over
different inputs the delta describes how they were produced, not what was
edited, and reporting that as a failing change would be a lie.
Comparability gains a typed Kind set. The existing Comparable bool spans
everything from "different repositories" to "the baseline is four days
old"; a reader can weigh that from the prose, a gate cannot, and consuming
the bool would have made every stale baseline a hard refusal — contrary to
the deliberate design of staleBaselineDays. Stale now warns, says what it
means for the delta, and still grades. Warnings keeps its type and JSON
shape, so no existing consumer changes.
Policy keys on the explainer, not on confidence, because the documented
"1.0 is a structural fact" invariant is not enforced: god-class clamps a
fan-in ratio to 1.0 and layers emits an informational pattern finding that
can reach it. Gating on the number would fail builds for a new statistical
outlier and for a re-detected pattern. Default is cycles only; confidence
is a floor within it, which still screens out the 0.4 coupling-density
finding the cycles explainer also emits.
Also:
- baseline pin|show|clear, with pin snapshotting first so a days-old
snapshot is not frozen as "the state before my change"
- path arguments resolve as directory=repo, file=config everywhere; a
directory previously fell through to config.Load, warned, and silently
analysed the working directory instead
- unrecognized arguments are rejected rather than absorbed as config
paths, which had made every typo a silent wrong action
- inverted-pair detection requires a strictly negative gap; GeneratedAt is
second-resolution, so pin-then-check inside one second is simultaneous,
not inverted, and used to exit non-zero on a clean tree
- the verdict reports what moved, not just how much: per-kind tallies,
named facts with file:line, edges broken down by relation with the
mechanical declares link sorted last
- baseline selector resolution shared between the CLI and the MCP tools
- pre-commit hook and CI workflow examples1 parent a7d777a commit 74256e7
18 files changed
Lines changed: 2472 additions & 57 deletions
File tree
- cmd/enola
- examples
- ci
- hooks
- internal
- diff
- engine
- server
- pkg
- check
- cli
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
11 | 16 | | |
12 | 17 | | |
13 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
223 | 223 | | |
224 | 224 | | |
225 | 225 | | |
| 226 | + | |
| 227 | + | |
226 | 228 | | |
227 | 229 | | |
228 | 230 | | |
| |||
557 | 559 | | |
558 | 560 | | |
559 | 561 | | |
| 562 | + | |
| 563 | + | |
560 | 564 | | |
561 | 565 | | |
562 | 566 | | |
| |||
583 | 587 | | |
584 | 588 | | |
585 | 589 | | |
586 | | - | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
587 | 626 | | |
588 | 627 | | |
589 | 628 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
342 | 342 | | |
343 | 343 | | |
344 | 344 | | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
345 | 354 | | |
346 | 355 | | |
347 | 356 | | |
| |||
608 | 617 | | |
609 | 618 | | |
610 | 619 | | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
611 | 628 | | |
612 | 629 | | |
613 | | - | |
| 630 | + | |
614 | 631 | | |
615 | 632 | | |
616 | 633 | | |
617 | 634 | | |
618 | 635 | | |
619 | 636 | | |
620 | 637 | | |
621 | | - | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
622 | 701 | | |
623 | 702 | | |
624 | 703 | | |
| |||
0 commit comments