Skip to content

Says what the create and step hooks reach - #135

Merged
johnnyt merged 1 commit into
mainfrom
sr-2cwo-hooks-tenancy-reach
Sep 30, 2026
Merged

johnnyt merged 1 commit into
mainfrom
sr-2cwo-hooks-tenancy-reach

Conversation

@johnnyt

@johnnyt johnnyt commented Sep 30, 2026

Copy link
Copy Markdown
Member

Refs: sr-2cwo

What

A host that wraps every step in a tenancy context of its own asked whether the :on_create and :on_step hooks are enough. The finding, written on the bead before this change: they cover the create and the step, and not the rest of the delivery. README.md's "Wrapping the create and step calls" now says so, in three paragraphs after the option table:

  • what a context set in the hook's body covers: the create or the step and what they write through the configuration's repo;
  • that the delivery's transaction and savepoint are open before either hook is called (StatifierRouter.Delivery.deliver/4), and what runs outside the hook's body: the dedupe claim (StatifierRouter.Dedupe.claim/4), the address row's read and insert with the :execution_id minter, an existing execution's status read (StatifierPersistence.Storage.fetch_execution/2), the :resolver and :chart_resolver calls, the :on_complete route, the terminal_seen_at update and the ledger row; plus the bindings resolver call and the key_refused row that StatifierRouter.route/3 makes with no delivery transaction open;
  • what that means for a process context, a transaction-local database setting and a session-level setting;
  • the two seams that reach further (the :delivery option; a direct caller's own transaction around route/3 or StatifierRouter.Webhook.handle/3, which the delivery nests into) and where neither reaches: StatifierRouter.Broadway, the key_refused row, and a send to an execution target (StatifierRouter.Delivery.deliver_event/4);
  • that no one seam wraps a whole delivery on every door today, stated as an open gap left for a later decision (filed separately in the tracker; not fixed here).

Documentation text only; no function changes. No changelog fragment: changelog.d/README.md excludes documentation.

Gate

README.md is a gated path, so the full mix quality ran on this exact tree (the staged tree was byte-identical to the tree the gate ran green on; the commit is a bare commit citing this run). Its output, quoted whole from the stage list:

Running quality checks...

✓ Format: No changes needed (306ms)
✓ Compile: dev + test compiled (warnings as errors) (31.2s)

Running analysis stages in parallel...

○ Doctor: skipped (:doctor not installed)
○ Gettext: skipped (:gettext not installed)
○ Sobelow: skipped (:sobelow not installed)
✓ Isolated tests: Passed (1.9s)
✓ Doc links: 1 link checked (8ms)
✓ Dependencies: No unused dependencies (430ms)
✓ Credo: No issues (1.4s)
✓ Docs: No warnings (1.4s)
✓ Tests: 396 of 396 passed, 98.4% coverage (3.1s)
⋯ Dialyzer: building PLT (this is a one-time cost)
✓ Dialyzer: No warnings (PLT built this run) (53.7s)

✓ All quality checks passed!

Review

In-turn review (documentation, gate tier). I re-read the diff against the bead and its notes and checked each claim against the code on main by anchor: the transaction opens in settled/5 and the savepoint in guarded/5 before claimed/4 calls Dedupe.claim/4; the hooks are called only from persistence_create/4 and persistence_step/5; the address row is read by lookup/4 and inserted by insert_or_existing/4, which calls mint_execution_id/4; existing/5 reads the status through Storage.fetch_execution/2; resolve/3 and chart/2 call the two resolvers; complete/3 delivers to the :on_complete route; stamp_terminal_seen/3 updates terminal_seen_at; record/6 writes the ledger row, all in StatifierRouter.Delivery. StatifierRouter.route/3 calls Config.bindings_for/2 and key_refused/5 writes its row outside any delivery transaction; the default delivery module is called as config.delivery.deliver/4; settled/5's comment and code nest into a caller's transaction; StatifierRouter.Broadway.handle_message/3 calls route/3 and partition/3 calls the bindings resolver; StatifierRouter.SendHandler delivers to an execution target through Delivery.deliver_event/4, never through the :delivery module.

Provenance

The probe was run on the bead before the docs change; the gap it found is tracked as a separate item for a later decision on one whole-delivery seam, so the README states it in words.

A host that wraps every step in a tenancy context of its own asked
whether :on_create and :on_step are enough. They are for the create and
the step, and not for the rest of the delivery. "Wrapping the create
and step calls" now says so: a context set in the hook's body covers
the create or the step and what they write through the configuration's
repo; the delivery's transaction and savepoint are already open before
either hook is called (Delivery.deliver/4); and the dedupe claim, the
address row's read and insert with the id minter, an existing
execution's status read, the resolver calls, the on-complete route, the
terminal_seen_at update and the ledger row run outside it. route/3 also
asks the bindings resolver and writes a key_refused row with no
delivery transaction open.

It names the two seams that reach further (the :delivery option, and a
direct caller's own transaction the delivery nests into) and where
neither reaches: the Broadway pipeline, the key_refused row, and a send
to an execution target (Delivery.deliver_event/4). The missing
whole-delivery seam is stated as an open gap, left for a later
decision.

Documentation text only; no function changes. README.md is a gated
path, so the full gate (mix quality) ran green on this exact tree. No
changelog fragment: changelog.d/README.md excludes documentation.

Refs: sr-2cwo
@johnnyt
johnnyt merged commit ce83e77 into main Sep 30, 2026
1 check passed
@johnnyt
johnnyt deleted the sr-2cwo-hooks-tenancy-reach branch September 30, 2026 06:18
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