docs(engagement): Phase 11b — the seed API, the in-universe voice, the governor's letter #196
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/engagement-phase-11b"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The design of record for Phase 11b. Pairs with website#178 (the seed API) and Module-uo#23 (the bodies).
Four decisions settled by the org lead before any 11b code, plus
MODULE_API1.9.0 and what building it found.The four decisions
api.registerEngagementSeeds({ templates, ruleGroups });MODULE_API_VERSION→ 1.9.0uo.governor.appointed— a 25th trigger,owner-audienced, beside the existing broadcastDecision 7 is the one 11a could not have discovered, because 11a seeded nothing. The plan's own sentence — "24 rules, all
enabled = 0; bespoke template bodies" — described work with no mechanism to land in. Reachingengagement_templatesthrough thectx.querya module already holds was considered and rejected: it would re-implementseedOne'scustomizedskip, itsseed_versioncomparison and its block validation outside the file that owns them.Decision 8 is also why the bodies had to be the module's. "A letter from Lord Blackthorn" is Britannian canon and §5.2's rule is that core stays ignorant of every word of a module's domain.
check:moduleswould not have caught it — it reads identifiers, imports and route literals, never prose, and says so in its own header — which is precisely the argument for taking the boundary seriously here rather than leaning on the checker.Decision 10 corrects a fact the plan had wrong by omission. §8.6 records that
uo.points.rank_changedcannot address a person, and the same reasoning was silently assumed to cover the governor.city.update'sgovernoris written byBridgeJson.Actor(), which emitsserial,name,acctandwebId— the new governor is addressable today, no protocol change. Widening the existing trigger to two audiences was refused: one trigger means one rule means one template, and the town's bulletin and the governor's letter are not the same text.What building it found
Recorded in a new "What building it found" block under Phase 11b, because four of these are cheap to get wrong from memory:
notify.event, wrong for a letter. The two fragment shapes (a label carries a sentence's spine; a trailing fragment leads with its own space) and why the labels stayrequired: falseeven though that leaves nothing at runtime to notice a mapper that forgot one.uo.champ.boss_upuses the character that separates them.Files
website/ENGAGEMENT.md— the decision block, the amended 11b bullet (25 rules), the findings, and four additions to the acceptance list.website/MODULE_API.md— §1.1 1.9.0 with the full shape and the three prohibitions;registerEngagementSeedsin §2.4.modules/uo/API.md— §5.7 the shipped bodies, §5.8 the presentational fragments; the trigger count and theownerceiling row updated for the 25th.AI-assisted: written with Claude Code.
🤖 Generated with Claude Code
Four decisions settled by the org lead before any 11b code, plus MODULE_API 1.9.0 and what building it found. DECISION 7 is the one 11a could not have discovered, because 11a seeded nothing. The plan's own sentence — "24 rules, all enabled = 0; bespoke template bodies" — described work with NO MECHANISM to land in: templateSeeds.js and coreRules.js are core files with core arrays, and registries.js has no registerTemplates. Adds api.registerEngagementSeeds({ templates, ruleGroups }). Templates re-ensure every boot; rule groups are one-shot per named group, which is 11a's seed-key finding stated as an API rather than as a warning. DECISION 8: the game-powered families read in-universe, with a per-family sender rather than one voice. The crown writes about the crown's business and nothing else. This is also why the bodies had to be the module's: §5.2 says core stays ignorant of a module's domain, and check:modules reads identifiers, never prose — so the boundary is honoured deliberately here rather than leaned on. DECISION 9: nine bodies stay plain. A failed-login notice written as a letter is indistinguishable in register from the phishing mail it warns about. DECISION 10 corrects a fact the plan had wrong by omission. §8.6 records that uo.points.rank_changed cannot address a person, and the same reasoning was silently assumed to cover the governor. city.update's `governor` is written by BridgeJson.Actor(), which emits acct and webId — the new governor is addressable today, no protocol change. uo.governor.appointed is the 25th trigger. Also records what building it found: the no-conditionals/empty-string collision that the presentational fragments exist for, the render sweep that found three defects no check could see (an optional in a subject line, multi-optional detail lines, a trailing fragment used as a leading one), the trigger-bound template that could not reference its own unsubscribe link, and the trigger-id/template-key grammar mismatch. docs/modules/uo/API.md gains §5.7 and §5.8. Co-Authored-By: Claude <noreply@anthropic.com>