Compare commits
1 Commits
2590d4cc58
...
docs/engag
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fd5d065b7 |
@@ -2764,7 +2764,10 @@ declared trigger that **nothing emits through the engine** — `coreTriggers.js`
|
||||
admin publish path still fires a raw `pushDispatch.publish` beside the engine rather than through it.
|
||||
The consequence for this phase: on a real deployment the only in-app items a rule can produce today
|
||||
come from the four Team triggers. Wiring the news emitter is a one-line `ctx.events.emit`-shaped change
|
||||
that belongs with whoever owns that decision, not smuggled into the channel's own phase.
|
||||
that belongs with whoever owns that decision, not smuggled into the channel's own phase. **Written up as
|
||||
§7.1 Q9**, which sets out the three other things a publish already fires (an announce leg, a module's
|
||||
post hook, the raw tickle), which of them the engine replaces and which it must not touch, and the
|
||||
continuity question that has to be answered before anyone writes the line. Recommended home: Phase 11.
|
||||
|
||||
**Still later phases':** the app's inbox screen and the tickle → pull → inbox path (Phase 8), and the
|
||||
suppression list, which this channel has no equivalent of — there is no address to suppress.
|
||||
@@ -2827,10 +2830,19 @@ starts early and lands independently.
|
||||
with Phase 6 if Phase 10 is still in flight — the trigger simply omits `nextStage`/`estimatedCollapse`
|
||||
until the v5 overlay is deployed, which the `required: false` declaration already permits.
|
||||
|
||||
**Also core's own `news.post` emitter, which this phase's title understates** (§7.1 Q9). `news.post` is
|
||||
declared with no caller, so a rule naming it can never fire; wiring it is one `ctx.events.emit`-shaped
|
||||
call in `announceIfNewlyPublished`, gated on the same job-id transition signal the push already uses.
|
||||
**The announce legs and the post hooks are untouched** — a module's town-crier leg is a delivery to a
|
||||
channel of the deployment and its news-gump hook is state mirroring, neither of which is a per-person
|
||||
notification. What the emit replaces is the raw `pushDispatch.publish` beside them, and Q9's continuity
|
||||
question has to be answered before it does.
|
||||
|
||||
**Acceptance:** the five-rung shard visibility walk still shows no leak; a house transitioning to
|
||||
`Greatly` on the live rig produces one email to the linked owner and nothing to anyone else; a second
|
||||
transition inside the cooldown produces nothing; a refresh back to `LikeNew` inside the delay window
|
||||
cancels the pending mail.
|
||||
cancels the pending mail; **a news post published on the rig reaches a rule, and the town-crier leg and
|
||||
every registered post hook still fire exactly as they did.**
|
||||
**Guardrails:** `check:modules` proves core gained no UO identifier across every phase to this point.
|
||||
|
||||
---
|
||||
@@ -2963,7 +2975,7 @@ day it ships.
|
||||
|
||||
## Part 7 — Open questions and forward-compat notes
|
||||
|
||||
### 7.1 Questions for the org lead — seven answered, one still open
|
||||
### 7.1 Questions for the org lead — seven answered, two still open
|
||||
|
||||
1. ✅ **ANSWERED — may unverified addresses receive engagement mail?** *"Emails need to be unique and
|
||||
verification blocking sending is an admin setting."* Combined with the opt-in answer, this settles
|
||||
@@ -3026,6 +3038,52 @@ day it ships.
|
||||
nine M12 phase PRs. Fix the trigger as Phase 8's first commit, or accept it deliberately?
|
||||
Recommendation: fix it. It is a two-line workflow change and the alternative is finding out about a
|
||||
Kotlin compile error during the cutover window.
|
||||
9. **Core's own `news.post` emitter — and the three other things a publish already fires.**
|
||||
`config/coreTriggers.js` declares core's five triggers and says in as many words that **nothing here
|
||||
emits yet**; Phase 6 migrated only the four `team.*` ones onto the engine. So `news.post` is a
|
||||
declared payload contract with **no caller**, and on a real deployment the only in-app or email items
|
||||
a rule can produce today come from Teams. Phase 7 found this and deliberately did not wire it, on the
|
||||
grounds that a channel's own phase is not the place to give another phase's trigger an emitter.
|
||||
|
||||
**The call itself is one line. The care is entirely in what it must not disturb.**
|
||||
`admin.controller.js`'s `announceIfNewlyPublished` already fans one publish four ways, and they are
|
||||
different in kind — three of them are *not* the engagement engine's business:
|
||||
|
||||
| What fires on a publish | Whose | What kind of thing it is | The engine's? |
|
||||
| --- | --- | --- | --- |
|
||||
| `announceJobs.enqueueIfNeeded` → `announce_job_legs` | core, with legs registered by modules — `module-uo` owns `towncrier` | a one-shot **delivery to a channel of the deployment**, with retry and classification | **No** |
|
||||
| `registries.dispatchPostHook('onSaved')` | modules, via `registerPostHook` (API 1.1.0) | idempotent **state mirroring** — it also runs on delete, and refreshes silently on an edit | **No** |
|
||||
| `pushDispatch.publish('news.post', { ref })` | core | a **per-person notification**, to whoever subscribed | **Yes — this is the one that should become an emit** |
|
||||
| *(missing)* `engagementEmit.emit('core', 'news.post', …)` | core | rules → email / in-app / push | **Yes** |
|
||||
|
||||
`registries.js` already states the first two apart and why they were not folded together ("a leg is a
|
||||
one-shot DELIVERY with retry and classification; a post hook maintains idempotent STATE, has to run on
|
||||
delete as well as save, and refreshes silently on an edit"). **Adding the engine makes a third
|
||||
distinction of the same kind, not a replacement for either.** A module's town-crier leg and a module's
|
||||
news gump must keep firing exactly as they do; what changes is only that the raw tickle stops being
|
||||
the one person-facing sink and becomes one channel of a rule.
|
||||
|
||||
**What a module gets out of this, stated so nobody widens it by accident.** A module already has two
|
||||
doors onto a news publish — the announce leg and the post hook — and it keeps both. What it does *not*
|
||||
get is the ability to fire `news.post` itself: the id's owner is core, `ctx.events.emit` binds the
|
||||
owner at the call and never reads it from the arguments, and §7.2's one namespace means an id has
|
||||
exactly one owner across both facets. A module that wants a person-facing notification of its own
|
||||
declares its own trigger through `registerEventTriggers`. That is the whole of "modules can use it".
|
||||
|
||||
**Three things to settle before anyone writes the line:**
|
||||
- **Continuity, and it is the same shape as G22 and Phase 6's decision 3.** Today publishing news
|
||||
tickles every `news.post` subscriber directly. If the emit *replaces* that call, push stops the
|
||||
moment this lands and stays stopped until an operator enables a rule — silently, because `enabled`
|
||||
defaults to `0`. Either core seeds a `news.post` rule (and then: enabled, against the standing
|
||||
default, or disabled with a banner as the Team rules got?), or the raw tickle stays beside the emit
|
||||
for one release and is removed once a rule is known to exist.
|
||||
- **The transition signal must be reused, not re-derived.** `enqueueIfNeeded` returning a truthy job
|
||||
id is the single "newly published news" test, and the push call already piggybacks on it
|
||||
deliberately so an edit or a re-publish does not re-fire. The emit must gate on the same value; a
|
||||
second reading of the transition is a second chance to disagree with the first.
|
||||
- **Which phase owns it.** Recommendation: **Phase 11**, which already ships "the first real rule" and
|
||||
is where a declared trigger first gets a caller. It is core work rather than `module-uo`'s, so that
|
||||
phase's title understates it — say so there rather than inventing a phase for one call site.
|
||||
|
||||
### 7.2 One namespace, or two?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user