PCO Plan 1.6.0: the message document is matched by the plan's own name #15

Merged
michael merged 1 commits from claude/pco-message-match into main 2026-09-22 16:56:52 -04:00
Owner

Why

Reports from both campuses: the PCO current item stops following ProPresenter while Now / Next keeps up. The Sunday logs show where: PCO Plan placed the live document on a plan item by title alone, and a sermon's document is named after the sermon — Waters names them YYMMDD Series Title - Part # — never after its plan item ("Message", "Resi Message"). Nothing matched, so the last song stayed current through the whole message.

North Attleboro, 20 Sept 2026:

Service Last match before the sermon Next match Stuck for
7:30 No One Like The Lord, 7:45 Communion, 8:51 65 min
9:30 No One Like The Lord, 9:45 Communion, 10:53 68 min
11:30 Message, 11:51 (the bumper happened to match) Communion, 12:50 tracked

Apollo Beach tracked its sermon only because the item is the media document "Resi Message" in both systems. Both booths' feeds were healthy throughout (live.available: true), which is why Now / Next looked fine.

What

The message rule (matching.js): a live document that reads like the plan itself — its date code, series title and part — is the plan's message and lands on the plan's message item: an item titled Message, Sermon, Teaching or Homily (a bare "Message" first), else the first item under a header so titled. Rules of the rule:

  • a date code naming another day is a firm no — last week's 260920 … - Part 5 stays unplaced;
  • dated with the plan's day, the rest need only resemble the series or the title (260927 Part 6 is enough);
  • undated, the name must read like series + title together and carry the title, so a series bumper ("Where is Your Faith?") is not taken for the sermon;
  • it overrides a name hit that is anything short of identical — a song called "Faith" cannot catch 260927 Where is Your Faith? - Part 6 — but an item titled exactly like the document still wins.

Position, as a tie-break only. ProPresenter's Planning Center playlist mirrors the plan item for item, headers included, every item PCO-flagged (checked at both campuses). While it does, the live item's playlist position breaks a tie between equally good names (the same song twice). It never places a document on its own, and an item the operator adds in ProPresenter — a song TAG — breaks the mirror and switches the tie-break off, so shifted positions cannot mislead it.

The log finally says what happened, which it never did: every feed drop and reconnect (ProPresenter module feed unavailable — … / following the ProPresenter module feed), which item the message document will land on (message item: "Message" — …, once per plan), what placed each item and how (live item → Message (message document, dated: "260927 Where is Your Faith? - Part 6"), live item → What a God (name 1.00: "What a God - [ Full ]")), and a live document that is not in the plan. A matcher that throws is logged once instead of swallowed.

placeDocument() in matching.js now holds the whole decision; the server's matchItem() is a thin wrapper. pco-plan 1.6.0. README updated.

Not in this PR

At the pre-roll boundary (AB, 10:30) the module restarts the live item's clock at 0:00 and marks the still-running service ended. Seen in the same logs, raised separately, not changed here.

Verified

  • node modules/pco-plan/matching.test.js — 27 checks built from both campuses' real 27 Sept 2026 plans and ProPresenter playlists as read from the booths on 22 Sept: the sermon document lands on "Message" (NA) and "Resi Message" (AB); the bumper lands there by name; last week's document, a series bumper, a dated "Announcements" and songs do not; the Faith trap; exact-title precedence; the mirror check against an added TAG item; tie-breaks by "ahead" and by position.
  • service-timing.test.js and tools/layout-roundtrip.test.js still pass; server.js and the module parse.
  • Scratch ProdDash on :24680 with tools/pco-mock.js and pp-mock.js: message item: "Sermon: Living Hope" logged once per plan, following the ProPresenter module feed after the boot-time loopback refusal, live item → This Is The Day (name 1.00: "This Is The Day - [ Full ]"), state matched: true, the Timers "Current item" running on it.

🤖 Generated with Claude Code

