You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tier rail 1/4: define the render-neutral v3 sections event and its transition policy #156
Part of #131 (remediation steps 1 and 7). Do this first; the other sub-issues build on the contract.
Difficulty Ladder currently emits presentation decisions (fillPercentage, glassSize) in difficulty_ladder.sections.v2. That forces every consumer (Section Map today) to inherit the glass metaphor and blocks alternative renderers. Replace it with a semantic payload.
Scope
Define the new event/schema (difficulty_ladder.sections.v3 or an explicitly versioned equivalent), per phrase/section:
stable id/index and time range
currentTier, topTier (tier where full detail is reached), maxTier
whether the entry is the current one
optional player context (must respect the multi-player contract in PLAYER_CONTEXT.md)
Decide and document the transition policy: keep emitting v2 for a bounded period, or version the new event so Section Map upgrades cannot break by load order (plugins load alphabetically).
Emit the v3 payload from screen.js's existing section-difficulty emit path; do not remove v2 here.
Document the payload and the transition policy in INTEGRATION.md.
Add contract tests for the v3 payload and for v2 transition behavior.
Acceptance criteria
The payload carries no presentation fields (no glassSize, no fillPercentage).
Missing phrase data produces no payload entry rather than a zero-tier value.
Split Screen / player-context instances stay isolated (payload is scoped per player context).
v2 consumers keep working unchanged during the transition.
Out of scope
Rendering (sub-issue 2), the setting rename (sub-issue 3), the Section Map consumer (sectionmap#14) and removing v2/glassSize (sub-issue 4).
@pullfrog please work on this issue. It is the first sub-issue of #131 and has no dependencies. Keep the PR scoped to this sub-issue only, follow the repo CLAUDE.md (bump plugin.json, update CHANGELOG.md, run node --test), and do not start the dependent sub-issues. Open a PR against main; do not merge it.
What shipped — difficulty_ladder.sections.v3 is now emitted additively from the existing calculateAndEmitSectionDifficulties() call, on its own event difficulty:sections-updated-v3, with v2 unchanged ahead of it and window._ddCapabilities.sectionsSchema advertising which schema this build speaks. The payload states tiers and facts (current_tier, top_tier, max_tier, avg_top_tier, is_current, has_chart_content, per-section and per-phrase) and carries no presentation field at any depth, so a second renderer doesn't need a second contract.
Notable decisions — missing data stays missing: no entry for a section without an overlapping phrase, and current_tier is null rather than 0 when the host reports no usable mastery or time (the null/''/NaN cases are explicit, since Number(null) === 0 would otherwise read as a real tier-0 measurement). Phrase ids use the context-derived key recordPhraseAttempt() writes phrase_attempt.v2 under, so the two join without a translation table. has_chart_content is what separates a silent section from an easy one (both top_tier: 0), inherited by single-level phrases instead of costing an O(phrases × notes) probe per emit.
Verification — node --test 226/226 pass (211 before), node --check screen.js clean, mutation-checked. Docs live in INTEGRATION.md → "sections v3" with the transition policy; version 0.26.0.
Scoped to #156 only — no dependent sub-issue started, and v2 removal is left to the follow-up that lands a v3 consumer in Section Map (sectionmap#14).
Task list (7/7 completed)
Read INTEGRATION.md, PLAYER_CONTEXT.md and the existing sections.v2 emit path in screen.js
@itsjustroxi this sub-issue contains a decision that blocks the other tier-rail sub-issues:
The v3 event shape and the v2 transition policy. Confirm the render-neutral payload (stable id/index and time range, currentTier, topTier, maxTier, is-current, optional player context), and decide whether to keep emitting v2 for a bounded period or to version the new event so Section Map upgrades cannot break by load order (plugins load alphabetically, so Section Map can load before or after this plugin's change).
Activity
pullfrog commentedon Oct 2, 2026
cchacs commentedon Oct 2, 2026
@pullfrog please work on this issue. It is the first sub-issue of #131 and has no dependencies. Keep the PR scoped to this sub-issue only, follow the repo
CLAUDE.md(bumpplugin.json, updateCHANGELOG.md, runnode --test), and do not start the dependent sub-issues. Open a PR againstmain; do not merge it.Generated by Claude Code
pullfrog commentedon Oct 2, 2026
PR #173 is up against
main: #173What shipped —
difficulty_ladder.sections.v3is now emitted additively from the existingcalculateAndEmitSectionDifficulties()call, on its own eventdifficulty:sections-updated-v3, with v2 unchanged ahead of it andwindow._ddCapabilities.sectionsSchemaadvertising which schema this build speaks. The payload states tiers and facts (current_tier,top_tier,max_tier,avg_top_tier,is_current,has_chart_content, per-section and per-phrase) and carries no presentation field at any depth, so a second renderer doesn't need a second contract.Notable decisions — missing data stays missing: no entry for a section without an overlapping phrase, and
current_tierisnullrather than0when the host reports no usable mastery or time (thenull/''/NaNcases are explicit, sinceNumber(null) === 0would otherwise read as a real tier-0 measurement). Phrase ids use the context-derived keyrecordPhraseAttempt()writesphrase_attempt.v2under, so the two join without a translation table.has_chart_contentis what separates a silent section from an easy one (bothtop_tier: 0), inherited by single-level phrases instead of costing anO(phrases × notes)probe per emit.Verification —
node --test226/226 pass (211 before),node --check screen.jsclean, mutation-checked. Docs live inINTEGRATION.md→ "sections v3" with the transition policy; version 0.26.0.Scoped to #156 only — no dependent sub-issue started, and v2 removal is left to the follow-up that lands a v3 consumer in Section Map (sectionmap#14).
Task list (7/7 completed)
big-pickle(free) | 𝕏cchacs commentedon Oct 2, 2026
@itsjustroxi this sub-issue contains a decision that blocks the other tier-rail sub-issues:
The v3 event shape and the v2 transition policy. Confirm the render-neutral payload (stable id/index and time range,
currentTier,topTier,maxTier, is-current, optional player context), and decide whether to keep emitting v2 for a bounded period or to version the new event so Section Map upgrades cannot break by load order (plugins load alphabetically, so Section Map can load before or after this plugin's change).Generated by Claude Code
fix: no fabricated tiers in the v3 payload (#156)
docs: state that is_current is an emit-time snapshot (#156)
feat: add the render-neutral difficulty_ladder.sections.v3 payload (#156
feat: remove glassSize, glass drawing and glass terminology (#159) (#231