Skip to content

Policy fromNowOn: the head recorded as read, nothing as handled - #180

Merged
vanrogu merged 4 commits into
developfrom
claude/event-driven-automation-policy-wabyjz
Oct 4, 2026
Merged

vanrogu merged 4 commits into
developfrom
claude/event-driven-automation-policy-wabyjz

Conversation

@vanrogu

@vanrogu vanrogu commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Problem

A policy registered fromNowOn() places its first bookmark at the head of the domain stream when it first leads. That bookmark named the head as the last handled event, with no read position. On the dashboard this showed as lastProcessed set and lastSeen empty (seen on the modeler's RevokeAgentKeysOfRevokedAccountPolicy).

That is wrong in two ways:

  • The handled reference named an event the policy never processed. An operator reads it as the last policy-matching event the policy actually handled.
  • The read position stayed empty until something new was appended to the stream.

Change

  • The first bookmark is a read position only. A fromNowOn() policy deployed for the first time records the head with placeReadPosition(head): read up to here, nothing handled.
  • It resumes after that read position while nothing has been handled. This uses the eventstore projector's new resumeAfterReadPosition(). Normally, a bookmark with no handled event resumes from the beginning, which would replay the history the policy was deployed to skip. The handled reference stays empty until the policy really handles an event.
  • The framework now builds on eventstore 0.11.4, the release carrying resumeAfterReadPosition().
  • CLAUDE.md is updated to match. Two earlier commits on this branch are superseded: one recorded the head as both positions, the other worked around the projector in the framework (ReadPositionStartSource, now removed).

Tests

PolicyModuleTest:

  • The bookmark records the head as read and nothing as handled.
  • Reading past an unrelated event moves only the read position, and the handled reference is the first event the policy really handled.
  • A restart before anything was handled reacts to what happened while the policy was down, and not to the history before it was deployed.

The full framework build passes on the in-memory and in-memory-fs backends, against eventstore 0.11.4 resolved from Maven Central. PostgreSQL was not run, because Docker is not available here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CbFecBFD17EgzYnoszEgfX

A policy starting from now on placed its first bookmark at the head with the
handled reference alone. The projector takes a missing read position to be
the handled reference, so an idle run reading to that same head saw nothing
moved and never wrote one: the bookmark showed an event processed but none
read until something was appended to the stream. The head is now recorded as
both positions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CbFecBFD17EgzYnoszEgfX
A policy starting from now on now records the head of the stream as its read
position only, so its bookmark's handled reference is only ever an event the
policy really handled - what an operator reads it as. While nothing has been
handled, its processor resumes after that read position (the eventstore
resumes such a bookmark from the beginning, which would replay the history
the policy was deployed to skip), reading through ReadPositionStartSource,
which keeps the projector from recording that start point as handled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CbFecBFD17EgzYnoszEgfX
@vanrogu vanrogu changed the title Policy fromNowOn: bookmark the head as read, not only as handled Policy fromNowOn: the head recorded as read, nothing as handled Oct 4, 2026
…re projector

The framework now builds on eventstore 0.12.0-SNAPSHOT and its
Projector.Builder.resumeAfterReadPosition(), which replaces
ReadPositionStartSource: a fromNowOn policy records the head as read only,
and while it has handled nothing its projector resumes after that read
position, the handled reference staying empty until it handles an event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CbFecBFD17EgzYnoszEgfX
…terReadPosition

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CbFecBFD17EgzYnoszEgfX
@vanrogu
vanrogu merged commit c34286e into develop Oct 4, 2026
1 check passed
@vanrogu
vanrogu deleted the claude/event-driven-automation-policy-wabyjz branch October 4, 2026 15:28
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.

2 participants