## Why Reports from both campuses: the PCO current item stops following ProPresenter while Now / Next keeps up. The Sunday logs show where: PCO Plan placed the live document on a plan item **by title alone**, and a sermon's document is named after the sermon — Waters names them `YYMMDD Series Title - Part #` — never after its plan item ("Message", "Resi Message"). Nothing matched, so the last song stayed current through the whole message. North Attleboro, 20 Sept 2026: | Service | Last match before the sermon | Next match | Stuck for | |---|---|---|---| | 7:30 | No One Like The Lord, 7:45 | Communion, 8:51 | 65 min | | 9:30 | No One Like The Lord, 9:45 | Communion, 10:53 | 68 min | | 11:30 | Message, 11:51 (the bumper happened to match) | Communion, 12:50 | tracked | Apollo Beach tracked its sermon only because the item is the media document "Resi Message" in both systems. Both booths' feeds were healthy throughout (`live.available: true`), which is why Now / Next looked fine. ## What **The message rule** (`matching.js`): a live document that reads like the plan itself — its date code, series title and part — is the plan's message and lands on the plan's **message item**: an item titled Message, Sermon, Teaching or Homily (a bare "Message" first), else the first item under a header so titled. Rules of the rule: - a date code naming **another day is a firm no** — last week's `260920 … - Part 5` stays unplaced; - dated with the plan's day, the rest need only resemble the series or the title (`260927 Part 6` is enough); - undated, the name must read like series + title together and carry the title, so a series bumper ("Where is Your Faith?") is not taken for the sermon; - it overrides a name hit that is anything short of identical — a song called "Faith" cannot catch `260927 Where is Your Faith? - Part 6` — but an item titled exactly like the document still wins. **Position, as a tie-break only.** ProPresenter's Planning Center playlist mirrors the plan item for item, headers included, every item PCO-flagged (checked at both campuses). While it does, the live item's playlist position breaks a tie between equally good names (the same song twice). It never places a document on its own, and an item the operator adds in ProPresenter — a song TAG — breaks the mirror and switches the tie-break off, so shifted positions cannot mislead it. **The log finally says what happened**, which it never did: every feed drop and reconnect (`ProPresenter module feed unavailable — …` / `following the ProPresenter module feed`), which item the message document will land on (`message item: "Message" — …`, once per plan), what placed each item and how (`live item → Message (message document, dated: "260927 Where is Your Faith? - Part 6")`, `live item → What a God (name 1.00: "What a God - [ Full ]")`), and a live document that is not in the plan. A matcher that throws is logged once instead of swallowed. `placeDocument()` in `matching.js` now holds the whole decision; the server's `matchItem()` is a thin wrapper. pco-plan **1.6.0**. README updated. ## Not in this PR At the pre-roll boundary (AB, 10:30) the module restarts the live item's clock at 0:00 and marks the still-running service ended. Seen in the same logs, raised separately, not changed here. ## Verified - `node modules/pco-plan/matching.test.js` — 27 checks built from both campuses' real 27 Sept 2026 plans and ProPresenter playlists as read from the booths on 22 Sept: the sermon document lands on "Message" (NA) and "Resi Message" (AB); the bumper lands there by name; last week's document, a series bumper, a dated "Announcements" and songs do not; the Faith trap; exact-title precedence; the mirror check against an added TAG item; tie-breaks by "ahead" and by position. - `service-timing.test.js` and `tools/layout-roundtrip.test.js` still pass; `server.js` and the module parse. - Scratch ProdDash on :24680 with `tools/pco-mock.js` and `pp-mock.js`: `message item: "Sermon: Living Hope"` logged once per plan, `following the ProPresenter module feed` after the boot-time loopback refusal, `live item → This Is The Day (name 1.00: "This Is The Day - [ Full ]")`, state `matched: true`, the Timers "Current item" running on it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
michael added 1 commit 2026-09-22 13:07:34 -04:00
The current item followed the live ProPresenter document by title alone,
and a sermon's document is named after the sermon — Waters names them
"YYMMDD Series Title - Part #" — never after its plan item. So the last
song stayed current through the whole message: North Attleboro on 20 Sept
spent 65 minutes on one song in two of its three services.

A live document that reads like the plan itself — its date code, series
title and part — now lands on the plan's message item: an item titled
Message, Sermon or Teaching, else the first item under such a header. A
date code naming another day is a firm no, so last week's sermon stays
unplaced. Position in the ProPresenter playlist breaks a tie between
equal names, only while the playlist mirrors the plan item for item, and
never places a document on its own.

The log now says what it never said: every feed drop and reconnect, which
item the message document will land on, what placed each item and how,
and a live document that is not in the plan.

matching.test.js: 27 checks built from both campuses' real 27 Sept plans
and ProPresenter playlists.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
michael merged commit f4d50f5e95 into main 2026-09-22 16:56:52 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: michael/ProdDash#15