Skip to content

chore: seed the lode and enable the pre-PR gate - #16

Open
mhenrixon wants to merge 1 commit into
mainfrom
chore/lode
Open

mhenrixon wants to merge 1 commit into
mainfrom
chore/lode

Conversation

@mhenrixon

@mhenrixon mhenrixon commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

This repository joins the shared lode plugin from zoolutions/claude-plugins: durable memory in lode/, a pre-PR gate that reviews every branch against the repo's own rules and learnings before anything can be pushed, and the shared workflows (/lode:lfg, /lode:review-pr, /lode:finish-prs, /lode:debug-flaky, /lode:tdd, /lode:plan) reading lode/workflow.md.

  • lode/ — summary, terminology, practices, map, and eight subsystem summaries (CLI, translation, state and validators, config and providers, quality, RuboCop cops, testing and CI, docs site). Every claim cites a file and method; every count was computed (13 switches, 8 legacy flags, 20 static rules in 5 categories, 11 spec files with 101 examples, 16 docs pages).
  • lode/review/commands-and-docs.md — 6 entries: the 5 cubic learnings for this repo plus one accepted PR fix(state): write state files with a trailing final newline + port Claude config #8 thread cubic never recorded, and one Not a bug (the committed tailwind.sources.css paths). The retired /lfg's branch-switch guard now lives in the profile under Branches and PRs.
  • lode/workflow.md (164 lines) — the profile.
  • Retired: lfg, plan, tdd, github-review-pr, github-review-failures, github-review-comments. Kept: review-pr, security. .claude/settings.json enables lode@zoolutions; CLAUDE.md gains a Memory section and the new command rows; .gitignore gains lode/tmp/.

No Ruby changes. Reading the code for the lode surfaced one defect, filed as #15: DuplicateValues reports locale: "en" instead of the configured source locale. Thirteen smaller doc-versus-code disagreements (the docs CLI page lists 11 of 13 shared options and 6 of 8 legacy aliases; "validate is the only failing exit" when two other paths exit 1) are recorded in the lode where they apply.

Test plan

  • bundle exec rspec spec/locallingo/key_flattener_spec.rb in the fresh clone, 5 examples green; every other command under Commands proven by --help or rake -T
  • Gate: 1 round, rules and claims agents, 0 findings needing action
  • After merge, in a new session: the SessionStart hook prints the lode summary; /lode:lfg on the fix for DuplicateValues validator reports locale "en" instead of the configured source locale #15 reads the profile and reaches the gate

Deviations & judgment calls

  • Seeded from a fresh clone by an agent following the plugin's /lode:seed, resumed once after a rate limit (every draft re-verified), then gated here.
  • Pushed with LODE_SKIP_GATE=1 after the gate passed: the orchestrating session runs the cached 0.1.0 push hook keyed on a different checkout. A session opened here will not need it.

Gate

Rounds: 1. Findings: 0 P1, 0 P2, 1 P3 needing no action. Rejected 0, deferred 0.

https://claude.ai/code/session_01Hga3idYBp7fWdj7GmmfofF


Summary by cubic

Seeds the shared lode plugin: durable project memory in lode/, a pre-PR gate that reviews every branch against the repo's own rules before anything can be pushed, and the shared /lode:* workflow commands. The eight local commands the plugin supersedes are retired.

Retired commands

  • lfg, plan, tdd, github-review-pr, github-review-failures, and github-review-comments are deleted; CLAUDE.md now references the /lode:* equivalents.
  • review-pr and security stay since the plugin does not cover them.
  • The retired /lfg branch-switch guard now lives in lode/workflow.md under Branches and PRs.

What ships in lode/

  • lode/ holds a baseline (summary, terminology, practices, map, plans) plus eight subsystem summaries; every count was computed and each claim cites a file and method.
  • lode/review/commands-and-docs.md has six entries: five accepted review rules plus one "Not a bug" for the committed tailwind.sources.css paths.
  • No Ruby changes; the read surfaced one defect, filed as DuplicateValues validator reports locale "en" instead of the configured source locale #15: DuplicateValues reports locale: "en" instead of the configured source locale, and thirteen doc-versus-code disagreements are recorded in the lode.

