Task: Give the events a subject of their own

Table of Contents

This page documents a task in the Stream the changes as they happen story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

(Describe what user-visible-or-internal change this task produces.)

2. Status

Field Value
State DONE
Parent story Stream the changes as they happen
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-11-01

3. Acceptance

4. Plan

(Implementation strategy. Written when work starts; key decisions are distilled into the parent story's * Decisions at close, but the plan itself stays — it is the historical record of what we did.)

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
Declarations the conformance checker reads 406 check_subject_conformance.py 013054611f
Codegen tests 64 pytest test_protocol_subject_grammar test_entity_events test_check_subject_conformance 013054611f
Core suite 196 assertions, 48 cases ores.http.core.tests 013054611f

6. Notes

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

8. PRs

PR Title
#4445 [codegen] Give the events a subject of their own
#4433 [codegen] Delete the twins no model writes

9. Review

Comment summary File Decision Notes
       

10. Plan

  • The generator moves, not the callers: entity_event_prefix states <component>.v1.events.<collection>, and the junction prefix with it, so every event header, protocol header and TypeScript twin follows from one rule.
  • The feed subscribes *.v1.events.> and reads five segments from the right. The old four-segment spelling is refused rather than tolerated, so a publisher left behind is named by the check instead of going quiet.
  • The checker learns the event grammar and refuses the old form. The specification, the messaging references and the codegen tests state it too.
  • Two subjects are written by hand and move with it: the scheduler's job-instance announcement and the shell's watch of it.

11. Result

An event is now <component>.v1.events.<collection>.<action>. The namespace is a token of its own, so *.v1.events.> hears the events of every component and nothing else: the feed no longer subscribes to every versioned request in the fleet and discards all but the events.

The generator states the rule once, and the catalogue is regenerated from it: 481 event headers before the merge, and every protocol header and committed twin with them. The feed parses five segments from the right and refuses the old spelling; the conformance checker accepts the new grammar and refuses the old form; the specification says five segments for an event. The BFF's eventSubject and its twelve assertions follow, and so do the scheduler's hand-written announcement and the shell's watch.

Verified: the conformance check reads 406 declarations with none new, 64 codegen tests pass, and the core and eventing suites pass. Not verified: the scheduler's integration cases, which need a broker this worktree does not have running, and the web suite beyond formatting. The deployment runs the old spelling until it is rebuilt.

Emacs 29.3 (Org mode 9.6.15)