enola-guides 0.3.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +168 -0
- data/LICENSE +1 -1
- data/NOTICE +7 -0
- data/README.md +157 -74
- data/bundle/bundle.json +1666 -0
- data/examples/go-service/EXPECTED +5 -0
- data/examples/go-service/README.md +32 -0
- data/examples/go-service/cmd/shop/main.go +11 -0
- data/examples/go-service/enola/constraints/domain.yaml +14 -0
- data/examples/go-service/enola/constraints/layers.yaml +10 -0
- data/examples/go-service/enola/constraints/supply.yaml +7 -0
- data/examples/go-service/go.mod +5 -0
- data/examples/go-service/internal/checkout/checkout.go +14 -0
- data/examples/go-service/internal/order/order.go +18 -0
- data/examples/go-service/internal/order/pricing.go +8 -0
- data/examples/go-service/internal/store/store.go +13 -0
- data/examples/go-service/internal/web/routes.go +30 -0
- data/examples/knowledge-base/README.md +6 -2
- data/examples/knowledge-base/enola-cluster.yaml +6 -6
- data/examples/knowledge-base/wiki/_state/enola/findings.json +2 -2
- data/examples/knowledge-base/wiki/_state/enola/receipts.json +11 -8
- data/examples/knowledge-base/wiki/shop/permanent/architecture.md +1 -1
- data/examples/knowledge-base/wiki/shop/permanent/public-surface.md +3 -3
- data/examples/laws/clean-rings/README.md +3 -1
- data/examples/laws/cluster-laws/README.md +3 -1
- data/examples/laws/cqrs-queries-never-write/README.md +3 -1
- data/examples/laws/foreign-keys/README.md +3 -1
- data/examples/laws/governed-code/README.md +3 -1
- data/examples/laws/instantiation/README.md +3 -1
- data/examples/laws/maintenance-tasks/README.md +3 -1
- data/examples/laws/mixins-stay-independent/README.md +3 -1
- data/examples/laws/naming-conventions/README.md +3 -1
- data/examples/laws/one-door/README.md +3 -1
- data/examples/laws/one-owner-per-table/README.md +3 -1
- data/examples/laws/paired-names/README.md +3 -1
- data/examples/laws/parts-never-cycle/README.md +3 -1
- data/examples/laws/protocol-any-of/README.md +3 -1
- data/examples/laws/public-surface/README.md +3 -1
- data/examples/laws/public-tool-prefix/README.md +3 -1
- data/examples/laws/rails-forbidden-names/README.md +3 -1
- data/examples/laws/rails-mutations-are-authorized/README.md +3 -1
- data/examples/laws/rails-request-boundaries/README.md +3 -1
- data/examples/laws/rails-strict-arrangement/README.md +3 -1
- data/examples/laws/readers-read-the-store-only/README.md +3 -1
- data/examples/laws/receiverless-request-api/README.md +3 -1
- data/examples/laws/resolved-ancestry/README.md +3 -1
- data/examples/laws/routes-have-consumers/README.md +3 -1
- data/examples/laws/storage-stays-home/README.md +3 -1
- data/examples/laws/vanilla-rails-stays-empty/README.md +3 -1
- data/examples/python-service/EXPECTED +6 -0
- data/examples/python-service/README.md +31 -0
- data/examples/python-service/enola/constraints/domain.yaml +14 -0
- data/examples/python-service/enola/constraints/layers.yaml +10 -0
- data/examples/python-service/enola/constraints/supply.yaml +7 -0
- data/examples/python-service/pyproject.toml +8 -0
- data/examples/python-service/shop/__init__.py +0 -0
- data/examples/python-service/shop/api/__init__.py +0 -0
- data/examples/python-service/shop/api/orders.py +18 -0
- data/examples/python-service/shop/domain/__init__.py +0 -0
- data/examples/python-service/shop/domain/order.py +6 -0
- data/examples/python-service/shop/domain/pricing.py +6 -0
- data/examples/python-service/shop/repositories/__init__.py +0 -0
- data/examples/python-service/shop/repositories/orders.py +22 -0
- data/examples/python-service/shop/services/__init__.py +0 -0
- data/examples/python-service/shop/services/checkout.py +8 -0
- data/examples/python-service/tests/test_order.py +5 -0
- data/examples/rails-shop/mcp-arch.yaml +7 -0
- data/examples/rust-service/Cargo.toml +8 -0
- data/examples/rust-service/EXPECTED +7 -0
- data/examples/rust-service/README.md +32 -0
- data/examples/rust-service/enola/constraints/domain.yaml +14 -0
- data/examples/rust-service/enola/constraints/layers.yaml +10 -0
- data/examples/rust-service/enola/constraints/supply.yaml +7 -0
- data/examples/rust-service/src/checkout/mod.rs +8 -0
- data/examples/rust-service/src/main.rs +10 -0
- data/examples/rust-service/src/order/mod.rs +15 -0
- data/examples/rust-service/src/order/pricing.rs +6 -0
- data/examples/rust-service/src/store/mod.rs +9 -0
- data/examples/rust-service/src/web/mod.rs +24 -0
- data/examples/typescript-service/EXPECTED +6 -0
- data/examples/typescript-service/README.md +31 -0
- data/examples/typescript-service/enola/constraints/domain.yaml +14 -0
- data/examples/typescript-service/enola/constraints/layers.yaml +10 -0
- data/examples/typescript-service/enola/constraints/supply.yaml +7 -0
- data/examples/typescript-service/package.json +10 -0
- data/examples/typescript-service/src/db/orders.ts +9 -0
- data/examples/typescript-service/src/db/schema.ts +6 -0
- data/examples/typescript-service/src/domain/order.ts +9 -0
- data/examples/typescript-service/src/domain/pricing.ts +6 -0
- data/examples/typescript-service/src/routes/orders.ts +18 -0
- data/examples/typescript-service/src/server.ts +7 -0
- data/examples/typescript-service/src/services/checkout.ts +8 -0
- data/examples/typescript-service/tsconfig.json +4 -0
- data/exe/enola-guides +6 -0
- data/guides/00-concepts.md +97 -0
- data/guides/01-start-here.md +242 -58
- data/guides/02-rails.md +80 -36
- data/guides/03-ember.md +15 -4
- data/guides/04-writing-laws.md +223 -15
- data/guides/05-constraints-in-ci.md +171 -33
- data/guides/06-hooks-and-agents.md +209 -35
- data/guides/07-providers.md +93 -23
- data/guides/08-beyond-one-repo.md +104 -13
- data/guides/09-a-knowledge-base-with-enola.md +22 -8
- data/guides/10-hooks.md +50 -21
- data/guides/11-the-skills-as-they-run.md +17 -5
- data/guides/12-the-wrapper.md +41 -7
- data/guides/13-tabula.md +215 -0
- data/guides/14-taha.md +110 -0
- data/guides/15-python.md +155 -0
- data/guides/16-typescript.md +130 -0
- data/guides/17-go.md +103 -0
- data/guides/18-rust.md +99 -0
- data/guides/19-rolling-out.md +131 -0
- data/guides/20-reading-a-verdict.md +183 -0
- data/lib/enola-guides/cli.rb +68 -0
- data/lib/enola-guides.rb +1 -1
- data/recipes/README.md +10 -10
- data/templates/constraints-starter/background-jobs-never-invoke-controller-code.rb +6 -0
- data/templates/constraints-starter/models-do-not-reach-controllers.rb +6 -0
- data/templates/constraints-starter/policies-only-answer.rb +6 -0
- data/templates/constraints-starter/the-request-api-stays-in-controllers.rb +6 -0
- data/templates/enola-check.sh +104 -37
- data/templates/enola-cluster.yaml +1 -1
- data/templates/enola-findings.rb +52 -11
- data/templates/hooks/intent-first-gate.sh +13 -2
- data/templates/hooks/record.sh +15 -4
- data/templates/hooks/stop-debt.sh +4 -2
- data/templates/kb/kb +367 -0
- data/templates/skills/enola/SKILL.md +15 -3
- data/templates/skills/enola-citation-hygiene/SKILL.md +7 -1
- data/templates/skills/enola-deepdive/SKILL.md +7 -1
- data/templates/skills/enola-drift/SKILL.md +7 -1
- data/templates/skills/enola-grade-before-push/SKILL.md +16 -7
- data/templates/skills/enola-ingest-check/SKILL.md +7 -1
- data/templates/skills/enola-laws/SKILL.md +19 -4
- data/templates/skills/enola-zoom-out/SKILL.md +7 -1
- metadata +82 -9
- data/examples/rails-shop/enola.yaml +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8d1b81f179855dbd64a4feb84618651f3b3805d7410dd82f09238fb9a3896f00
|
|
4
|
+
data.tar.gz: 46ec48df52057f409f66e0a60ee1c32224cdfc84f06da9474c85561923a677b5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d6c33d263d7d51ad7b16dc436ddf1412f441309dbbb05f8534fd4efda42c97b8ba2489d02ef9fc04f887ab226261db0f0edab3168dad1c4bf5b2426e899415b8
|
|
7
|
+
data.tar.gz: 99318280749a1987d2a1197f29ca3fe8850a78df1a5fdd13cc3d743d2e24ce14918b79b8b6ccabd1cb492174db69cec19f5f456a2e57283a31d1f13b8ea43c01
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,173 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0 (2026-10-26)
|
|
4
|
+
|
|
5
|
+
Checked against enola v0.4.35, and read again as someone who has never
|
|
6
|
+
heard of enola: a developer landing on the README, one following guide 01
|
|
7
|
+
literally on a Python service, and a tech lead deciding whether to adopt
|
|
8
|
+
it. What they tripped on is fixed, and every command it changed was run
|
|
9
|
+
against v0.4.35.
|
|
10
|
+
|
|
11
|
+
- The README says what enola is and how to install it before anything
|
|
12
|
+
else, and groups the guides into tracks: new to enola, your stack, laws
|
|
13
|
+
and CI, agents, deeper, and an optional knowledge-base track.
|
|
14
|
+
- Three new guides. [00, what enola is](guides/00-concepts.md): the
|
|
15
|
+
pieces, a glossary, who makes what, and enola beside linters and
|
|
16
|
+
dependency-rule tools. [19, rolling out](guides/19-rolling-out.md):
|
|
17
|
+
measured costs (Mastodon and a 20,000-file Rails monolith), one recipe
|
|
18
|
+
instead of five, report then enforce, owners, what to commit, turning
|
|
19
|
+
it off. [20, reading a verdict](guides/20-reading-a-verdict.md): every
|
|
20
|
+
section and exit code, partial and declined, the surprises.
|
|
21
|
+
- Guide 01: install pinned through `pipx`, the npm `enola` warning, the
|
|
22
|
+
MCP server registered with `alwaysLoad`, `doctor` before a restart, a
|
|
23
|
+
first law in YAML that fires on any layout with the output it gives,
|
|
24
|
+
and why a first `.rb` law in a repository with no Ruby makes the verdict
|
|
25
|
+
partial and grades an old breach as new.
|
|
26
|
+
- Guide 04: modes as a table with the confidence each reports at; fix,
|
|
27
|
+
exempt, suppress or leave in the baseline, with the syntax in Ruby and
|
|
28
|
+
YAML; a recipes section; `check` needs a pinned baseline.
|
|
29
|
+
- Guide 05: the action pinned with `version:`, Rubydex installed pinned;
|
|
30
|
+
the template's variables, requirements, exit codes and comment.
|
|
31
|
+
- Guide 06: registering the MCP server per agent, what the agent does
|
|
32
|
+
differently, v0.4.35's narrower search refusal and folder-of-repositories
|
|
33
|
+
install, what to commit (the hooks carry an absolute path) and how to
|
|
34
|
+
turn each piece off.
|
|
35
|
+
- `templates/enola-check.sh`: a regression under enforcement is a verdict
|
|
36
|
+
with a comment, not "did not run"; the confidence floor stays at 1.00 so
|
|
37
|
+
advisory laws never fail; a shallow clone fails on CI instead of passing
|
|
38
|
+
quietly; the comment is edited by its numeric id; without Ruby the
|
|
39
|
+
comment is enola's own summary; `.enola-version` pins the release.
|
|
40
|
+
`script/test-check-template` covers each.
|
|
41
|
+
- The knowledge-base hooks leave a repository with no decision records
|
|
42
|
+
alone (`ENOLA_DECISION_DIRS`) and are wired from `.claude/hooks/`, where
|
|
43
|
+
`enola-guides copy` writes them. The five knowledge-base skills call a
|
|
44
|
+
wrapper that now ships, `templates/kb/kb`, tested by `script/test-kb`.
|
|
45
|
+
`examples/knowledge-base`'s cluster config parses on v0.4.35.
|
|
46
|
+
- Fixed: the `enola --generate . && enola check .` line in guide 02, the
|
|
47
|
+
skills and the twenty-six law READMEs fails with no pinned baseline;
|
|
48
|
+
`constraints init` binds a recipe only when every role has a directory;
|
|
49
|
+
a Ruby `via:` keyword on a sentence is dropped (write `via :imports` in
|
|
50
|
+
the law); `enola gc` trims the local history; the Ember recipe is copied
|
|
51
|
+
with `enola-guides copy`, not `gem contents`; undefined names (munola,
|
|
52
|
+
the brain) are gone; `list recipes` no longer lists the recipes README.
|
|
53
|
+
- What v0.4.35 still reads less than the code, each re-checked: an
|
|
54
|
+
Express `router.post("/")` under a mount, an inline Axum `.nest`, a
|
|
55
|
+
bare Cargo version read as pinned, an inline TypeScript handler,
|
|
56
|
+
`layered`'s `depends_on` rules on Python, TypeScript, Go and Rust, and a
|
|
57
|
+
Ruby `where:` value that is not a string.
|
|
58
|
+
- tabula and taha are marked as a preview: neither is public yet.
|
|
59
|
+
- `script/check-links` checks `#anchors` too.
|
|
60
|
+
|
|
61
|
+
## 0.8.0 (2026-10-25)
|
|
62
|
+
|
|
63
|
+
One command, `enola-guides`, in every ecosystem: RubyGems, npm, PyPI,
|
|
64
|
+
crates.io, Go and Homebrew, and binaries for Linux, macOS and Windows on
|
|
65
|
+
the GitHub release. `list`, `show` and `copy` read one catalogue,
|
|
66
|
+
`bundle/bundle.json`, generated from the tree by `script/bundle`: 74 items
|
|
67
|
+
across guides, examples, laws, skills, hooks, recipes and templates. The
|
|
68
|
+
five implementations (Go, Rust, Node, Python, Ruby) are held to the same
|
|
69
|
+
22 cases, byte for byte, by `script/test-clis`, and CI runs them against
|
|
70
|
+
each package as installed from the artifact a release would publish, and
|
|
71
|
+
installs the Homebrew formula from a local tap. `VERSION` is the one
|
|
72
|
+
version; a tag `vX.Y.Z` publishes everywhere through trusted publishing
|
|
73
|
+
(`RELEASING.md`). A `NOTICE` names enola. `CONTRIBUTING.md`, `SECURITY.md`,
|
|
74
|
+
a code of conduct, issue and pull-request templates and Dependabot for the
|
|
75
|
+
actions and the crate; `script/test` runs every check CI runs that needs
|
|
76
|
+
no registry.
|
|
77
|
+
|
|
78
|
+
## 0.7.0 (2026-10-25)
|
|
79
|
+
|
|
80
|
+
Python, TypeScript, Go and Rust. Guides 15 to 18 and a worked example in
|
|
81
|
+
each language: the same four-layer service with its source, binding the
|
|
82
|
+
`layered` and `supply-chain` recipes and breaking its laws on purpose.
|
|
83
|
+
`script/test-examples` snapshots every example with the pinned enola and
|
|
84
|
+
fails when the laws reporting a breach are not exactly the ones its
|
|
85
|
+
`EXPECTED` file lists. What the examples showed on v0.4.34, each said
|
|
86
|
+
where it bites:
|
|
87
|
+
|
|
88
|
+
- `layered`'s two domain rules read `depends_on`, which none of the four
|
|
89
|
+
extractors writes, so each example states the domain's law over
|
|
90
|
+
`imports`.
|
|
91
|
+
- A TypeScript handler written inline puts its calls on the file, where
|
|
92
|
+
the edge rules do not walk; a named handler is walked.
|
|
93
|
+
- An Express `router.post("/")` under a mount produces no route.
|
|
94
|
+
- An Axum router nested inline keeps its bare paths.
|
|
95
|
+
- A Cargo version with no operator counts as pinned.
|
|
96
|
+
|
|
97
|
+
Guide 01 states its first law in YAML as well as Ruby, and the README
|
|
98
|
+
no longer reads as Rubyists first.
|
|
99
|
+
|
|
100
|
+
## 0.6.0 (2026-10-25)
|
|
101
|
+
|
|
102
|
+
tabula and taha. Guide 13 is tabula for an enola user: a release that
|
|
103
|
+
carries cardo inside the binary and finds it last, after `engine.binary`
|
|
104
|
+
and any `enola` on PATH; the tour; laws said on an architecture page and
|
|
105
|
+
compiled into plain enola YAML that upstream v0.4.34 lints clean; a PRD
|
|
106
|
+
bullet graded with `grade: enola check clean`; its hooks beside enola's;
|
|
107
|
+
and which hand-built piece of guides 09 to 12 each verb replaces. Guide
|
|
108
|
+
14 is taha: installing from a clone (the npm name `taha` is another
|
|
109
|
+
package's), a run under a mandate, adopting a repository enola already
|
|
110
|
+
measures, and the `cardo` it calls by name. Guides 09 to 12 keep the
|
|
111
|
+
hand-built path and say where tabula takes it over.
|
|
112
|
+
|
|
113
|
+
## 0.5.0 (2026-10-25)
|
|
114
|
+
|
|
115
|
+
What enola shipped between v0.4.4 and v0.4.34, each command and key run
|
|
116
|
+
against v0.4.34 before it was written down:
|
|
117
|
+
|
|
118
|
+
- Guide 05: enola-action@v2, with the install step that gives it the
|
|
119
|
+
Rubydex library it does not fetch itself, its outputs, and `-format`
|
|
120
|
+
`sarif`, `annotations` and `summary`; `-reviewers`. A CI job runs the
|
|
121
|
+
workflow the guide prints.
|
|
122
|
+
- Guide 06: the opencode and Pi install targets, the Claude Code plugin
|
|
123
|
+
and what it leaves out, all twenty-two MCP tools, and the questions the
|
|
124
|
+
CLI answers without an agent (`impact`, `endpoint`, `plan`, `flows`,
|
|
125
|
+
`constraints ledger`, `dashboard`).
|
|
126
|
+
- Guide 07: the rbs and zeitwerk providers, provider reuse, and pinning a
|
|
127
|
+
provider of your own.
|
|
128
|
+
- Guide 08: `cluster init` and folders indexed as clusters, why the
|
|
129
|
+
output directory needs its own name (it is resolved inside each
|
|
130
|
+
member), `matched_routes`, `caller`, `unreached_by_clients`, `coverage
|
|
131
|
+
--unresolved`, declaring an in-house HTTP client, and sharing the
|
|
132
|
+
history.
|
|
133
|
+
- Guide 04: laws over dependencies and the `supply-chain` recipe, the
|
|
134
|
+
ledger, `no_frame_in_members`, and how `since` falls back to git.
|
|
135
|
+
In v0.4.34 a Ruby `where:` drops a value that is not a string or a
|
|
136
|
+
symbol, so the guide quotes booleans and numbers.
|
|
137
|
+
- Guide 02: the `packwerk` explainer and the `package_paths` it needs
|
|
138
|
+
when packs live outside `packages/`, and the `ruby-conventions` recipe.
|
|
139
|
+
|
|
140
|
+
## 0.4.0 (2026-10-25)
|
|
141
|
+
|
|
142
|
+
Checked against enola v0.4.34. enola skips a provider whose
|
|
143
|
+
`expected_version` disagrees with what it answers, and the guides pinned
|
|
144
|
+
Prism at `0.1.0` (the script answers `0.2.0` since v0.4.5) and Rubydex at
|
|
145
|
+
`0.4.0` (the binary carries `0.4.1` since v0.4.33), so their Ruby
|
|
146
|
+
configurations produced no provider facts. Every configuration now names
|
|
147
|
+
the built-in `rubydex` and `prism` providers with no pin; neither needs
|
|
148
|
+
Ruby. Also fixed, each wrong before this release too:
|
|
149
|
+
|
|
150
|
+
- The configuration file is `mcp-arch.yaml`; enola never read
|
|
151
|
+
`enola.yaml`, so `examples/rails-shop` now ships `mcp-arch.yaml`.
|
|
152
|
+
- `templates/enola-check.sh` defaults to v0.4.34 (it named `0.5.0`, which
|
|
153
|
+
does not exist), installs the binary under the name the release archive
|
|
154
|
+
gives it, configures the built-in providers in a tree with a `Gemfile`,
|
|
155
|
+
and grades with the configuration it generated with; grading the bare
|
|
156
|
+
path read no providers and reported every Ruby run as a partial verdict.
|
|
157
|
+
- `templates/enola-findings.rb` renders a partial verdict and names each
|
|
158
|
+
producer it left ungraded.
|
|
159
|
+
- `constraints init` writes `enola/constraints/recipes.yaml`.
|
|
160
|
+
- A provider that ran on one side only gives a partial verdict, not a
|
|
161
|
+
decline; the session-start hook pins a baseline, and in Claude Code a
|
|
162
|
+
`PreToolUse` hook refuses the first two file searches.
|
|
163
|
+
- `doctor` reports the hooks and the baseline, not the Rubydex library.
|
|
164
|
+
- The recipes README lists `ruby-conventions` and `supply-chain` among
|
|
165
|
+
upstream's built-ins.
|
|
166
|
+
|
|
167
|
+
A CI workflow lints every example against the pinned enola release, runs
|
|
168
|
+
the check template end to end on a Rails fixture, and checks every
|
|
169
|
+
relative link.
|
|
170
|
+
|
|
3
171
|
## 0.3.1 (2026-08-23)
|
|
4
172
|
|
|
5
173
|
The recipes README says where the catalogue ships: built into munola,
|
data/LICENSE
CHANGED
|
@@ -187,7 +187,7 @@ APPENDIX: How to apply the Apache License to your work.
|
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
|
188
188
|
identification within third-party archives.
|
|
189
189
|
|
|
190
|
-
Copyright (c) 2026
|
|
190
|
+
Copyright (c) 2026 Muhamed Isabegovic
|
|
191
191
|
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
193
|
you may not use this file except in compliance with the License.
|
data/NOTICE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
enola-guides
|
|
2
|
+
Copyright (c) 2026 Muhamed Isabegovic
|
|
3
|
+
|
|
4
|
+
Guides, worked examples, skills and templates for enola
|
|
5
|
+
(https://github.com/enola-labs/enola), by Dejan Menges, licensed under the
|
|
6
|
+
Apache License, Version 2.0. enola, tabula, taha and cardo are separate
|
|
7
|
+
projects; no part of their code is included here.
|
data/README.md
CHANGED
|
@@ -1,80 +1,163 @@
|
|
|
1
1
|
# enola-guides
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
[enola](https://github.com/enola-labs/enola) snapshots a codebase's
|
|
4
|
+
architecture (modules, calls, routes, tables, dependencies) and grades
|
|
5
|
+
each change against a pinned baseline. It catches what file-by-file
|
|
6
|
+
linters cannot: a new cycle across four files, a job that starts calling
|
|
7
|
+
a controller, a second part writing a table that was one part's own. And
|
|
8
|
+
it reports only what the change added, not the hundreds of findings the
|
|
9
|
+
repository already had.
|
|
10
|
+
|
|
11
|
+
These are guides to using it: a first graded change in ten minutes, laws
|
|
12
|
+
your team states as sentences, the check on every pull request, and the
|
|
13
|
+
hooks and tools a coding agent uses during a session, for Rails, Ember,
|
|
14
|
+
Python, TypeScript, Go and Rust. Every command, flag and output in them
|
|
15
|
+
was run against **enola v0.4.35**, and CI snapshots and grades the worked
|
|
16
|
+
examples on every change. The guides are by Muhamed Isabegovic and are
|
|
17
|
+
not part of enola-labs.
|
|
18
|
+
|
|
19
|
+
## Install enola
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
curl -fsSL https://raw.githubusercontent.com/enola-labs/enola/main/install.sh | sh
|
|
23
|
+
enola --version
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
or `pipx install enola-cli` (the PyPI name; the command is `enola`).
|
|
27
|
+
[Start here](guides/01-start-here.md) has the rest, including how to pin
|
|
28
|
+
a version. enola is not on npm: the npm package `enola` is something
|
|
29
|
+
else.
|
|
30
|
+
|
|
31
|
+
## Read in this order
|
|
32
|
+
|
|
33
|
+
**New to enola**
|
|
34
|
+
|
|
35
|
+
- [What enola is, and the words these guides use](guides/00-concepts.md):
|
|
36
|
+
the pieces, a glossary, and how it sits beside the tools you already
|
|
37
|
+
run. Five minutes.
|
|
38
|
+
- [Start here](guides/01-start-here.md): install, snapshot, baseline, a
|
|
39
|
+
graded change, the agent hooks, a first law. Ten minutes.
|
|
40
|
+
|
|
41
|
+
**Your stack**: what enola measures in each, the recipe that names its
|
|
42
|
+
parts, and where it reads less than the code says.
|
|
43
|
+
|
|
44
|
+
- [Rails](guides/02-rails.md) · [Ember](guides/03-ember.md) ·
|
|
45
|
+
[Python](guides/15-python.md) · [TypeScript and JavaScript](guides/16-typescript.md) ·
|
|
46
|
+
[Go](guides/17-go.md) · [Rust](guides/18-rust.md)
|
|
47
|
+
|
|
48
|
+
**Laws and CI**
|
|
49
|
+
|
|
50
|
+
- [Writing laws](guides/04-writing-laws.md): parts, the sentences, modes,
|
|
51
|
+
dates, exemptions and suppressions, what a refusal means.
|
|
52
|
+
- [Constraints in CI](guides/05-constraints-in-ci.md): the check on every
|
|
53
|
+
pull request, on GitHub or any other CI.
|
|
54
|
+
- [Rolling out](guides/19-rolling-out.md): adopting it on a repository
|
|
55
|
+
with years of history, what to commit, what it costs, how to turn each
|
|
56
|
+
piece off.
|
|
57
|
+
- [Reading a verdict](guides/20-reading-a-verdict.md): every section of
|
|
58
|
+
`enola check`'s output, every exit code, and the surprises.
|
|
59
|
+
|
|
60
|
+
**Agents**
|
|
61
|
+
|
|
62
|
+
- [Hooks and agents](guides/06-hooks-and-agents.md): registering the MCP
|
|
63
|
+
server, the session hooks, what the agent does differently, the tools
|
|
64
|
+
it reaches for.
|
|
65
|
+
|
|
66
|
+
**Deeper**
|
|
67
|
+
|
|
68
|
+
- [Providers](guides/07-providers.md): the Ruby pair, the census, the
|
|
69
|
+
runtime capture, writing one.
|
|
70
|
+
- [Beyond one repository](guides/08-beyond-one-repo.md): the cluster, the
|
|
71
|
+
seams between repositories, the laws across them, the history.
|
|
72
|
+
|
|
73
|
+
**Optional: a knowledge base of decisions.** For teams that keep
|
|
74
|
+
decision records beside their code and want each page anchored to the
|
|
75
|
+
code it governs. Nothing above needs it.
|
|
76
|
+
|
|
77
|
+
- [A knowledge base with enola](guides/09-a-knowledge-base-with-enola.md):
|
|
78
|
+
pages that compile into the graph, receipts, a finding ledger.
|
|
79
|
+
- [Knowledge-base hooks](guides/10-hooks.md): the intent-first gate, the
|
|
80
|
+
turn record, the stop-time debt, the session refresh.
|
|
81
|
+
- [The knowledge-base skills, as they run](guides/11-the-skills-as-they-run.md):
|
|
82
|
+
deepdive, claim check, drift, citation hygiene, zoom-out.
|
|
83
|
+
- [The wrapper](guides/12-the-wrapper.md): the command those skills call,
|
|
84
|
+
shipped as a template.
|
|
85
|
+
- *Preview:* [tabula](guides/13-tabula.md) and [taha](guides/14-taha.md),
|
|
86
|
+
the same practice as one program and agents run on it. Neither is
|
|
87
|
+
public yet.
|
|
88
|
+
|
|
89
|
+
## Worked examples
|
|
90
|
+
|
|
91
|
+
- [`examples/python-service`](examples/python-service),
|
|
92
|
+
[`typescript-service`](examples/typescript-service),
|
|
93
|
+
[`go-service`](examples/go-service) and
|
|
94
|
+
[`rust-service`](examples/rust-service): the same four-layer service in
|
|
95
|
+
each language, with its source, breaking the laws it states on purpose
|
|
96
|
+
so you can watch each one fire.
|
|
97
|
+
- [`examples/rails-shop`](examples/rails-shop): thirteen laws in the Ruby
|
|
98
|
+
DSL, one file each, from "jobs never invoke controller code" to
|
|
99
|
+
"billing keeps to its own tables", with the Prism and Rubydex
|
|
100
|
+
providers configured.
|
|
101
|
+
- [`examples/ember-app`](examples/ember-app): an Ember application bound
|
|
102
|
+
to the conventions recipe in one block.
|
|
103
|
+
- [`examples/laws`](examples/laws/README.md): twenty-six laws, one
|
|
104
|
+
directory each, from foreign keys on a tenant column to parts that may
|
|
105
|
+
not cycle, each a complete declaration you copy and run.
|
|
106
|
+
- [`examples/knowledge-base`](examples/knowledge-base/README.md): two
|
|
107
|
+
pages anchored to code, a cluster config, receipts and a finding
|
|
108
|
+
ledger, for the optional track.
|
|
109
|
+
|
|
110
|
+
## Skills, hooks, templates and recipes
|
|
111
|
+
|
|
112
|
+
- [`templates/skills/`](templates/skills): skills for a coding agent.
|
|
113
|
+
Four for any repository: `enola` (ask the graph before searching, grade
|
|
114
|
+
after changing), `enola-laws` (write a law with a reason, lint it, read
|
|
115
|
+
its verdict), `enola-grade-before-push` (a declined grade is not a
|
|
116
|
+
pass) and `enola-intent-first` (read the governing decision before the
|
|
117
|
+
file moves). Five more belong to the knowledge-base track and call its
|
|
118
|
+
[wrapper](guides/12-the-wrapper.md) (`enola-guides copy templates/kb`):
|
|
119
|
+
`enola-deepdive`, `enola-ingest-check`, `enola-drift`,
|
|
120
|
+
`enola-citation-hygiene`, `enola-zoom-out`.
|
|
121
|
+
- [`templates/hooks/`](templates/hooks): the knowledge-base hooks of
|
|
122
|
+
[guide 10](guides/10-hooks.md).
|
|
123
|
+
- [`templates/`](templates): the CI check script and its comment
|
|
124
|
+
renderer, a cluster configuration, and a starter of four Rails laws.
|
|
125
|
+
- [`recipes/`](recipes/README.md): recipes to copy into your own
|
|
126
|
+
`enola/recipes/` and bind in one block, each with the count its laws
|
|
127
|
+
held at on a real repository; starting points a team reviews, never
|
|
128
|
+
defaults the tool applies.
|
|
129
|
+
|
|
130
|
+
## These guides as a command
|
|
131
|
+
|
|
132
|
+
Everything above is also one command, `enola-guides`, with the same items
|
|
133
|
+
and the same output from every package. Take it from the ecosystem you
|
|
134
|
+
already use:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
gem install enola-guides # RubyGems
|
|
138
|
+
npm install -g enola-guides # npm
|
|
139
|
+
pipx install enola-guides # PyPI (or uv tool install)
|
|
140
|
+
cargo install enola-guides # crates.io
|
|
141
|
+
go install github.com/misabegovic/enola-guides/cmd/enola-guides@latest
|
|
142
|
+
brew install misabegovic/tap/enola-guides # Homebrew
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
or a binary for Linux, macOS or Windows from the
|
|
146
|
+
[releases](https://github.com/misabegovic/enola-guides/releases). Then:
|
|
12
147
|
|
|
13
148
|
```bash
|
|
14
|
-
|
|
15
|
-
|
|
149
|
+
enola-guides list # every item; list guides, list laws, list skills, ...
|
|
150
|
+
enola-guides show guides/01-start-here
|
|
151
|
+
enola-guides copy laws/foreign-keys # writes enola/constraints/foreign-keys.yaml
|
|
152
|
+
enola-guides copy skills/enola # writes .claude/skills/enola/SKILL.md
|
|
153
|
+
enola-guides copy hooks/stop-debt # writes .claude/hooks/stop-debt.sh
|
|
154
|
+
enola-guides copy examples/python-service # a project to try the guides on
|
|
16
155
|
```
|
|
17
156
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
the conventions recipe in one block. [`examples/knowledge-base`](examples/knowledge-base/README.md):
|
|
26
|
-
two pages anchored to code, a cluster config, receipts and a finding ledger,
|
|
27
|
-
the smallest knowledge base the skills and hooks run against. [`examples/laws`](examples/laws/README.md):
|
|
28
|
-
twenty-six laws, one directory each, from foreign keys on a tenant column
|
|
29
|
-
to parts that may not cycle, each a complete declaration you copy and run.
|
|
30
|
-
|
|
31
|
-
## Guides
|
|
32
|
-
|
|
33
|
-
1. [Start here](guides/01-start-here.md): install, snapshot, baseline, a
|
|
34
|
-
graded change, the hooks, a first law. Ten minutes.
|
|
35
|
-
2. [A Rails application](guides/02-rails.md): what enola measures, the
|
|
36
|
-
Prism and Rubydex providers, the recipe, the laws a Rails team writes.
|
|
37
|
-
3. [An Ember application](guides/03-ember.md): the Ember facts, the
|
|
38
|
-
conventions as a recipe, an app inside a larger repository.
|
|
39
|
-
4. [Writing laws](guides/04-writing-laws.md): parts, the twenty-one
|
|
40
|
-
sentences, modes, dates, exemptions, what a refusal means.
|
|
41
|
-
5. [Constraints in CI](guides/05-constraints-in-ci.md): the check step.
|
|
42
|
-
6. [Hooks and agents](guides/06-hooks-and-agents.md): the session hooks,
|
|
43
|
-
the MCP tools, the skills.
|
|
44
|
-
7. [Providers](guides/07-providers.md): the seam, the Ruby pair, the
|
|
45
|
-
census, the runtime capture.
|
|
46
|
-
8. [Beyond one repository](guides/08-beyond-one-repo.md): the cluster, the
|
|
47
|
-
seams, the laws across them, the history.
|
|
48
|
-
9. [A knowledge base with enola](guides/09-a-knowledge-base-with-enola.md):
|
|
49
|
-
what a wiki of decisions gets when its pages anchor to code and every
|
|
50
|
-
number it states was read from a receipt.
|
|
51
|
-
10. [Hooks](guides/10-hooks.md): the four agent hooks a knowledge base runs
|
|
52
|
-
(intent-first gate, turn record, stop-time debt, session refresh).
|
|
53
|
-
11. [The skills, as they run](guides/11-the-skills-as-they-run.md): deepdive
|
|
54
|
-
before shaping, claim check while ingesting, drift on a schedule,
|
|
55
|
-
citation hygiene, the blast radius.
|
|
56
|
-
12. [The wrapper](guides/12-the-wrapper.md): the thin command the skills
|
|
57
|
-
call, the named skip, the receipts and the ledger.
|
|
58
|
-
|
|
59
|
-
## Skills
|
|
60
|
-
|
|
61
|
-
The skills under [`templates/skills/`](templates/skills) are the ones used
|
|
62
|
-
day to day with enola's MCP in an agent session: `enola` (ask the graph
|
|
63
|
-
before grepping, grade after changing), `enola-laws` (write a law as a
|
|
64
|
-
sentence with a reason, lint it, read what it verdicts),
|
|
65
|
-
`enola-grade-before-push` (the delta is the deliverable, a declined grade
|
|
66
|
-
is not a pass), `enola-intent-first` (read the governing decision before
|
|
67
|
-
the file moves), and the five a knowledge base runs: `enola-deepdive`,
|
|
68
|
-
`enola-ingest-check`, `enola-drift`, `enola-citation-hygiene`,
|
|
69
|
-
`enola-zoom-out`, each described as it runs in
|
|
70
|
-
[guide 11](guides/11-the-skills-as-they-run.md). Copy a directory into
|
|
71
|
-
your agent's skills folder; the hooks they pair with are under
|
|
72
|
-
[`templates/hooks/`](templates/hooks).
|
|
73
|
-
|
|
74
|
-
## Templates and recipes
|
|
75
|
-
|
|
76
|
-
[`templates/`](templates): the CI check script and its comment renderer,
|
|
77
|
-
a cluster configuration, a constraints starter. [`recipes/`](recipes/README.md) (the catalogue munola binds, each recipe with the number its laws held at):
|
|
78
|
-
recipes a repository copies into its own `enola/recipes/` and binds in one
|
|
79
|
-
line, starting with the Ember conventions and a house-recipe template;
|
|
80
|
-
starting points the team reviews, never defaults the tool applies.
|
|
157
|
+
`copy` writes an item's files under a directory each kind has a default
|
|
158
|
+
for (`enola/constraints` for a law, `enola/recipes` for a recipe,
|
|
159
|
+
`.claude/skills` for a skill, `.claude/hooks` for a hook) or the one you
|
|
160
|
+
name, and never overwrites: it names the first file that exists and
|
|
161
|
+
writes nothing. The gem also carries the tree itself, so
|
|
162
|
+
`gem contents enola-guides` lists every file and a team can pin the
|
|
163
|
+
guidance it adopted in its `Gemfile`.
|