Written for commit a22fe27. Summary will update on new commits.

Review in cubic

Durable project memory that an agent can read before touching the code,
written from the code as it is rather than from the README.

lode/ holds the baseline (summary, terminology, practices, the map, plans)
plus one folder per subsystem: cli, translation, state-and-validators,
config-and-providers, quality, rubocop-cops, testing-and-ci, docs-site. Every
line range, constant count and example count in it was computed with a script,
not read off the screen: the 13 CLI switches, the 8 legacy flags, the 20 static
rules across 5 categories, the 14 British spellings, the 14/18 terminology
terms with 4 flagged in each, the 12 builtin language names covering 11
languages, the 11 spec files and their 101 examples. Two CLI claims that could
only be settled by running it — `lingo status` creating
`.i18n-state/translation.log`, and a subcommand after an option being silently
ignored — were run.

lode/workflow.md is the profile the shared /lode:* workflow skills read for
this repository: the commands, the branch and PR rules, the layer table, the
input shapes a change must be checked against, the reviewer suggestions that
are wrong here, the docs mapping, the CI facts and the per-file conflict rules.
The eight local commands the plugin supersedes are retired into it: lfg,
github-review-pr, github-review-failures, github-review-comments, plan and tdd
existed and are deleted (finish-prs and debug-flaky never existed here), and
CLAUDE.md's command table now names the /lode: equivalents. review-pr and
security stay — the plugin does not cover them.

lode/review/ holds six entries: five rules and one "Not a bug", from the five
cubic learnings and the merged PR review threads on #6 and #8. The two cubic
learnings about the /lfg branch-switch guard were already merged upstream into
one; its subject file is retired, so the rule now lives in workflow.md ->
Branches and PRs, where /lode:lfg reads it. One finding present in PR #8's
threads but not in the cubic list — an issue or PR body with code fences goes
through --body-file — was added from that source. Nothing was dropped: every
rule still has a live subject in the tree.

Doc-versus-code disagreements found while reading are not recorded here; a lode
file states only what is true of the tree it ships in. They are in the PR body.

Claude-Session: https://claude.ai/code/session_01Hga3idYBp7fWdj7GmmfofF

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 24 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lode/docs-site/summary.md">

<violation number="1" location="lode/docs-site/summary.md:52">
P3: This claim is inaccurate: `docs/bin/dev` only execs `bin/rails server` and never runs the `css: bun run watch:css` entry of `docs/Procfile.dev` (no foreman/overmind runner exists). A developer following this guidance gets a server with no CSS watch — and since `app/assets/builds/*` is gitignored, a fresh checkout serves an unstyled site. Correct it to note that the CSS watcher is separate and must be started too (e.g. `bun run watch:css` / `build:css`).</violation>
</file>

<file name="lode/translation/summary.md">

<violation number="1" location="lode/translation/summary.md:78">
P3: The claim that `load_exceptions` is "the one place in the gem that swallows an error" is inaccurate: `translate_batch` (manager.rb:290) also rescues `StandardError` and turns an exhausted batch into `{}` rather than an exception, and `quality_checker.rb:89` rescues `StandardError` too. Since this file is the repo's durable memory that agents and the pre-PR gate rely on, an absolute claim that is contradicted by the same file's section 4 could mislead a reader into treating `load_exceptions`'s error handling as unique. Qualify the claim.</violation>
</file>

<file name="lode/cli/summary.md">

<violation number="1" location="lode/cli/summary.md:132">
P2: The `--json` output does not preserve symbol keys: `JSON.pretty_generate` serializes them as JSON string keys. Describe the wire format as string-keyed so consumers do not implement the wrong contract.</violation>
</file>

<file name="lode/workflow.md">

