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.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +168 -0
  3. data/LICENSE +1 -1
  4. data/NOTICE +7 -0
  5. data/README.md +157 -74
  6. data/bundle/bundle.json +1666 -0
  7. data/examples/go-service/EXPECTED +5 -0
  8. data/examples/go-service/README.md +32 -0
  9. data/examples/go-service/cmd/shop/main.go +11 -0
  10. data/examples/go-service/enola/constraints/domain.yaml +14 -0
  11. data/examples/go-service/enola/constraints/layers.yaml +10 -0
  12. data/examples/go-service/enola/constraints/supply.yaml +7 -0
  13. data/examples/go-service/go.mod +5 -0
  14. data/examples/go-service/internal/checkout/checkout.go +14 -0
  15. data/examples/go-service/internal/order/order.go +18 -0
  16. data/examples/go-service/internal/order/pricing.go +8 -0
  17. data/examples/go-service/internal/store/store.go +13 -0
  18. data/examples/go-service/internal/web/routes.go +30 -0
  19. data/examples/knowledge-base/README.md +6 -2
  20. data/examples/knowledge-base/enola-cluster.yaml +6 -6
  21. data/examples/knowledge-base/wiki/_state/enola/findings.json +2 -2
  22. data/examples/knowledge-base/wiki/_state/enola/receipts.json +11 -8
  23. data/examples/knowledge-base/wiki/shop/permanent/architecture.md +1 -1
  24. data/examples/knowledge-base/wiki/shop/permanent/public-surface.md +3 -3
  25. data/examples/laws/clean-rings/README.md +3 -1
  26. data/examples/laws/cluster-laws/README.md +3 -1
  27. data/examples/laws/cqrs-queries-never-write/README.md +3 -1
  28. data/examples/laws/foreign-keys/README.md +3 -1
  29. data/examples/laws/governed-code/README.md +3 -1
  30. data/examples/laws/instantiation/README.md +3 -1
  31. data/examples/laws/maintenance-tasks/README.md +3 -1
  32. data/examples/laws/mixins-stay-independent/README.md +3 -1
  33. data/examples/laws/naming-conventions/README.md +3 -1
  34. data/examples/laws/one-door/README.md +3 -1
  35. data/examples/laws/one-owner-per-table/README.md +3 -1
  36. data/examples/laws/paired-names/README.md +3 -1
  37. data/examples/laws/parts-never-cycle/README.md +3 -1
  38. data/examples/laws/protocol-any-of/README.md +3 -1
  39. data/examples/laws/public-surface/README.md +3 -1
  40. data/examples/laws/public-tool-prefix/README.md +3 -1
  41. data/examples/laws/rails-forbidden-names/README.md +3 -1
  42. data/examples/laws/rails-mutations-are-authorized/README.md +3 -1
  43. data/examples/laws/rails-request-boundaries/README.md +3 -1
  44. data/examples/laws/rails-strict-arrangement/README.md +3 -1
  45. data/examples/laws/readers-read-the-store-only/README.md +3 -1
  46. data/examples/laws/receiverless-request-api/README.md +3 -1
  47. data/examples/laws/resolved-ancestry/README.md +3 -1
  48. data/examples/laws/routes-have-consumers/README.md +3 -1
  49. data/examples/laws/storage-stays-home/README.md +3 -1
  50. data/examples/laws/vanilla-rails-stays-empty/README.md +3 -1
  51. data/examples/python-service/EXPECTED +6 -0
  52. data/examples/python-service/README.md +31 -0
  53. data/examples/python-service/enola/constraints/domain.yaml +14 -0
  54. data/examples/python-service/enola/constraints/layers.yaml +10 -0
  55. data/examples/python-service/enola/constraints/supply.yaml +7 -0
  56. data/examples/python-service/pyproject.toml +8 -0
  57. data/examples/python-service/shop/__init__.py +0 -0
  58. data/examples/python-service/shop/api/__init__.py +0 -0
  59. data/examples/python-service/shop/api/orders.py +18 -0
  60. data/examples/python-service/shop/domain/__init__.py +0 -0
  61. data/examples/python-service/shop/domain/order.py +6 -0
  62. data/examples/python-service/shop/domain/pricing.py +6 -0
  63. data/examples/python-service/shop/repositories/__init__.py +0 -0
  64. data/examples/python-service/shop/repositories/orders.py +22 -0
  65. data/examples/python-service/shop/services/__init__.py +0 -0
  66. data/examples/python-service/shop/services/checkout.py +8 -0
  67. data/examples/python-service/tests/test_order.py +5 -0
  68. data/examples/rails-shop/mcp-arch.yaml +7 -0
  69. data/examples/rust-service/Cargo.toml +8 -0
  70. data/examples/rust-service/EXPECTED +7 -0
  71. data/examples/rust-service/README.md +32 -0
  72. data/examples/rust-service/enola/constraints/domain.yaml +14 -0
  73. data/examples/rust-service/enola/constraints/layers.yaml +10 -0
  74. data/examples/rust-service/enola/constraints/supply.yaml +7 -0
  75. data/examples/rust-service/src/checkout/mod.rs +8 -0
  76. data/examples/rust-service/src/main.rs +10 -0
  77. data/examples/rust-service/src/order/mod.rs +15 -0
  78. data/examples/rust-service/src/order/pricing.rs +6 -0
  79. data/examples/rust-service/src/store/mod.rs +9 -0
  80. data/examples/rust-service/src/web/mod.rs +24 -0
  81. data/examples/typescript-service/EXPECTED +6 -0
  82. data/examples/typescript-service/README.md +31 -0
  83. data/examples/typescript-service/enola/constraints/domain.yaml +14 -0
  84. data/examples/typescript-service/enola/constraints/layers.yaml +10 -0
  85. data/examples/typescript-service/enola/constraints/supply.yaml +7 -0
  86. data/examples/typescript-service/package.json +10 -0
  87. data/examples/typescript-service/src/db/orders.ts +9 -0
  88. data/examples/typescript-service/src/db/schema.ts +6 -0
  89. data/examples/typescript-service/src/domain/order.ts +9 -0
  90. data/examples/typescript-service/src/domain/pricing.ts +6 -0
  91. data/examples/typescript-service/src/routes/orders.ts +18 -0
  92. data/examples/typescript-service/src/server.ts +7 -0
  93. data/examples/typescript-service/src/services/checkout.ts +8 -0
  94. data/examples/typescript-service/tsconfig.json +4 -0
  95. data/exe/enola-guides +6 -0
  96. data/guides/00-concepts.md +97 -0
  97. data/guides/01-start-here.md +242 -58
  98. data/guides/02-rails.md +80 -36
  99. data/guides/03-ember.md +15 -4
  100. data/guides/04-writing-laws.md +223 -15
  101. data/guides/05-constraints-in-ci.md +171 -33
  102. data/guides/06-hooks-and-agents.md +209 -35
  103. data/guides/07-providers.md +93 -23
  104. data/guides/08-beyond-one-repo.md +104 -13
  105. data/guides/09-a-knowledge-base-with-enola.md +22 -8
  106. data/guides/10-hooks.md +50 -21
  107. data/guides/11-the-skills-as-they-run.md +17 -5
  108. data/guides/12-the-wrapper.md +41 -7
  109. data/guides/13-tabula.md +215 -0
  110. data/guides/14-taha.md +110 -0
  111. data/guides/15-python.md +155 -0
  112. data/guides/16-typescript.md +130 -0
  113. data/guides/17-go.md +103 -0
  114. data/guides/18-rust.md +99 -0
  115. data/guides/19-rolling-out.md +131 -0
  116. data/guides/20-reading-a-verdict.md +183 -0
  117. data/lib/enola-guides/cli.rb +68 -0
  118. data/lib/enola-guides.rb +1 -1
  119. data/recipes/README.md +10 -10
  120. data/templates/constraints-starter/background-jobs-never-invoke-controller-code.rb +6 -0
  121. data/templates/constraints-starter/models-do-not-reach-controllers.rb +6 -0
  122. data/templates/constraints-starter/policies-only-answer.rb +6 -0
  123. data/templates/constraints-starter/the-request-api-stays-in-controllers.rb +6 -0
  124. data/templates/enola-check.sh +104 -37
  125. data/templates/enola-cluster.yaml +1 -1
  126. data/templates/enola-findings.rb +52 -11
  127. data/templates/hooks/intent-first-gate.sh +13 -2
  128. data/templates/hooks/record.sh +15 -4
  129. data/templates/hooks/stop-debt.sh +4 -2
  130. data/templates/kb/kb +367 -0
  131. data/templates/skills/enola/SKILL.md +15 -3
  132. data/templates/skills/enola-citation-hygiene/SKILL.md +7 -1
  133. data/templates/skills/enola-deepdive/SKILL.md +7 -1
  134. data/templates/skills/enola-drift/SKILL.md +7 -1
  135. data/templates/skills/enola-grade-before-push/SKILL.md +16 -7
  136. data/templates/skills/enola-ingest-check/SKILL.md +7 -1
  137. data/templates/skills/enola-laws/SKILL.md +19 -4
  138. data/templates/skills/enola-zoom-out/SKILL.md +7 -1
  139. metadata +82 -9
  140. data/examples/rails-shop/enola.yaml +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8f7f20100ffdeea1ae928ad9e76186848aeba81caed9491993e09cfc5bc7461
