Story 4.2: Fix lint errors and code review findings

- Remove unused StripOverlayLayer import and stripOverlayLayer variable from module.js
- Add comprehensive JSDoc annotations to FoundryAdapter.js methods (settings, socket, users, scenes, notifications, hooks)
- Add /* global Dialog */ comment to PlayerPrivacyPanel.js for ESLint
- Remove unused _force parameter from GMPlayerPrivacySelector.js render() method
- Fix PlayerPrivacyPanelMenu.js: add constructor() to fallback class and call super()

All 862 unit tests passing. All Story 4.2 acceptance criteria met.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-05-24 01:25:30 +02:00
parent 2d898f6818
commit 20d13fc678
460 changed files with 68054 additions and 22 deletions
@@ -0,0 +1,325 @@
<!DOCTYPE html>
<!--
PRD Validation Report — skeleton template.
This file is a starter the synthesis pass fills in directly. There is no
substitution engine. The LLM:
1. Reads {doc_workspace}/review-rubric.md and every review-{slug}.md from
additional reviewers.
2. Copies this skeleton.
3. Replaces the placeholder content (everything between TEMPLATE markers)
with the consolidated review, preserving the structure and CSS.
4. Writes the result to {doc_workspace}/validation-report.html.
5. Writes a markdown twin to {doc_workspace}/validation-report.md.
Visual rules the LLM must preserve:
- The container width, the color tokens, the typography.
- One dimension = one collapsible <section class="dimension">.
- Verdict pill uses the verdict-* class matching its judgment.
- Severity badge uses the sev-* class matching its level.
- Each extra reviewer (adversarial, etc.) gets its own collapsible section
below the rubric dimensions.
- The footer always shows the artifact paths and timestamp.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>PRD Validation: TEMPLATE_PRD_NAME</title>
<style>
:root {
--bg: #fafaf9;
--surface: #ffffff;
--border: #e7e5e4;
--text: #1c1917;
--muted: #78716c;
--verdict-strong: #16a34a;
--verdict-adequate: #65a30d;
--verdict-thin: #d97706;
--verdict-broken: #dc2626;
--sev-low: #64748b;
--sev-medium: #ca8a04;
--sev-high: #ea580c;
--sev-critical: #dc2626;
--grade-exc: #16a34a;
--grade-good: #65a30d;
--grade-fair: #d97706;
--grade-poor: #dc2626;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.6;
font-size: 15px;
}
.container { max-width: 960px; margin: 0 auto; padding: 32px 24px 64px; }
header.report-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 24px;
padding-bottom: 16px;
border-bottom: 1px solid var(--border);
margin-bottom: 24px;
}
.title h1 { margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
.title .subtitle { color: var(--muted); font-size: 13px; margin-top: 4px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.grade {
padding: 10px 18px;
border-radius: 8px;
font-weight: 600;
color: white;
font-size: 15px;
white-space: nowrap;
}
.grade-excellent { background: var(--grade-exc); }
.grade-good { background: var(--grade-good); }
.grade-fair { background: var(--grade-fair); }
.grade-poor { background: var(--grade-poor); }
.synthesis {
background: var(--surface);
border: 1px solid var(--border);
border-left: 3px solid var(--muted);
border-radius: 8px;
padding: 18px 22px;
margin-bottom: 24px;
font-size: 15.5px;
}
.synthesis p { margin: 0 0 10px; }
.synthesis p:last-child { margin-bottom: 0; }
.dimension-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
margin-bottom: 24px;
}
.dim-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 12px 14px;
}
.dim-card .dim-name { font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.dim-card .dim-verdict { font-size: 14px; font-weight: 600; }
section.dimension, section.reviewer-section { margin-bottom: 14px; }
section.dimension details, section.reviewer-section details {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
}
section summary {
padding: 14px 20px;
cursor: pointer;
user-select: none;
list-style: none;
display: flex;
align-items: center;
gap: 12px;
}
section summary::-webkit-details-marker { display: none; }
section summary::before {
content: "▸";
display: inline-block;
color: var(--muted);
transition: transform 0.15s ease;
}
section details[open] summary::before { transform: rotate(90deg); }
section summary h2 {
display: inline;
margin: 0;
font-size: 16px;
font-weight: 600;
letter-spacing: -0.005em;
flex: 1;
}
.verdict-pill {
font-size: 11px;
padding: 3px 10px;
border-radius: 999px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: white;
}
.verdict-strong { background: var(--verdict-strong); }
.verdict-adequate { background: var(--verdict-adequate); }
.verdict-thin { background: var(--verdict-thin); }
.verdict-broken { background: var(--verdict-broken); }
.dim-body { padding: 4px 20px 18px; }
.dim-judgment { color: var(--text); font-size: 14.5px; }
.dim-judgment p { margin: 0 0 10px; }
.findings-list { padding: 0 20px 4px; }
article.finding {
padding: 14px 0;
border-top: 1px solid var(--border);
}
article.finding:first-child { border-top: none; }
article.finding header {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 6px;
}
.badge {
font-size: 10.5px;
padding: 3px 8px;
border-radius: 4px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
line-height: 1.4;
}
.badge-sev-low { background: rgba(100, 116, 139, 0.12); color: var(--sev-low); }
.badge-sev-medium { background: rgba(202, 138, 4, 0.14); color: var(--sev-medium); }
.badge-sev-high { background: rgba(234, 88, 12, 0.14); color: var(--sev-high); }
.badge-sev-critical { background: rgba(220, 38, 38, 0.14); color: var(--sev-critical); }
.finding-title { margin: 0; font-size: 15px; font-weight: 500; flex: 1; min-width: 200px; }
.finding-location { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12.5px; color: var(--muted); }
.finding-note, .finding-fix { margin-top: 6px; font-size: 14px; }
.finding-fix strong { color: var(--muted); font-weight: 500; }
.reviewer-source {
font-size: 12px;
color: var(--muted);
font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
.mechanical {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 16px 20px;
margin-top: 24px;
font-size: 14px;
}
.mechanical h3 { margin: 0 0 10px; font-size: 14px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.mechanical ul { margin: 0; padding-left: 20px; }
.mechanical li { margin-bottom: 4px; color: var(--text); }
footer.report-footer {
margin-top: 40px;
padding-top: 16px;
border-top: 1px solid var(--border);
font-size: 12px;
color: var(--muted);
font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
footer .meta { display: flex; gap: 24px; flex-wrap: wrap; }
</style>
</head>
<body>
<div class="container">
<!-- TEMPLATE: header. Fill prd name, prd path, grade text & class. -->
<header class="report-header">
<div class="title">
<h1>TEMPLATE_PRD_NAME — Validation Report</h1>
<div class="subtitle">TEMPLATE_PRD_PATH</div>
</div>
<div class="grade TEMPLATE_GRADE_CLASS">TEMPLATE_GRADE</div>
</header>
<!-- TEMPLATE: overall synthesis paragraphs. Lift directly from
review-rubric.md "Overall verdict" section; expand if extra reviewers
materially shift the picture. Wrap each paragraph in <p>. -->
<div class="synthesis">
<p>TEMPLATE_SYNTHESIS_PARAGRAPH</p>
</div>
<!-- TEMPLATE: dimension summary cards. One per rubric dimension. The
dim-verdict text uses one of: strong | adequate | thin | broken. -->
<div class="dimension-summary">
<div class="dim-card">
<div class="dim-name">Decision-readiness</div>
<div class="dim-verdict" style="color: var(--verdict-TEMPLATE_VERDICT)">TEMPLATE_VERDICT_TEXT</div>
</div>
<!-- repeat for each of the seven dimensions -->
</div>
<!-- TEMPLATE: one section per rubric dimension. Skip a dimension entirely
if the rubric review marked it n/a for this PRD (e.g. downstream
usability for a standalone PRD). Open the section by default if
verdict is thin or broken. -->
<section class="dimension">
<details open>
<summary>
<h2>Decision-readiness</h2>
<span class="verdict-pill verdict-TEMPLATE_VERDICT">TEMPLATE_VERDICT_TEXT</span>
</summary>
<div class="dim-body">
<div class="dim-judgment">
<p>TEMPLATE_DIMENSION_JUDGMENT</p>
</div>
</div>
<div class="findings-list">
<!-- TEMPLATE: zero or more findings -->
<article class="finding">
<header>
<span class="badge badge-sev-TEMPLATE_SEVERITY">TEMPLATE_SEVERITY</span>
<h3 class="finding-title">TEMPLATE_FINDING_TITLE</h3>
<span class="finding-location">TEMPLATE_LOCATION</span>
</header>
<div class="finding-note">TEMPLATE_FINDING_NOTE</div>
<div class="finding-fix"><strong>Fix:</strong> TEMPLATE_SUGGESTED_FIX</div>
</article>
</div>
</details>
</section>
<!-- TEMPLATE: one section per extra reviewer that ran (adversarial, etc.).
Skip this block entirely if only the rubric walker ran. -->
<section class="reviewer-section">
<details>
<summary>
<h2>Adversarial review</h2>
<span class="reviewer-source">TEMPLATE_REVIEWER_SOURCE_FILE</span>
</summary>
<div class="dim-body">
<div class="dim-judgment">
<p>TEMPLATE_REVIEWER_PREAMBLE</p>
</div>
</div>
<div class="findings-list">
<article class="finding">
<header>
<span class="badge badge-sev-TEMPLATE_SEVERITY">TEMPLATE_SEVERITY</span>
<h3 class="finding-title">TEMPLATE_FINDING_TITLE</h3>
<span class="finding-location">TEMPLATE_LOCATION</span>
</header>
<div class="finding-note">TEMPLATE_FINDING_NOTE</div>
<div class="finding-fix"><strong>Fix:</strong> TEMPLATE_SUGGESTED_FIX</div>
</article>
</div>
</details>
</section>
<!-- TEMPLATE: mechanical notes — short, bulleted. Skip if there are none. -->
<div class="mechanical">
<h3>Mechanical notes</h3>
<ul>
<li>TEMPLATE_MECHANICAL_NOTE</li>
</ul>
</div>
<footer class="report-footer">
<div class="meta">
<span>Rubric: TEMPLATE_RUBRIC_PATH</span>
<span>Generated: TEMPLATE_TIMESTAMP</span>
</div>
</footer>
</div>
</body>
</html>