Two defects, and the second is why the first survived a whole phase. The manifest is stale. `engagement-triggers.json` embeds `moduleApiVersion` deliberately -- "a stale manifest needs to know which API's rules produced it" -- and Phase 7 (website#189) bumped MODULE_API_VERSION to 1.10.0 without regenerating it. The committed file has said 1.9.0 ever since. One line, and regenerating is the whole fix. The check could not be believed. Both the test and the `--check` CI gate compared bytes, and this repo is developed on Windows under core.autocrlf=true, so git checks the committed LF blob out as CRLF and the comparison then calls an unchanged manifest stale. That failure fires on every Windows checkout, says "a trigger declaration changed", and is "fixed" by regenerating a file whose content was already correct. So the one check that exists to be believed had been failing for a reason everyone had learned to write off as environmental -- including me, twice: the Phase 7 PR recorded it as a pre-existing CRLF failure, and the Phase 8 PR repeated the claim. It was neither pre-existing nor CRLF. A check that cries wolf is a check nobody reads, and the genuine staleness underneath it went unnoticed for exactly that reason. Line endings are now normalised on both sides, which is the convention routeManifest.js and routeManifest.test.js already use one file along -- that pair had clearly hit this and been fixed; the engagement pair never was. What is being asserted is that the committed manifest describes the same declarations, and a line ending is not a declaration. Policing the encoding is .gitattributes' job, not this check's. Verify - The check is still LIVE, proved by breaking it deliberately: with the content changed the gate exits 1; with only the line endings changed it exits 0. That is the whole point of the fix, so it is not taken on trust. - `npm test` under the TAP reporter: 1950 tests, 1877 pass, 0 fail. That is pristine `edge`'s 1950/1876 plus the one test this repairs. A harness note, disclosed rather than buried The default (spec) reporter intermittently reports a FILE-level failure with all of that file's subtests passing, no assertion, and no diagnostic beyond 'test failed'. It named a different unrelated file on each of four runs (requireInternalKey, routeManifest, eventAuthorize, totp) and the TAP reporter shows zero failures over the same suite. It appears to be a reporter artifact under concurrency rather than a failing test, but it correlates with this branch (4/4) against pristine edge (0/2) on the same machine state, which I could not explain and am not claiming to have. Worth its own look; it does not indicate a product defect and no assertion fails. Co-Authored-By: Claude <noreply@anthropic.com>
212 lines
6.5 KiB
JSON
212 lines
6.5 KiB
JSON
{
|
|
"_comment": "Generated event-trigger inventory - the authoritative freeze of CORE's engagement contract (docs/website/ENGAGEMENT.md 4.3). Regenerate with `npm run engagement:manifest` in website/server. A renamed variable, a changed type or a widened ceiling breaks stored templates and rules, so the diff here is the review signal. A module ships its own copy in its bundle; this file never contains one.",
|
|
"moduleApiVersion": "1.10.0",
|
|
"triggers": [
|
|
{
|
|
"id": "news.post",
|
|
"owner": "core",
|
|
"label": "News post published",
|
|
"description": "A news / Five-on-Friday / newsletter post was published.",
|
|
"kind": "event",
|
|
"subjectKey": null,
|
|
"audience": "subscribers",
|
|
"ceiling": "authenticated",
|
|
"version": 1,
|
|
"variables": [
|
|
{
|
|
"name": "title",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Five on Friday — the Yew invasion",
|
|
"description": "The post title."
|
|
},
|
|
{
|
|
"name": "excerpt",
|
|
"type": "string",
|
|
"required": false,
|
|
"example": "Four new champion spawns, and the fate of the Yew moongate…",
|
|
"description": "A plain-text summary, already stripped of markup."
|
|
},
|
|
{
|
|
"name": "category",
|
|
"type": "string",
|
|
"required": false,
|
|
"example": "Five on Friday",
|
|
"description": "The post category, when it has one."
|
|
},
|
|
{
|
|
"name": "postUrl",
|
|
"type": "url",
|
|
"required": true,
|
|
"example": "/site/news",
|
|
"description": "Site-relative path to the post. The news list today — the site has no per-post route."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "team.announcement",
|
|
"owner": "core",
|
|
"label": "Team — announcement",
|
|
"description": "A leader posted an announcement in a Team.",
|
|
"kind": "event",
|
|
"subjectKey": "teamName",
|
|
"audience": "members",
|
|
"ceiling": "members",
|
|
"version": 1,
|
|
"variables": [
|
|
{
|
|
"name": "teamName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "The Silver Anvil",
|
|
"description": "The Team the event is about. Also the cooldown subject."
|
|
},
|
|
{
|
|
"name": "authorName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Marisol",
|
|
"description": "Display name of the leader who posted."
|
|
},
|
|
{
|
|
"name": "title",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Siege practice moved to Sunday",
|
|
"description": "The announcement title."
|
|
},
|
|
{
|
|
"name": "excerpt",
|
|
"type": "string",
|
|
"required": false,
|
|
"example": "We are moving practice to Sunday 8pm…",
|
|
"description": "Plain-text excerpt of the announcement body."
|
|
},
|
|
{
|
|
"name": "postUrl",
|
|
"type": "url",
|
|
"required": false,
|
|
"example": "/guilds/the-silver-anvil/forum/419",
|
|
"description": "Site-relative path to the announcement."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "team.forum.post",
|
|
"owner": "core",
|
|
"label": "Team — new forum post",
|
|
"description": "A new thread or reply in a Team forum.",
|
|
"kind": "event",
|
|
"subjectKey": "teamName",
|
|
"audience": "members",
|
|
"ceiling": "members",
|
|
"version": 1,
|
|
"variables": [
|
|
{
|
|
"name": "teamName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "The Silver Anvil",
|
|
"description": "The Team the event is about. Also the cooldown subject."
|
|
},
|
|
{
|
|
"name": "authorName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Darrow",
|
|
"description": "Display name of the poster."
|
|
},
|
|
{
|
|
"name": "threadTitle",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Tuesday champ rotation",
|
|
"description": "Title of the thread the post belongs to."
|
|
},
|
|
{
|
|
"name": "excerpt",
|
|
"type": "string",
|
|
"required": false,
|
|
"example": "Moving the Tuesday run an hour later…",
|
|
"description": "Plain-text excerpt of the post body, already stripped of markup."
|
|
},
|
|
{
|
|
"name": "postUrl",
|
|
"type": "url",
|
|
"required": false,
|
|
"example": "/guilds/the-silver-anvil/forum/412",
|
|
"description": "Site-relative path to the post."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "team.leadership.changed",
|
|
"owner": "core",
|
|
"label": "Team — leadership change",
|
|
"description": "Leadership changed in a Team.",
|
|
"kind": "event",
|
|
"subjectKey": "teamName",
|
|
"audience": "members",
|
|
"ceiling": "members",
|
|
"version": 1,
|
|
"variables": [
|
|
{
|
|
"name": "teamName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "The Silver Anvil",
|
|
"description": "The Team the event is about. Also the cooldown subject."
|
|
},
|
|
{
|
|
"name": "leaderName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Marisol",
|
|
"description": "Display name of the new leader."
|
|
},
|
|
{
|
|
"name": "teamUrl",
|
|
"type": "url",
|
|
"required": false,
|
|
"example": "/guilds/the-silver-anvil",
|
|
"description": "Site-relative path to the Team page."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "team.member.joined",
|
|
"owner": "core",
|
|
"label": "Team — new member",
|
|
"description": "Someone joined a Team.",
|
|
"kind": "event",
|
|
"subjectKey": "teamName",
|
|
"audience": "members",
|
|
"ceiling": "members",
|
|
"version": 1,
|
|
"variables": [
|
|
{
|
|
"name": "teamName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "The Silver Anvil",
|
|
"description": "The Team the event is about. Also the cooldown subject."
|
|
},
|
|
{
|
|
"name": "memberName",
|
|
"type": "string",
|
|
"required": true,
|
|
"example": "Darrow",
|
|
"description": "Display name of the member who joined."
|
|
},
|
|
{
|
|
"name": "teamUrl",
|
|
"type": "url",
|
|
"required": false,
|
|
"example": "/guilds/the-silver-anvil",
|
|
"description": "Site-relative path to the Team page. Absent when no module supplies a pageUrlTemplate."
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|