4
- data.tar.gz: dcbacd0bba3cf8ee9883b1590a8cd969d1c01150d4549789c1869920dad8de9e
3
+ metadata.gz: 8d1b81f179855dbd64a4feb84618651f3b3805d7410dd82f09238fb9a3896f00
4
+ data.tar.gz: 46ec48df52057f409f66e0a60ee1c32224cdfc84f06da9474c85561923a677b5
5
5
  SHA512:
6
- metadata.gz: f3de1b04dfb1ec8c76f2686d4730052a0f38175721ea288294a09e1f4c2be4fa154d9622748405204b086857bdc5de3969675b49f729b0a5f229f5b8dc5ebebb
7
- data.tar.gz: 49e2f753fa478c657683dbe69b729774dc94129a8ba8bf3c6614469b7576e0752857daa266f993006098e8a3e36eeeada89377412548d122c83f9d4fa41d1a01
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 Dejan Menges
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
- How to use what [enola](https://github.com/enola-labs/enola) ships since
4
- v0.4.4 ([enola-labs/enola#247](https://github.com/enola-labs/enola/pull/247)): a
5
- Ruby DSL for writing architecture constraints, Prism and Rubydex as
6
- providers that run together with enola's own extractors, recipes a team
7
- reviews, laws that read the whole graph, and an MCP your agent uses during
8
- a session. Guides, worked examples, skills and templates, packaged as a
9
- gem so a team can pin the guidance it adopted. Rubyists first; consumed by
10
- [enola-rb](https://github.com/misabegovic/enola-rb), the gem that runs
11
- enola. Expanding as the practice does.
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
- gem install enola-guides
15
- gem contents enola-guides
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
- ## Start with an example
19
-
20
- [`examples/rails-shop`](examples/rails-shop): a Rails application declaring
21
- thirteen laws in the Ruby DSL, one file each, from "jobs never invoke controller code" to
22
- "billing keeps to its own tables" and "a mutating action is authorized",
23
- with Prism and Rubydex configured as providers beside the extractors.
24
- [`examples/ember-app`](examples/ember-app): an Ember application bound to
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`.