Skip to content

Say that ungenerated State Machine events are stubs - #167

Merged
raghubetina merged 1 commit into
mainfrom
transition-stubs
Oct 12, 2026
Merged

raghubetina merged 1 commit into
mainfrom
transition-stubs

Conversation

@raghubetina

Copy link
Copy Markdown
Contributor

Why

The service's next Compiler (service main e2318b81) keeps a required, unconditional State Machine alone on its Entity in AASM when an event has effects it cannot generate: two effects, or one that sets a Field on another Entity, a required, immutable, derived, or non-datetime Field, or a Value other than the current time or nil. Before, one such event made the whole machine storage only, with no events, AASM initialization, or direct-assignment guard, even for the events it could generate. Now the aasm block lists the generated events, and each other event gets <m>!, <m>, and may_<m>? under the names AASM would give it, each raising NotImplementedError until it is written. The README's Behavior to write lists each one, the event's State Machine examples fail through the stub, and seeds and spec setup never fire one. The generated AGENTS.md now says:

A stubbed scope or event raises NotImplementedError, a stubbed Policy rule returns false, and a deletion outcome First Draft left out fails its spec with RecordNotDestroyed.

Plugin 0.8.13 named only a stubbed scope as raising, and its Plan reference said cross-Entity, multi-effect, and broader effect shapes kept only storage.

  • The failing-spec rule. "Run the generated tests" and continuation say a stubbed scope or event raises, as the generated AGENTS.md does. The preview gate is unchanged: a stubbed event's examples fail, so the run passes only once it is written, and no generated page fires an event.
  • Plan reference. The State Machine paragraph now says which events are generated and which become stubs, that the machine keeps its AASM states, initialization, validation, and direct-assignment guard even when every event is a stub, that Behavior to write lists each stub and its examples fail, that a development record or spec setup that needs one is left out, and that the GapSet keeps the event's effects_not_generated record with a consequence naming the stubs. Optional, conditional, multiple-per-Entity, guarded, and colliding machines still keep only storage.
  • Evals. No case quotes the AGENTS.md bullet or describes a storage-only State Machine, so none changed.

Verified on service e2318b81. script/compiler_transition_stubs_runtime_smoke passed. Its Ticket status machine kept aasm :status with no_direct_assignment and only event :assign, and stubs for resolve (sets desk.last_resolved_at), postpone (a required Field), reopen (a date Field), and archive (two effects). The README's Behavior to write listed all four with the wording this PR quotes, the generated AGENTS.md carried the new sentence, the seed left out the resolved Ticket, and Test coverage to complete listed the Policy and request examples whose setup needs resolve. The generated suite ran 96 examples with 16 failures, each an expected failure through one of the four stubs' State Machine examples.

Order. Ship with the service release that deploys e2318b81 or later. Until then no README lists an event under Behavior to write, so the rule holds on both sides of the deploy.

Release. Plugin 0.8.13 is published and selected, so this moves to 0.8.14 with a CHANGELOG entry. Packing main (84bb47f) with CLI 92f27714 (v0.8.2) on Node 24.18.0 reproduced its declared digest 1b57b73a…; this branch packs to 9a00700f…, twice. This PR does not tag, publish, or change the catalog selection.

Checks. npm ci --ignore-scripts and npm audit (0 vulnerabilities) pass. sh script/check passes 85/85 with the stub CLI and with CLI 92f27714, and node script/check-cli-contract.mjs passes.

Docs: updated skills/create-full-stack-app/references/diagnostics-and-recovery.md (Run the generated tests, continuation), references/foundation-plan-023.md (the State Machine paragraph), and the CHANGELOG.md 0.8.14 entry.

Review: Codex (codex-review 0.8.0, max effort), session 6043bc21-89d0-459d-bfb6-4d27c0bc06b0, approve.

The service's next Compiler keeps a required, unconditional State
Machine alone on its Entity in AASM when an event has effects it
cannot generate. Before, one such event made the whole machine
storage only, with no events, AASM initialization, or assignment
guard, even for the events it could generate. Now the aasm block lists
the generated events, and each other event is emitted as its bang
form, plain form, and may_ predicate, under the names AASM would give
it, each raising NotImplementedError until it is written. The README's
Behavior to write lists each one, its State Machine examples fail
through the stub, and seeds and spec setup never fire one. The
generated AGENTS.md now says a stubbed scope or event raises.

The Skill's rule for failing specs named only a stubbed scope, so the
test run and continuation now say a stubbed scope or event raises, as
the app's AGENTS.md does. The Plan reference said cross-Entity,
multi-effect, and broader effect shapes kept only storage; it now
says which events are generated, describes the stub, the left-out
seed record, and the GapSet record, and keeps storage only for
optional, conditional, multiple-per-Entity, guarded, and colliding
machines.

Until the service deploys that Compiler, no README lists an event
under Behavior to write, so the rule holds on both sides of the
deploy.

Plugin 0.8.13 is published and selected, so this moves to 0.8.14
with a CHANGELOG entry. Packing main (84bb47f) with CLI 92f27714 on
Node 24.18.0 reproduced its digest before the repack. npm ci
--ignore-scripts, npm audit, sh script/check with the stub CLI and
with that CLI, and check-cli-contract pass.
@raghubetina
raghubetina merged commit c7621c8 into main Oct 12, 2026
3 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