Skip to content

Pre-release hardening: five issues found installing into a real app - #10

Merged
Harry-kp merged 1 commit into
mainfrom
fix/pre-release-hardening
Aug 29, 2026
Merged

Harry-kp merged 1 commit into
mainfrom
fix/pre-release-hardening

Conversation

@Harry-kp

Copy link
Copy Markdown
Owner

Everything to date was verified inside the engine's own dummy app, where the gem loads from source. So I did what an adopter does — rails new, add the gem, run the generator, db:migrate, and run the README quickstart verbatim.

The good news: it works. Routed on create, both layers, after_approved firing through the outbox:

routed:        true
pending on:    Manager sign-off -> Maria
after manager: pending, pending CFO sign-off
after cfo:     approved
invoice state: "paid"   <- host callback via outbox

That path is now known-good rather than assumed. Five things it surfaced:

The outbox had no retention story

It is a queue, not a ledger — one row per activation, decision and outcome, and a relayed row has no reader — but nothing ever swept it. On a busy app the table grows without bound.

OutboxEvent.purge! removes relayed events past a window (30 days by default), keeps dead letters whatever their age (an event that exhausted its retries is evidence of a broken callback, not litter), and never touches the audit trail.

:unprocessable_entity is deprecated

Rack has deprecated it and will remove it. The replacement symbol doesn't exist on Rails 7.1, so the admin renders 422 — the same on every version we support.

shiny_json_logic was pinned too loosely

~> 0.3 allows 0.4. It is pre-1.0, where a minor release may break, and it evaluates every routing rule — so a routine bundle update in an adopter's app could change what matches. Pinned to ~> 0.3.6.

Ruby 3.1 was claimed and never tested

The same claim-without-evidence gap the Rails matrix just closed, and 3.1 is past end of life. The floor is 3.2, which CI proves.

PostgreSQL had no stated version

The tables key on gen_random_uuid(), which is core Postgres only from 13. Before that it needs pgcrypto and the migration just fails. Documented as 13+.


Also: .gitignore covered *.log but not rotated logs, so a 105MB test.log.0 was sitting untracked-but-addable. GitHub's 100MB limit caught it on push; now ignored properly.

339 runs, 1070 assertions, 0 failures. Rubocop clean, gem builds, stable across seven seeds.

🤖 Generated with Claude Code

Everything until now was verified inside the engine's own dummy app, where
the gem is loaded from source. So I did what an adopter does: `rails new`, add
the gem, run the generator, migrate, and run the README quickstart verbatim.
It works — routed on create, both layers, `after_approved` firing through the
outbox. That path is now known-good rather than assumed.

Five things it surfaced:

The outbox had no retention story. It is a queue, not a ledger — one row per
activation, decision and outcome, and a relayed row has no reader — but
nothing ever swept it, so the table grew without bound. `OutboxEvent.purge!`
removes relayed events past a window, keeps dead letters whatever their age
(an exhausted event is evidence, not litter), and never touches the audit
trail.

`:unprocessable_entity` is deprecated in Rack and will be removed. The
replacement symbol does not exist on Rails 7.1, so the admin renders `422`,
which is the same on every version we support.

`shiny_json_logic` was pinned `~> 0.3`, which allows 0.4. It is pre-1.0, where
a minor may break, and it evaluates every routing rule — so a routine
`bundle update` in an adopter's app could change what matches. Pinned to the
patch series.

Ruby 3.1 was claimed and never tested, the same gap the Rails matrix just
closed, and it is past end of life. The floor is 3.2, which CI proves.

PostgreSQL had no stated version. The tables key on `gen_random_uuid()`,
which is core Postgres only from 13; before that it needs pgcrypto and the
migration simply fails. Documented as 13+.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Harry-kp
Harry-kp merged commit dcccd7e into main Aug 29, 2026
5 checks passed
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