enola-guides 0.3.1 → 0.8.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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +110 -0
  3. data/LICENSE +1 -1
  4. data/NOTICE +7 -0
  5. data/README.md +57 -12
  6. data/bundle/bundle.json +1606 -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/wiki/_state/enola/receipts.json +2 -2
  20. data/examples/python-service/EXPECTED +6 -0
  21. data/examples/python-service/README.md +31 -0
  22. data/examples/python-service/enola/constraints/domain.yaml +14 -0
  23. data/examples/python-service/enola/constraints/layers.yaml +10 -0
  24. data/examples/python-service/enola/constraints/supply.yaml +7 -0
  25. data/examples/python-service/pyproject.toml +8 -0
  26. data/examples/python-service/shop/__init__.py +0 -0
  27. data/examples/python-service/shop/api/__init__.py +0 -0
  28. data/examples/python-service/shop/api/orders.py +18 -0
  29. data/examples/python-service/shop/domain/__init__.py +0 -0
  30. data/examples/python-service/shop/domain/order.py +6 -0
  31. data/examples/python-service/shop/domain/pricing.py +6 -0
  32. data/examples/python-service/shop/repositories/__init__.py +0 -0
  33. data/examples/python-service/shop/repositories/orders.py +22 -0
  34. data/examples/python-service/shop/services/__init__.py +0 -0
  35. data/examples/python-service/shop/services/checkout.py +8 -0
  36. data/examples/python-service/tests/test_order.py +5 -0
  37. data/examples/rails-shop/mcp-arch.yaml +7 -0
  38. data/examples/rust-service/Cargo.toml +8 -0
  39. data/examples/rust-service/EXPECTED +7 -0
  40. data/examples/rust-service/README.md +32 -0
  41. data/examples/rust-service/enola/constraints/domain.yaml +14 -0
  42. data/examples/rust-service/enola/constraints/layers.yaml +10 -0
  43. data/examples/rust-service/enola/constraints/supply.yaml +7 -0
  44. data/examples/rust-service/src/checkout/mod.rs +8 -0
  45. data/examples/rust-service/src/main.rs +10 -0
  46. data/examples/rust-service/src/order/mod.rs +15 -0
  47. data/examples/rust-service/src/order/pricing.rs +6 -0
  48. data/examples/rust-service/src/store/mod.rs +9 -0
  49. data/examples/rust-service/src/web/mod.rs +24 -0
  50. data/examples/typescript-service/EXPECTED +6 -0
  51. data/examples/typescript-service/README.md +31 -0
  52. data/examples/typescript-service/enola/constraints/domain.yaml +14 -0
  53. data/examples/typescript-service/enola/constraints/layers.yaml +10 -0
  54. data/examples/typescript-service/enola/constraints/supply.yaml +7 -0
  55. data/examples/typescript-service/package.json +10 -0
  56. data/examples/typescript-service/src/db/orders.ts +9 -0
  57. data/examples/typescript-service/src/db/schema.ts +6 -0
  58. data/examples/typescript-service/src/domain/order.ts +9 -0
  59. data/examples/typescript-service/src/domain/pricing.ts +6 -0
  60. data/examples/typescript-service/src/routes/orders.ts +18 -0
  61. data/examples/typescript-service/src/server.ts +7 -0
  62. data/examples/typescript-service/src/services/checkout.ts +8 -0
  63. data/examples/typescript-service/tsconfig.json +4 -0
  64. data/exe/enola-guides +6 -0
  65. data/guides/01-start-here.md +43 -17
  66. data/guides/02-rails.md +55 -31
  67. data/guides/04-writing-laws.md +67 -5
  68. data/guides/05-constraints-in-ci.md +76 -11
  69. data/guides/06-hooks-and-agents.md +90 -17
  70. data/guides/07-providers.md +76 -17
  71. data/guides/08-beyond-one-repo.md +80 -10
  72. data/guides/09-a-knowledge-base-with-enola.md +7 -1
  73. data/guides/10-hooks.md +11 -4
  74. data/guides/11-the-skills-as-they-run.md +5 -0
  75. data/guides/12-the-wrapper.md +4 -0
  76. data/guides/13-tabula.md +205 -0
  77. data/guides/14-taha.md +100 -0
  78. data/guides/15-python.md +140 -0
  79. data/guides/16-typescript.md +116 -0
  80. data/guides/17-go.md +91 -0
  81. data/guides/18-rust.md +87 -0
  82. data/lib/enola-guides/cli.rb +68 -0
  83. data/lib/enola-guides.rb +1 -1
  84. data/recipes/README.md +3 -3
  85. data/templates/enola-check.sh +21 -18
  86. data/templates/enola-cluster.yaml +1 -1
  87. data/templates/enola-findings.rb +22 -1
  88. metadata +78 -9
  89. 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: 3784520433166796cdd4b84e8991d25877fc6c1c97dcd5af9e04b5d8dcf12985
4
+ data.tar.gz: a6e317df671ddcbc2cc90f3077eff8db4ec03e6762cd5c5e3ea8e439d27d3555
5
5
  SHA512:
6
- metadata.gz: f3de1b04dfb1ec8c76f2686d4730052a0f38175721ea288294a09e1f4c2be4fa154d9622748405204b086857bdc5de3969675b49f729b0a5f229f5b8dc5ebebb
7
- data.tar.gz: 49e2f753fa478c657683dbe69b729774dc94129a8ba8bf3c6614469b7576e0752857daa266f993006098e8a3e36eeeada89377412548d122c83f9d4fa41d1a01
6
+ metadata.gz: 7b7987e38206a19d0bddbfa955b77158df65da89b794398ad510c1b63b482f4d28466cba970f1ccf58cf42592e533a2fffa072bd9a89533b60f83852c10b3188
7
+ data.tar.gz: 3a488496fb470ab2eb67183cc0e38bfa6f177892a74437cc808e345b85421ef0683bc6061231a9c6bfe38e3b362c9f597672cc274bbe415140767da699c1bccd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,115 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 (2026-10-25)
4
+
5
+ One command, `enola-guides`, in every ecosystem: RubyGems, npm, PyPI,
6
+ crates.io, Go and Homebrew, and binaries for Linux, macOS and Windows on
7
+ the GitHub release. `list`, `show` and `copy` read one catalogue,
8
+ `bundle/bundle.json`, generated from the tree by `script/bundle`: 74 items
9
+ across guides, examples, laws, skills, hooks, recipes and templates. The
10
+ five implementations (Go, Rust, Node, Python, Ruby) are held to the same
11
+ 22 cases, byte for byte, by `script/test-clis`, and CI runs them against
12
+ each package as installed from the artifact a release would publish, and
13
+ installs the Homebrew formula from a local tap. `VERSION` is the one
14
+ version; a tag `vX.Y.Z` publishes everywhere through trusted publishing
15
+ (`RELEASING.md`). A `NOTICE` names enola. `CONTRIBUTING.md`, `SECURITY.md`,
16
+ a code of conduct, issue and pull-request templates and Dependabot for the
17
+ actions and the crate; `script/test` runs every check CI runs that needs
18
+ no registry.
19
+
20
+ ## 0.7.0 (2026-10-25)
21
+
22
+ Python, TypeScript, Go and Rust. Guides 15 to 18 and a worked example in
23
+ each language: the same four-layer service with its source, binding the
24
+ `layered` and `supply-chain` recipes and breaking its laws on purpose.
25
+ `script/test-examples` snapshots every example with the pinned enola and
26
+ fails when the laws reporting a breach are not exactly the ones its
27
+ `EXPECTED` file lists. What the examples showed on v0.4.34, each said
28
+ where it bites:
29
+
30
+ - `layered`'s two domain rules read `depends_on`, which none of the four
31
+ extractors writes, so each example states the domain's law over
32
+ `imports`.
33
+ - A TypeScript handler written inline puts its calls on the file, where
34
+ the edge rules do not walk; a named handler is walked.
35
+ - An Express `router.post("/")` under a mount produces no route.
36
+ - An Axum router nested inline keeps its bare paths.
37
+ - A Cargo version with no operator counts as pinned.
38
+
39
+ Guide 01 states its first law in YAML as well as Ruby, and the README
40
+ no longer reads as Rubyists first.
41
+
42
+ ## 0.6.0 (2026-10-25)
43
+
44
+ tabula and taha. Guide 13 is tabula for an enola user: a release that
45
+ carries cardo inside the binary and finds it last, after `engine.binary`
46
+ and any `enola` on PATH; the tour; laws said on an architecture page and
47
+ compiled into plain enola YAML that upstream v0.4.34 lints clean; a PRD
48
+ bullet graded with `grade: enola check clean`; its hooks beside enola's;
49
+ and which hand-built piece of guides 09 to 12 each verb replaces. Guide
50
+ 14 is taha: installing from a clone (the npm name `taha` is another
51
+ package's), a run under a mandate, adopting a repository enola already
52
+ measures, and the `cardo` it calls by name. Guides 09 to 12 keep the
53
+ hand-built path and say where tabula takes it over.
54
+
55
+ ## 0.5.0 (2026-10-25)
56
+
57
+ What enola shipped between v0.4.4 and v0.4.34, each command and key run
58
+ against v0.4.34 before it was written down:
59
+
60
+ - Guide 05: enola-action@v2, with the install step that gives it the
61
+ Rubydex library it does not fetch itself, its outputs, and `-format`
62
+ `sarif`, `annotations` and `summary`; `-reviewers`. A CI job runs the
63
+ workflow the guide prints.
64
+ - Guide 06: the opencode and Pi install targets, the Claude Code plugin
65
+ and what it leaves out, all twenty-two MCP tools, and the questions the
66
+ CLI answers without an agent (`impact`, `endpoint`, `plan`, `flows`,
67
+ `constraints ledger`, `dashboard`).
68
+ - Guide 07: the rbs and zeitwerk providers, provider reuse, and pinning a
69
+ provider of your own.
70
+ - Guide 08: `cluster init` and folders indexed as clusters, why the
71
+ output directory needs its own name (it is resolved inside each
72
+ member), `matched_routes`, `caller`, `unreached_by_clients`, `coverage
73
+ --unresolved`, declaring an in-house HTTP client, and sharing the
74
+ history.
75
+ - Guide 04: laws over dependencies and the `supply-chain` recipe, the
76
+ ledger, `no_frame_in_members`, and how `since` falls back to git.
77
+ In v0.4.34 a Ruby `where:` drops a value that is not a string or a
78
+ symbol, so the guide quotes booleans and numbers.
79
+ - Guide 02: the `packwerk` explainer and the `package_paths` it needs
80
+ when packs live outside `packages/`, and the `ruby-conventions` recipe.
81
+
82
+ ## 0.4.0 (2026-10-25)
83
+
84
+ Checked against enola v0.4.34. enola skips a provider whose
85
+ `expected_version` disagrees with what it answers, and the guides pinned
86
+ Prism at `0.1.0` (the script answers `0.2.0` since v0.4.5) and Rubydex at
87
+ `0.4.0` (the binary carries `0.4.1` since v0.4.33), so their Ruby
88
+ configurations produced no provider facts. Every configuration now names
89
+ the built-in `rubydex` and `prism` providers with no pin; neither needs
90
+ Ruby. Also fixed, each wrong before this release too:
91
+
92
+ - The configuration file is `mcp-arch.yaml`; enola never read
93
+ `enola.yaml`, so `examples/rails-shop` now ships `mcp-arch.yaml`.
94
+ - `templates/enola-check.sh` defaults to v0.4.34 (it named `0.5.0`, which
95
+ does not exist), installs the binary under the name the release archive
96
+ gives it, configures the built-in providers in a tree with a `Gemfile`,
97
+ and grades with the configuration it generated with; grading the bare
98
+ path read no providers and reported every Ruby run as a partial verdict.
99
+ - `templates/enola-findings.rb` renders a partial verdict and names each
100
+ producer it left ungraded.
101
+ - `constraints init` writes `enola/constraints/recipes.yaml`.
102
+ - A provider that ran on one side only gives a partial verdict, not a
103
+ decline; the session-start hook pins a baseline, and in Claude Code a
104
+ `PreToolUse` hook refuses the first two file searches.
105
+ - `doctor` reports the hooks and the baseline, not the Rubydex library.
106
+ - The recipes README lists `ruby-conventions` and `supply-chain` among
107
+ upstream's built-ins.
108
+
109
+ A CI workflow lints every example against the pinned enola release, runs
110
+ the check template end to end on a Rails fixture, and checks every
111
+ relative link.
112
+
3
113
  ## 0.3.1 (2026-08-23)
4
114
 
5
115
  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,20 +1,46 @@
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
+ How to use [enola](https://github.com/enola-labs/enola), the tool that
4
+ grades what a change did to a codebase's architecture, checked against
5
+ v0.4.34: laws written as sentences in Ruby or YAML, recipes a team
6
+ reviews, providers that run beside enola's own extractors, the check in
7
+ CI, the hooks and MCP tools an agent uses during a session, and the
8
+ knowledge base built on top of it with [tabula](guides/13-tabula.md) and
9
+ [taha](guides/14-taha.md). Guides for Rails, Ember, Python, TypeScript,
10
+ Go and Rust, worked examples that CI snapshots and grades on every change,
11
+ skills and templates, packaged so a team can pin the guidance it adopted.
12
+
13
+ ## Install
14
+
15
+ One command, `enola-guides`, with the same items and the same output from
16
+ every package. Take it from the ecosystem you already use:
12
17
 
13
18
  ```bash
14
- gem install enola-guides
15
- gem contents enola-guides
19
+ gem install enola-guides # RubyGems
20
+ npm install -g enola-guides # npm
21
+ pipx install enola-guides # PyPI (or uv tool install)
22
+ cargo install enola-guides # crates.io
23
+ go install github.com/misabegovic/enola-guides/cmd/enola-guides@latest
24
+ brew install misabegovic/tap/enola-guides # Homebrew
16
25
  ```
17
26
 
27
+ or a binary for Linux, macOS or Windows from the
28
+ [releases](https://github.com/misabegovic/enola-guides/releases). Then:
29
+
30
+ ```bash
31
+ enola-guides list # every item; list guides, list laws, list skills, ...
32
+ enola-guides show guides/01-start-here
33
+ enola-guides copy laws/foreign-keys # writes enola/constraints/foreign-keys.yaml
34
+ enola-guides copy skills/enola # writes .claude/skills/enola/SKILL.md
35
+ ```
36
+
37
+ `copy` writes an item's files under a directory each kind has a default
38
+ for (`enola/constraints` for a law, `.claude/skills` for a skill,
39
+ `enola/recipes` for a recipe) or the one you name, and never overwrites:
40
+ it names the first file that exists and writes nothing. The gem also
41
+ carries the tree itself, so `gem contents enola-guides` lists every file
42
+ and a team can pin the guidance it adopted in its `Gemfile`.
43
+
18
44
  ## Start with an example
19
45
 
20
46
  [`examples/rails-shop`](examples/rails-shop): a Rails application declaring
@@ -24,7 +50,12 @@ with Prism and Rubydex configured as providers beside the extractors.
24
50
  [`examples/ember-app`](examples/ember-app): an Ember application bound to
25
51
  the conventions recipe in one block. [`examples/knowledge-base`](examples/knowledge-base/README.md):
26
52
  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):
53
+ the smallest knowledge base the skills and hooks run against. [`examples/python-service`](examples/python-service),
54
+ [`examples/typescript-service`](examples/typescript-service),
55
+ [`examples/go-service`](examples/go-service) and
56
+ [`examples/rust-service`](examples/rust-service): the same four-layer
57
+ service in each language, with its source, breaking the laws it states on
58
+ purpose so you can watch each one fire. [`examples/laws`](examples/laws/README.md):
28
59
  twenty-six laws, one directory each, from foreign keys on a tenant column
29
60
  to parts that may not cycle, each a complete declaration you copy and run.
30
61
 
@@ -55,6 +86,20 @@ to parts that may not cycle, each a complete declaration you copy and run.
55
86
  citation hygiene, the blast radius.
56
87
  12. [The wrapper](guides/12-the-wrapper.md): the thin command the skills
57
88
  call, the named skip, the receipts and the ledger.
89
+ 13. [tabula](guides/13-tabula.md): the knowledge base kept by a tool that
90
+ carries cardo, its laws compiled into `enola/constraints/`, PRDs
91
+ graded with `enola check`, and which hand-built piece each verb
92
+ replaces.
93
+ 14. [taha](guides/14-taha.md): agents run on a tabula project under a
94
+ mandate, gated by tabula's verdicts, asking before anything is
95
+ published.
96
+ 15. [A Python service](guides/15-python.md),
97
+ 16. [a TypeScript or JavaScript service](guides/16-typescript.md),
98
+ 17. [a Go service](guides/17-go.md), and
99
+ 18. [a Rust service](guides/18-rust.md): what enola measures in each
100
+ language, the `layered` recipe bound to a service, the law over
101
+ `imports` its domain rules need, dependencies, and where v0.4.34 reads
102
+ less than the code says.
58
103
 
59
104
  ## Skills
60
105