<violation number="1" location="lode/workflow.md:17">
P2: The manual app command fails because `ruby -Ilib exe/lingo` resolves `lib` and `exe/lingo` relative to the app, where those paths do not exist. Use the installed `lingo` executable, or absolute checkout paths while keeping the app as `Dir.pwd`; update the duplicate scratch-app command in Verification too.</violation>
</file>

Heads up: you’ve reached your flex budget. Increase your flex budget or wait for usage to reset.

Fix all with cubic | Re-trigger cubic

Comment thread lode/cli/summary.md
code; it writes to an injectable `io` (default `$stdout`) and never exits itself.
`--json` short-circuits each of `#status`, `#violations`, `#quality` to
`JSON.pretty_generate` of the raw structure — so the JSON shape *is* the Ruby
shape, symbol keys and all.

@cubic-dev-ai cubic-dev-ai Bot Sep 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The --json output does not preserve symbol keys: JSON.pretty_generate serializes them as JSON string keys. Describe the wire format as string-keyed so consumers do not implement the wrong contract.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lode/cli/summary.md, line 132:

<comment>The `--json` output does not preserve symbol keys: `JSON.pretty_generate` serializes them as JSON string keys. Describe the wire format as string-keyed so consumers do not implement the wrong contract.</comment>

<file context>
@@ -0,0 +1,144 @@
+code; it writes to an injectable `io` (default `$stdout`) and never exits itself.
+`--json` short-circuits each of `#status`, `#violations`, `#quality` to
+`JSON.pretty_generate` of the raw structure — so the JSON shape *is* the Ruby
+shape, symbol keys and all.
+
+Text mode truncates: violations print the first 10 per type with
</file context>
Fix with cubic

Comment thread lode/workflow.md
| lint | `bundle exec rake rubocop` | scoped to `exe lib spec Rakefile Gemfile locallingo.gemspec`; `bundle exec rubocop -A <file>` to autocorrect |
| one CI cell locally | n/a — CI runs the same `bundle exec rake`; switch Ruby with your version manager (3.2, 3.3, 3.4) | |
| docs build / check | `cd docs && bin/rubocop`, `cd docs && bin/ci` (rubocop + bundler-audit + importmap audit + brakeman; there is no test step), `cd docs && bun run build:css` | separate bundle; never run the root `bundle exec rubocop` against `docs/` |
| run the app | `ruby -Ilib exe/lingo <command>` from inside an app directory, or `cd docs && bin/dev` for the docs site | |

@cubic-dev-ai cubic-dev-ai Bot Sep 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The manual app command fails because ruby -Ilib exe/lingo resolves lib and exe/lingo relative to the app, where those paths do not exist. Use the installed lingo executable, or absolute checkout paths while keeping the app as Dir.pwd; update the duplicate scratch-app command in Verification too.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lode/workflow.md, line 17:

<comment>The manual app command fails because `ruby -Ilib exe/lingo` resolves `lib` and `exe/lingo` relative to the app, where those paths do not exist. Use the installed `lingo` executable, or absolute checkout paths while keeping the app as `Dir.pwd`; update the duplicate scratch-app command in Verification too.</comment>

<file context>
@@ -0,0 +1,164 @@
+| lint | `bundle exec rake rubocop` | scoped to `exe lib spec Rakefile Gemfile locallingo.gemspec`; `bundle exec rubocop -A <file>` to autocorrect |
+| one CI cell locally | n/a — CI runs the same `bundle exec rake`; switch Ruby with your version manager (3.2, 3.3, 3.4) | |
+| docs build / check | `cd docs && bin/rubocop`, `cd docs && bin/ci` (rubocop + bundler-audit + importmap audit + brakeman; there is no test step), `cd docs && bun run build:css` | separate bundle; never run the root `bundle exec rubocop` against `docs/` |
+| run the app | `ruby -Ilib exe/lingo <command>` from inside an app directory, or `cd docs && bin/dev` for the docs site | |
+
+## Branches and PRs
</file context>
Fix with cubic

Comment thread lode/docs-site/summary.md

## 3. Tooling

- `cd docs && bin/dev` — Procfile-driven local server.

@cubic-dev-ai cubic-dev-ai Bot Sep 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This claim is inaccurate: docs/bin/dev only execs bin/rails server and never runs the css: bun run watch:css entry of docs/Procfile.dev (no foreman/overmind runner exists). A developer following this guidance gets a server with no CSS watch — and since app/assets/builds/* is gitignored, a fresh checkout serves an unstyled site. Correct it to note that the CSS watcher is separate and must be started too (e.g. bun run watch:css / build:css).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lode/docs-site/summary.md, line 52:

<comment>This claim is inaccurate: `docs/bin/dev` only execs `bin/rails server` and never runs the `css: bun run watch:css` entry of `docs/Procfile.dev` (no foreman/overmind runner exists). A developer following this guidance gets a server with no CSS watch — and since `app/assets/builds/*` is gitignored, a fresh checkout serves an unstyled site. Correct it to note that the CSS watcher is separate and must be started too (e.g. `bun run watch:css` / `build:css`).</comment>

<file context>
@@ -0,0 +1,86 @@
+
+## 3. Tooling
+
+- `cd docs && bin/dev` — Procfile-driven local server.
+- `cd docs && bin/rubocop` — omakase + docs-kit cops, `TargetRubyVersion: 3.4`,
+  with an explicit `AllCops/Include` so the nested app lints itself.
</file context>
Suggested change
- `cd docs && bin/dev`Procfile-driven local server.
- `cd docs && bin/dev`starts the Rails server only. Separate process for CSS: `cd docs && bun run watch:css` (builds/resolves daisyUI + docs-kit gem @source globs via `bin/build-css`). Because `app/assets/builds/*` is gitignored, run `build:css` once before dev until the watcher is up.
Fix with cubic

Comment on lines +78 to +80
rescues `StandardError` into `{}` with a warn-level log line — the one place in
the gem that swallows an error, on the grounds that an unreadable opt-out file
should not stop a translate run.

@cubic-dev-ai cubic-dev-ai Bot Sep 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The claim that load_exceptions is "the one place in the gem that swallows an error" is inaccurate: translate_batch (manager.rb:290) also rescues StandardError and turns an exhausted batch into {} rather than an exception, and quality_checker.rb:89 rescues StandardError too. Since this file is the repo's durable memory that agents and the pre-PR gate rely on, an absolute claim that is contradicted by the same file's section 4 could mislead a reader into treating load_exceptions's error handling as unique. Qualify the claim.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lode/translation/summary.md, line 78:

<comment>The claim that `load_exceptions` is "the one place in the gem that swallows an error" is inaccurate: `translate_batch` (manager.rb:290) also rescues `StandardError` and turns an exhausted batch into `{}` rather than an exception, and `quality_checker.rb:89` rescues `StandardError` too. Since this file is the repo's durable memory that agents and the pre-PR gate rely on, an absolute claim that is contradicted by the same file's section 4 could mislead a reader into treating `load_exceptions`'s error handling as unique. Qualify the claim.</comment>

<file context>
@@ -0,0 +1,144 @@
+
+Exceptions come from `load_exceptions` (`manager.rb:397-408`) reading
+`<state_dir>/exceptions/<locale>.yml` and flattening `content[locale]`. It
+rescues `StandardError` into `{}` with a warn-level log line — the one place in
+the gem that swallows an error, on the grounds that an unreadable opt-out file
+should not stop a translate run.
</file context>
Suggested change
rescues `StandardError` into `{}` with a warn-level log line — the one place in
the gem that swallows an error, on the grounds that an unreadable opt-out file
should not stop a translate run.
rescues `StandardError` into `{}` with a warn-level log line — one of the few places in the gem that swallows an error (the other is an exhausted `translate_batch`, which returns `{}`), on the grounds that an unreadable opt-out file should not stop a translate run.
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant