feat: 增加 beautiful 模板人工审查闭环

新增 34 套 family 的本地人工审查面板和 JSON 导出。

新增 human review receipt apply 脚本,生成可追溯的 pending/pass/needs_fix/reject 结果。

人工 receipt 不直接修改 production/default_selectable,当前默认链路仍只有 blue-professional。
This commit is contained in:
songtianyi.theo
2026-06-24 23:07:13 +08:00
parent e8c1d53b86
commit 96ea87a6db
76 changed files with 7752 additions and 247 deletions

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>8-bit-orbit</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="8-bit-orbit"><div class="decision-buttons"><button type="button" data-family-id="8-bit-orbit" data-review-status="pass">pass</button><button type="button" data-family-id="8-bit-orbit" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="8-bit-orbit" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="8-bit-orbit">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="8-bit-orbit" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;8-bit-orbit&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;pixel-orbit-console&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-1" /></div><h2>1. slide-1</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-2" /></div><h2>2. slide-2</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-3" /></div><h2>3. slide-3</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-4" /></div><h2>4. slide-4</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-5.png" alt="slide-5" /></div><h2>5. slide-5</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-6.png" alt="slide-6" /></div><h2>6. slide-6</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-7" /></div><h2>7. slide-7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-8" /></div><h2>8. slide-8</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-9" /></div><h2>9. slide-9</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/8-bit-orbit-1.png" alt="slide-10" /></div><h2>10. slide-10</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/8-bit-orbit.html",
"render_status": "missing_smoke",
"sha256": "86070d51ad2d5f1cef0438e4d5505c160c16f3f5b701a0ef17a950f13f520f19"
"sha256": "6700d6ce17310762eeb43dec97eee6a0c706da5ab7082cdf6c0d0dda83a2453d"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "86070d51ad2d5f1cef0438e4d5505c160c16f3f5b701a0ef17a950f13f520f19",
"contact_sheet": "6700d6ce17310762eeb43dec97eee6a0c706da5ab7082cdf6c0d0dda83a2453d",
"fidelity_receipt": "31bab9cafb1fabb4453980f01a8255d16c9a79e1f882d01585b319dee779d556",
"reference_screenshot": "c1f0517225fbe17807d69de03a7260881738d25bc456bd4151af67fabbb15281",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>biennale-yellow</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="biennale-yellow"><div class="decision-buttons"><button type="button" data-family-id="biennale-yellow" data-review-status="pass">pass</button><button type="button" data-family-id="biennale-yellow" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="biennale-yellow" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="biennale-yellow">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="biennale-yellow" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;biennale-yellow&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;biennale-programme-poster&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-1.png" alt="manifesto" /></div><h2>2. manifesto</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-manifesto</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-1.png" alt="programme" /></div><h2>3. programme</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-programme</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-1.png" alt="chapter" /></div><h2>4. chapter</h2><p>closing / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-5.png" alt="data" /></div><h2>5. data</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-data</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-1.png" alt="quote" /></div><h2>6. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-1.png" alt="cal" /></div><h2>7. cal</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cal</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/biennale-yellow-8.png" alt="colophon" /></div><h2>8. colophon</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-colophon</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/biennale-yellow.html",
"render_status": "missing_smoke",
"sha256": "d0b40a3bfc2420a4c9c8b4c9baaf3cdf08c204a8e504d0917f1458a9b90e01e8"
"sha256": "1c72a9c2b36088f74069f44fc0226aff8002f0b3507243531da6edf96ae4aff7"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "d0b40a3bfc2420a4c9c8b4c9baaf3cdf08c204a8e504d0917f1458a9b90e01e8",
"contact_sheet": "1c72a9c2b36088f74069f44fc0226aff8002f0b3507243531da6edf96ae4aff7",
"fidelity_receipt": "27b20213513d6a895ae84c07aea6d784f5acd5a5fcd4b5a6baf0d1868f4a7dfe",
"reference_screenshot": "8acd74e991ff533d6982f60fc2934ad2020d5ea8e03c5d79d00c24899d6f9e8d",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>block-frame</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="block-frame"><div class="decision-buttons"><button type="button" data-family-id="block-frame" data-review-status="pass">pass</button><button type="button" data-family-id="block-frame" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="block-frame" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="block-frame">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="block-frame" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;block-frame&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;block-frame-grid&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="data_dashboard" /></div><h2>3. data_dashboard</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-4.png" alt="data_dashboard-4" /></div><h2>4. data_dashboard-4</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="quote_or_emphasis" /></div><h2>5. quote_or_emphasis</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="process_or_timeline" /></div><h2>6. process_or_timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="process_or_timeline-7" /></div><h2>7. process_or_timeline-7</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-8.png" alt="data_dashboard-8" /></div><h2>8. data_dashboard-8</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="process_or_timeline-9" /></div><h2>9. process_or_timeline-9</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/block-frame-1.png" alt="closing" /></div><h2>10. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/block-frame.html",
"render_status": "missing_smoke",
"sha256": "e1eebb164177c32de707e461d85253b10fd4789cddd64ec87f390779f2b69802"
"sha256": "cfd16fda1c5b8104b5e6f3c990b3fc2d2b829f79deaea3dae5cb1157444ea9e6"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "e1eebb164177c32de707e461d85253b10fd4789cddd64ec87f390779f2b69802",
"contact_sheet": "cfd16fda1c5b8104b5e6f3c990b3fc2d2b829f79deaea3dae5cb1157444ea9e6",
"fidelity_receipt": "e35a3eb5441b55568413e926f2275e9593c0b01d95a4345337995c995ffffd95",
"reference_screenshot": "3fd1774d38f1bfbda05df46fc7f2b98a1780de45ced4d71f4925136bbf2460a0",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>blue-professional</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>passed</strong>auto gate</div>
<div class="metric"><strong>passed</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="blue-professional"><div class="decision-buttons"><button type="button" data-family-id="blue-professional" data-review-status="pass">pass</button><button type="button" data-family-id="blue-professional" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="blue-professional" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="blue-professional">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="blue-professional" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;blue-professional&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;executive-dashboard&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> none</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge ok">passed</span></p><p><code>layout-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge ok">passed</span></p><p><code>layout-agenda</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="metrics" /></div><h2>3. metrics</h2><p>data_metrics / data_or_structured</p><p><span class="badge ok">passed</span></p><p><code>layout-metrics</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="dashboard" /></div><h2>4. dashboard</h2><p>data_dashboard / data_or_structured</p><p><span class="badge ok">passed</span></p><p><code>layout-dashboard</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="split" /></div><h2>5. split</h2><p>content_split / comparison_or_split</p><p><span class="badge ok">passed</span></p><p><code>layout-split</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-6.png" alt="bars" /></div><h2>6. bars</h2><p>data_chart / data_or_structured</p><p><span class="badge ok">passed</span></p><p><code>layout-bars</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge ok">passed</span></p><p><code>layout-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-8.png" alt="timeline" /></div><h2>8. timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge ok">passed</span></p><p><code>layout-timeline</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="detail" /></div><h2>9. detail</h2><p>detail / content</p><p><span class="badge ok">passed</span></p><p><code>layout-detail</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/blue-professional-1.png" alt="closing" /></div><h2>10. closing</h2><p>closing / closing</p><p><span class="badge ok">passed</span></p><p><code>layout-closing</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/blue-professional.html",
"render_status": "passed",
"sha256": "28d5646879b9daf6f8841e968e2337c2dceb316feea8bd83ae416ae65f54a7d2"
"sha256": "315b18dd7cd44f6cb18061c82b58a74a54c88ca797b93232011edb322653e51b"
},
"default_selectable": true,
"evidence_hashes": {
"contact_sheet": "28d5646879b9daf6f8841e968e2337c2dceb316feea8bd83ae416ae65f54a7d2",
"contact_sheet": "315b18dd7cd44f6cb18061c82b58a74a54c88ca797b93232011edb322653e51b",
"fidelity_receipt": "f6a4a0a015c09f14cb9e987f69734cbb05a06e79bba9c9b1ba2ca16ed6bc597a",
"reference_screenshot": "0f08aefe70cb14ca7f3126ecc2f34319ca8f281ecdf81c6d6486ea93b2236f8c",
"smoke_receipt": "ae3cfa9a3ba970c0f4d6903148d7291375019dd3d12a8c3619599c5520742804",

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>bold-poster</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="bold-poster"><div class="decision-buttons"><button type="button" data-family-id="bold-poster" data-review-status="pass">pass</button><button type="button" data-family-id="bold-poster" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="bold-poster" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="bold-poster">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="bold-poster" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;bold-poster&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;poster-stat-punch&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="hero" /></div><h2>1. hero</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-hero</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="red" /></div><h2>2. red</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-red</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="summary" /></div><h2>3. summary</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-summary</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-4.png" alt="financial" /></div><h2>4. financial</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-financial</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="stat" /></div><h2>5. stat</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-stat</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="services" /></div><h2>6. services</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-services</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="roadmap" /></div><h2>7. roadmap</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-roadmap</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-8.png" alt="pillars" /></div><h2>8. pillars</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-pillars</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="global" /></div><h2>9. global</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-global</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/bold-poster-1.png" alt="close" /></div><h2>10. close</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-close</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/bold-poster.html",
"render_status": "missing_smoke",
"sha256": "55b5c1c1fb0a11183ee0779e02f4a374cb989adceb4e3999f754dcf815f2e161"
"sha256": "17a715b8c3cab33d9e80c8abbbd902fa00ae702f63a86ad87fa0bdeb68913433"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "55b5c1c1fb0a11183ee0779e02f4a374cb989adceb4e3999f754dcf815f2e161",
"contact_sheet": "17a715b8c3cab33d9e80c8abbbd902fa00ae702f63a86ad87fa0bdeb68913433",
"fidelity_receipt": "5cb7f128615cbb801b3e66df177a5c1d61b3339c92cba3a04b9db00aadce0635",
"reference_screenshot": "95a9351619463053bda29bdf472702ed4bc650a4510fa6b3cfcc34d5e3ba79b1",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>broadside</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>16</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="broadside"><div class="decision-buttons"><button type="button" data-family-id="broadside" data-review-status="pass">pass</button><button type="button" data-family-id="broadside" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="broadside" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="broadside">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="broadside" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;broadside&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;editorial-quote-chart&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="chapter" /></div><h2>2. chapter</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="statement" /></div><h2>3. statement</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-4.png" alt="split" /></div><h2>4. split</h2><p>content_split / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--split</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="stats" /></div><h2>5. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="fadelist" /></div><h2>6. fadelist</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--fadelist</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="list" /></div><h2>7. list</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--list</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="quote" /></div><h2>8. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="compare" /></div><h2>9. compare</h2><p>process_or_timeline / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--compare</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="chart" /></div><h2>10. chart</h2><p>closing / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="diagram" /></div><h2>11. diagram</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--diagram</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="pie" /></div><h2>12. pie</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--pie</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-13.png" alt="pyramid" /></div><h2>13. pyramid</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--pyramid</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="vtimeline" /></div><h2>14. vtimeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--vtimeline</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="cycle" /></div><h2>15. cycle</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--cycle</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/broadside-1.png" alt="end" /></div><h2>16. end</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--end</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/broadside.html",
"render_status": "missing_smoke",
"sha256": "3f823b2d1e5a98af40443c0f04c5180e2d40c0ae8dab5a5b5c81f80494298822"
"sha256": "db1ffb89fb710b18e5e23c50bd04a5c500bea3a9602bc7148def1cd9b712572c"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "3f823b2d1e5a98af40443c0f04c5180e2d40c0ae8dab5a5b5c81f80494298822",
"contact_sheet": "db1ffb89fb710b18e5e23c50bd04a5c500bea3a9602bc7148def1cd9b712572c",
"fidelity_receipt": "fd3c0b8d0ae82ecad0cbeb13974361d5bf8f9e76083619edf5a88d77b0b5f664",
"reference_screenshot": "96805bd67e4502f94b078b723d252717183fe8eb34f2eb529c44b772b4dcdce4",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>capsule</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="capsule"><div class="decision-buttons"><button type="button" data-family-id="capsule" data-review-status="pass">pass</button><button type="button" data-family-id="capsule" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="capsule" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="capsule">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="capsule" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;capsule&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;capsule-card-system&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="data_dashboard" /></div><h2>3. data_dashboard</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-4.png" alt="data_dashboard-4" /></div><h2>4. data_dashboard-4</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="quote_or_emphasis" /></div><h2>5. quote_or_emphasis</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="process_or_timeline" /></div><h2>6. process_or_timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="data_dashboard-7" /></div><h2>7. data_dashboard-7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-8.png" alt="slide-8" /></div><h2>8. slide-8</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="slide-9" /></div><h2>9. slide-9</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/capsule-1.png" alt="closing" /></div><h2>10. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/capsule.html",
"render_status": "missing_smoke",
"sha256": "35b0d6c1d01dd97448bcf50981754d1f0155439b4431efeeaa2b9d4208f7378f"
"sha256": "b89c818def92fdd5638e4d0c343bdfd8a1ae201087c5701f9740e66d21d41636"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "35b0d6c1d01dd97448bcf50981754d1f0155439b4431efeeaa2b9d4208f7378f",
"contact_sheet": "b89c818def92fdd5638e4d0c343bdfd8a1ae201087c5701f9740e66d21d41636",
"fidelity_receipt": "38ef8db0e9fdaf4d3c4f83f3b9ab1a2c956661315784c6090c301faac93f2f8c",
"reference_screenshot": "468b1b618668660274e7a46a528d0a323fb926c3e47f7e5895ec03189efd35b3",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>cartesian</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>9</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="cartesian"><div class="decision-buttons"><button type="button" data-family-id="cartesian" data-review-status="pass">pass</button><button type="button" data-family-id="cartesian" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="cartesian" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="cartesian">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="cartesian" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;cartesian&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;architectural-spec&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="agenda" /></div><h2>1. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-agenda</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="statement" /></div><h2>2. statement</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="barchart" /></div><h2>3. barchart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-barchart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-4.png" alt="twocol" /></div><h2>4. twocol</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-twocol</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="cards" /></div><h2>5. cards</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-cards</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="linechart" /></div><h2>6. linechart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-linechart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="timeline" /></div><h2>7. timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-timeline</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-8.png" alt="team" /></div><h2>8. team</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-team</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cartesian-1.png" alt="closing" /></div><h2>9. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-closing</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/cartesian.html",
"render_status": "missing_smoke",
"sha256": "c1f6795edcce9b5f104edd8f19b1674ceee66b19b905b330f20f1328fde6baa4"
"sha256": "3a68f9f0984b0c0dcd526bfb1bd7deec743e293c739d09529d31ec8dc31c548d"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "c1f6795edcce9b5f104edd8f19b1674ceee66b19b905b330f20f1328fde6baa4",
"contact_sheet": "3a68f9f0984b0c0dcd526bfb1bd7deec743e293c739d09529d31ec8dc31c548d",
"fidelity_receipt": "d7bec45b7684b8ab2e98755e76624fffdf5048fd864aa64d7092aeb6aba3a62d",
"reference_screenshot": "59af0f5ee20b85f07ada82a1d6bb8ab5e69b81bb08b5abf2a7520eca4934e93e",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>cobalt-grid</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="cobalt-grid"><div class="decision-buttons"><button type="button" data-family-id="cobalt-grid" data-review-status="pass">pass</button><button type="button" data-family-id="cobalt-grid" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="cobalt-grid" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="cobalt-grid">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="cobalt-grid" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;cobalt-grid&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;trend-grid-report&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-1.png" alt="manifesto" /></div><h2>2. manifesto</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-manifesto</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-3.png" alt="index" /></div><h2>3. index</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-index</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-1.png" alt="chapter" /></div><h2>4. chapter</h2><p>content / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-5.png" alt="data" /></div><h2>5. data</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-data</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-1.png" alt="quote" /></div><h2>6. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-1.png" alt="table" /></div><h2>7. table</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-table</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/cobalt-grid-1.png" alt="colophon" /></div><h2>8. colophon</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-colophon</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/cobalt-grid.html",
"render_status": "missing_smoke",
"sha256": "f9970bf563b9fc18a08f6617c1a1769cbc8cebd4ec98dcf042c1be12398c8f46"
"sha256": "4fd837a9e9c7fc3da874f451915c9942f7c35b2f179f07986e2523c8fb0e2e9f"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "f9970bf563b9fc18a08f6617c1a1769cbc8cebd4ec98dcf042c1be12398c8f46",
"contact_sheet": "4fd837a9e9c7fc3da874f451915c9942f7c35b2f179f07986e2523c8fb0e2e9f",
"fidelity_receipt": "fd2b394777733364723f20d0d732a346f93edba0a748628ce9a1e5596726cb02",
"reference_screenshot": "e85989914eb7ca3bb279e03cc792df19c5d06f8d3ba0e59515211164fca5ae2d",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>coral</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="coral"><div class="decision-buttons"><button type="button" data-family-id="coral" data-review-status="pass">pass</button><button type="button" data-family-id="coral" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="coral" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="coral">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="coral" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;coral&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;coral-magazine-feature&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="detail" /></div><h2>3. detail</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-4.png" alt="data_dashboard" /></div><h2>4. data_dashboard</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="process_or_timeline" /></div><h2>5. process_or_timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="data_dashboard-6" /></div><h2>6. data_dashboard-6</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="quote_or_emphasis" /></div><h2>7. quote_or_emphasis</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-8.png" alt="process_or_timeline-8" /></div><h2>8. process_or_timeline-8</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="detail-9" /></div><h2>9. detail-9</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/coral-1.png" alt="closing" /></div><h2>10. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/coral.html",
"render_status": "missing_smoke",
"sha256": "402b5732bbb22f8145a73ec00176e0653a5f2744245bf10ec9ea757f8b6c1e70"
"sha256": "b47a477b472ff5e219ff685d2fd247587ea389cdbd726d2276ffabbbfebf5403"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "402b5732bbb22f8145a73ec00176e0653a5f2744245bf10ec9ea757f8b6c1e70",
"contact_sheet": "b47a477b472ff5e219ff685d2fd247587ea389cdbd726d2276ffabbbfebf5403",
"fidelity_receipt": "dd795f5b763b8b5769e173a07ba63f2a2da2345fefaf96cb48989b7a5ba4ef2c",
"reference_screenshot": "3cce11542e0c380396c14d2e7ac7406af704af163e7ba85b8ce9e2fdf7d12015",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>creative-mode</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="creative-mode"><div class="decision-buttons"><button type="button" data-family-id="creative-mode" data-review-status="pass">pass</button><button type="button" data-family-id="creative-mode" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="creative-mode" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="creative-mode">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="creative-mode" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;creative-mode&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;creative-mode-grid&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-1.png" alt="s1" /></div><h2>1. s1</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-1.png" alt="s2" /></div><h2>2. s2</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-1.png" alt="s3" /></div><h2>3. s3</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-4.png" alt="s4" /></div><h2>4. s4</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-1.png" alt="s5" /></div><h2>5. s5</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-6.png" alt="s6" /></div><h2>6. s6</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-1.png" alt="s7" /></div><h2>7. s7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/creative-mode-1.png" alt="s8" /></div><h2>8. s8</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s8</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/creative-mode.html",
"render_status": "missing_smoke",
"sha256": "224db100187b471bfeb2b4d38360dc8efa283251be6ebf174da10d74700b080e"
"sha256": "d25bb924c36879bf68e1282a46c1818b201962ec80ad0d845a1b2bef6d5b2292"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "224db100187b471bfeb2b4d38360dc8efa283251be6ebf174da10d74700b080e",
"contact_sheet": "d25bb924c36879bf68e1282a46c1818b201962ec80ad0d845a1b2bef6d5b2292",
"fidelity_receipt": "51de4317d40671c7a4ba0868cacfa3c86ca2de0d14eecb8d07177f6c53506acf",
"reference_screenshot": "aaac87da4e7f0e1e294f8f3d88616b067174687f4b89dafcad0acb4b967e9633",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>daisy-days</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>9</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="daisy-days"><div class="decision-buttons"><button type="button" data-family-id="daisy-days" data-review-status="pass">pass</button><button type="button" data-family-id="daisy-days" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="daisy-days" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="daisy-days">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="daisy-days" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;daisy-days&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;daisy-workshop-playbook&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="welcome" /></div><h2>1. welcome</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-welcome</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="weekly" /></div><h2>2. weekly</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-weekly</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="timeline" /></div><h2>3. timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-timeline</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-4.png" alt="chart_bar" /></div><h2>4. chart_bar</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-chart-bar</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="cards" /></div><h2>5. cards</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-cards</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="quote" /></div><h2>6. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="team" /></div><h2>7. team</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-team</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-8.png" alt="process" /></div><h2>8. process</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-process</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/daisy-days-1.png" alt="donut" /></div><h2>9. donut</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-donut</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/daisy-days.html",
"render_status": "missing_smoke",
"sha256": "60ae07dae1e5cb86fbefc0ffb62eb9bdf8c371f121793ad9d9e4cee23c993443"
"sha256": "4df7e9d7a65b8e6749d3e487481302defbcfb6d0efd98fc00bb5afc6921e20cc"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "60ae07dae1e5cb86fbefc0ffb62eb9bdf8c371f121793ad9d9e4cee23c993443",
"contact_sheet": "4df7e9d7a65b8e6749d3e487481302defbcfb6d0efd98fc00bb5afc6921e20cc",
"fidelity_receipt": "926bc15a8016d24e25c00a42eb878578dbb825471d6ba2abc316bf48016ab5bc",
"reference_screenshot": "65f6615ff2ec51a3d4a77573c2a53471b356724a58bd33dffdb55ed69ab2b73b",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>editorial-forest</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="editorial-forest"><div class="decision-buttons"><button type="button" data-family-id="editorial-forest" data-review-status="pass">pass</button><button type="button" data-family-id="editorial-forest" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="editorial-forest" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="editorial-forest">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="editorial-forest" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;editorial-forest&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;serif-stat-editorial&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-2.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>agenda</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-1.png" alt="statement" /></div><h2>3. statement</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-1.png" alt="two_col" /></div><h2>4. two_col</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>two-col</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-5.png" alt="data" /></div><h2>5. data</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-1.png" alt="framework" /></div><h2>6. framework</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>framework</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-1.png" alt="stats" /></div><h2>7. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-forest-1.png" alt="summary" /></div><h2>8. summary</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>summary</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/editorial-forest.html",
"render_status": "missing_smoke",
"sha256": "6966fb4b3014525f5b221bd6ad46a06c7f98b2046882f23d9a96c35876453e30"
"sha256": "a72d3845093b54b819d538e7549951871fe1cb07d991b6eb84b48b2a398c653f"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "6966fb4b3014525f5b221bd6ad46a06c7f98b2046882f23d9a96c35876453e30",
"contact_sheet": "a72d3845093b54b819d538e7549951871fe1cb07d991b6eb84b48b2a398c653f",
"fidelity_receipt": "64abadb7a840271a45d482c1f3a7e8f4e75909ac007ef2c13d4ac0f77c77fdaf",
"reference_screenshot": "a081f3b16a3dd72dd16d9fdfcf30aa61cf66c79c865189eb380d22bd425c2a1c",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>editorial-tri-tone</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="editorial-tri-tone"><div class="decision-buttons"><button type="button" data-family-id="editorial-tri-tone" data-review-status="pass">pass</button><button type="button" data-family-id="editorial-tri-tone" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="editorial-tri-tone" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="editorial-tri-tone">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="editorial-tri-tone" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;editorial-tri-tone&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;tritone-editorial-spread&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-1.png" alt="manifesto" /></div><h2>2. manifesto</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-manifesto</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-3.png" alt="grid" /></div><h2>3. grid</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-grid</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-4.png" alt="stat" /></div><h2>4. stat</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stat</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-1.png" alt="timeline" /></div><h2>5. timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-timeline</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-1.png" alt="chart" /></div><h2>6. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-1.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/editorial-tri-tone-1.png" alt="closer" /></div><h2>8. closer</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-closer</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/editorial-tri-tone.html",
"render_status": "missing_smoke",
"sha256": "ba27daa57e94914e24e341b6a8ae1d7434dfb715f5bc6a54643173865839fb10"
"sha256": "dfa4ea5c54fbd6428d4c98cba1707e4e7a6fa3f11b74dc8879c25305b20ca07f"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "ba27daa57e94914e24e341b6a8ae1d7434dfb715f5bc6a54643173865839fb10",
"contact_sheet": "dfa4ea5c54fbd6428d4c98cba1707e4e7a6fa3f11b74dc8879c25305b20ca07f",
"fidelity_receipt": "5bf44805d7dc674b07da8f0ac8f0a749bfc78893371e921567db82e5bf3a251b",
"reference_screenshot": "0b89022af5bfcc26356b7bdb48156510ba16b643e9bc01027ae8197092ead507",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>emerald-editorial</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="emerald-editorial"><div class="decision-buttons"><button type="button" data-family-id="emerald-editorial" data-review-status="pass">pass</button><button type="button" data-family-id="emerald-editorial" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="emerald-editorial" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="emerald-editorial">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="emerald-editorial" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;emerald-editorial&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;emerald-editorial-cover&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-1.png" alt="s1" /></div><h2>1. s1</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-1.png" alt="s2" /></div><h2>2. s2</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-3.png" alt="s3" /></div><h2>3. s3</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-1.png" alt="s4" /></div><h2>4. s4</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-1.png" alt="s5" /></div><h2>5. s5</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-6.png" alt="s6" /></div><h2>6. s6</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-1.png" alt="s7" /></div><h2>7. s7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/emerald-editorial-1.png" alt="s8" /></div><h2>8. s8</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>s8</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/emerald-editorial.html",
"render_status": "missing_smoke",
"sha256": "e082713ef62b3a90e195a07823726c77e4909aaed1cde7ca7b57b4b888860833"
"sha256": "ae8042a321313b12a03e9b25379c89544421c4a9e8886b08f87990638f02d7da"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "e082713ef62b3a90e195a07823726c77e4909aaed1cde7ca7b57b4b888860833",
"contact_sheet": "ae8042a321313b12a03e9b25379c89544421c4a9e8886b08f87990638f02d7da",
"fidelity_receipt": "7aa06118b44f3dcc6202b56e64ec03134f5487d3e48a25279a9ccfeb09c1c81b",
"reference_screenshot": "fda35bb4c4810369a5c5bccd70cbcd9d474691027c79a0d94ebf59dbf673c150",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>grove</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>12</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="grove"><div class="decision-buttons"><button type="button" data-family-id="grove" data-review-status="pass">pass</button><button type="button" data-family-id="grove" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="grove" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="grove">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="grove" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;grove&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;grove-organic-brief&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="chapter" /></div><h2>2. chapter</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="statement" /></div><h2>3. statement</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-4.png" alt="split" /></div><h2>4. split</h2><p>content_split / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--split</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="stats" /></div><h2>5. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="list" /></div><h2>6. list</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--list</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-8.png" alt="compare" /></div><h2>8. compare</h2><p>data_dashboard / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--compare</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="chapter-9" /></div><h2>9. chapter-9</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="statement-10" /></div><h2>10. statement-10</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="chart" /></div><h2>11. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/grove-1.png" alt="end" /></div><h2>12. end</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--end</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/grove.html",
"render_status": "missing_smoke",
"sha256": "35333c79ea1ad148e7763b55a6d5886dae6c077cd65c49430a954e69d5997eb7"
"sha256": "da6b1ce28c3ae75ea17159bc4a656369fc659bdbfcff3b953aa9ac3ca4c74e28"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "35333c79ea1ad148e7763b55a6d5886dae6c077cd65c49430a954e69d5997eb7",
"contact_sheet": "da6b1ce28c3ae75ea17159bc4a656369fc659bdbfcff3b953aa9ac3ca4c74e28",
"fidelity_receipt": "72a5d983bb922049b536f086eedb89d0e3a7959b72480aab5fcfce63842d7455",
"reference_screenshot": "6a01598d4b183837b96c698eb9453962fea4bea072a431ee4d71aef6e09da3eb",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>long-table</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="long-table"><div class="decision-buttons"><button type="button" data-family-id="long-table" data-review-status="pass">pass</button><button type="button" data-family-id="long-table" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="long-table" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="long-table">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="long-table" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;long-table&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;printed-program&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-1.png" alt="manifesto" /></div><h2>2. manifesto</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-manifesto</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-3.png" alt="index" /></div><h2>3. index</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-index</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-1.png" alt="featured" /></div><h2>4. featured</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-featured</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-1.png" alt="menu" /></div><h2>5. menu</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-menu</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-1.png" alt="quote" /></div><h2>6. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-7.png" alt="cal" /></div><h2>7. cal</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cal</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/long-table-1.png" alt="closing" /></div><h2>8. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-closing</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/long-table.html",
"render_status": "missing_smoke",
"sha256": "03eff66d27ff955a40c9ff4fda6f840251594bcaa9698d1452cc3527118a7317"
"sha256": "451fb96587eb1e8dad65a4e7e34a40c7f81ce178256f9e61f72fb57090c4c61a"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "03eff66d27ff955a40c9ff4fda6f840251594bcaa9698d1452cc3527118a7317",
"contact_sheet": "451fb96587eb1e8dad65a4e7e34a40c7f81ce178256f9e61f72fb57090c4c61a",
"fidelity_receipt": "96948f5547801870efb639d755ee4b944114cd0925c3fd03f6d15cafe935119e",
"reference_screenshot": "79f7956399971a6038c6b98ba7850b8d232c593bafb1c484c7127e5d3fd60bba",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>mat</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>9</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="mat"><div class="decision-buttons"><button type="button" data-family-id="mat" data-review-status="pass">pass</button><button type="button" data-family-id="mat" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="mat" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="mat">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="mat" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;mat&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;mat-midcentury-board&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="statement" /></div><h2>2. statement</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="split" /></div><h2>3. split</h2><p>content_split / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--split</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-4.png" alt="stats" /></div><h2>4. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="quote" /></div><h2>5. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="list" /></div><h2>6. list</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--list</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="compare" /></div><h2>7. compare</h2><p>content / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--compare</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-8.png" alt="chart" /></div><h2>8. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/mat-1.png" alt="end" /></div><h2>9. end</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--end</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/mat.html",
"render_status": "missing_smoke",
"sha256": "80cc3f0b8990075017711519795bc91a6a73eb5e748ec350fcf1dbbec092738f"
"sha256": "45c1a37544d752c06e326d5789a8ad1a51ba2a7926e27db048490526898423b4"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "80cc3f0b8990075017711519795bc91a6a73eb5e748ec350fcf1dbbec092738f",
"contact_sheet": "45c1a37544d752c06e326d5789a8ad1a51ba2a7926e27db048490526898423b4",
"fidelity_receipt": "e1e95e38f4ea8124a378b7de4a0eb81593f192811ea42e7b31085ed84410cf34",
"reference_screenshot": "acac0ac30af8fbb206adfb6810573c72d3ca96b00293f9f850fdeefed1ae11dc",
"smoke_receipt": null,

File diff suppressed because one or more lines are too long

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/monochrome.html",
"render_status": "missing_smoke",
"sha256": "98ff05a96dc1ba8c6d1567cdc05e07d956cf6c4d8acb8ff95ec73df343d9e6d7"
"sha256": "3d2584d894dc76b41f1abd78da0a0dba991a1b9cbc6e63672bb9cb45f75418a1"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "98ff05a96dc1ba8c6d1567cdc05e07d956cf6c4d8acb8ff95ec73df343d9e6d7",
"contact_sheet": "3d2584d894dc76b41f1abd78da0a0dba991a1b9cbc6e63672bb9cb45f75418a1",
"fidelity_receipt": "7fd4a1a4f9929a0add47861c0f489f80b3cfe4dd9e91dc13014ec264811c78c5",
"reference_screenshot": "bac6b00bf1d0b3c97b19d2a0c45edf44af5cbf369f2cf3ebe78a207a7b6b8c7b",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>neo-grid-bold</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>12</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="neo-grid-bold"><div class="decision-buttons"><button type="button" data-family-id="neo-grid-bold" data-review-status="pass">pass</button><button type="button" data-family-id="neo-grid-bold" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="neo-grid-bold" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="neo-grid-bold">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="neo-grid-bold" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;neo-grid-bold&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;dense-panel-grid&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="toc" /></div><h2>2. toc</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-toc</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-3.png" alt="stats" /></div><h2>3. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="features" /></div><h2>4. features</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-features</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="chart" /></div><h2>5. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="section" /></div><h2>6. section</h2><p>content / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-section</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-8.png" alt="cta" /></div><h2>8. cta</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cta</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="consult" /></div><h2>9. consult</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-consult</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="chart2" /></div><h2>10. chart2</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="process2" /></div><h2>11. process2</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-process2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/neo-grid-bold-1.png" alt="matrix2" /></div><h2>12. matrix2</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-matrix2</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/neo-grid-bold.html",
"render_status": "missing_smoke",
"sha256": "ceebdd152351e3d9124f365de2ea46b5b03bd90f8ca532d7f99f79bc29cfd95d"
"sha256": "dfdb0c6be0e75f49ecd5d5a782eff136bb25cc679bfbfd17540b9aa47d14356e"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "ceebdd152351e3d9124f365de2ea46b5b03bd90f8ca532d7f99f79bc29cfd95d",
"contact_sheet": "dfdb0c6be0e75f49ecd5d5a782eff136bb25cc679bfbfd17540b9aa47d14356e",
"fidelity_receipt": "9d0ced3d64a642e028edf86ff6457c36def39175b3079fff6a4c97b645803228",
"reference_screenshot": "c53ba5da0f1b85b23ad1975da65edafaee84f029f06c468b2fbd036031ce15e5",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>peoples-platform</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="peoples-platform"><div class="decision-buttons"><button type="button" data-family-id="peoples-platform" data-review-status="pass">pass</button><button type="button" data-family-id="peoples-platform" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="peoples-platform" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="peoples-platform">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="peoples-platform" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;peoples-platform&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;people-platform-manifesto&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="toc" /></div><h2>2. toc</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-toc</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="manifesto" /></div><h2>3. manifesto</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-manifesto</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-4.png" alt="pillars" /></div><h2>4. pillars</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-pillars</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="stat" /></div><h2>5. stat</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stat</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="platform" /></div><h2>6. platform</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-platform</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-8.png" alt="timeline" /></div><h2>8. timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-timeline</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="compare" /></div><h2>9. compare</h2><p>detail / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-compare</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/peoples-platform-1.png" alt="close" /></div><h2>10. close</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-close</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/peoples-platform.html",
"render_status": "missing_smoke",
"sha256": "6cde51c31f47436c3b5b6db4fbaccb4181b795fb84213c6a1e0ace77cd88eb66"
"sha256": "35f74a4093000ea952bfbfef2a211fd0d47f6c926ecbc6cb6fc95a07f3946acf"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "6cde51c31f47436c3b5b6db4fbaccb4181b795fb84213c6a1e0ace77cd88eb66",
"contact_sheet": "35f74a4093000ea952bfbfef2a211fd0d47f6c926ecbc6cb6fc95a07f3946acf",
"fidelity_receipt": "679368f5526815a2cb311d583f0f86871000639c85643e6b47099ab91566d5cc",
"reference_screenshot": "9a0c40acaa0fb9c058745cbd16c875f9b7a0417d46c6c37dede388e32cf52d25",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>pin-and-paper</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>11</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="pin-and-paper"><div class="decision-buttons"><button type="button" data-family-id="pin-and-paper" data-review-status="pass">pass</button><button type="button" data-family-id="pin-and-paper" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="pin-and-paper" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="pin-and-paper">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="pin-and-paper" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;pin-and-paper&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;annotated-field-board&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-agenda</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-3.png" alt="notes" /></div><h2>3. notes</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-notes</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="sec" /></div><h2>4. sec</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-sec</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="notice" /></div><h2>5. notice</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-notice</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="chart" /></div><h2>6. chart</h2><p>process_or_timeline / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="process" /></div><h2>7. process</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-process</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="matrix" /></div><h2>8. matrix</h2><p>process_or_timeline / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-matrix</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="stats" /></div><h2>9. stats</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-1.png" alt="quote" /></div><h2>10. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pin-and-paper-11.png" alt="cta" /></div><h2>11. cta</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cta</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/pin-and-paper.html",
"render_status": "missing_smoke",
"sha256": "d3300e5df932d79e82fd0853a9af8c252aa090d1e1df988d77b4d1045ca63002"
"sha256": "063652158d00662045c6a94a70a8e7ae36f00aabf3ea5216463e7f8c6564256a"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "d3300e5df932d79e82fd0853a9af8c252aa090d1e1df988d77b4d1045ca63002",
"contact_sheet": "063652158d00662045c6a94a70a8e7ae36f00aabf3ea5216463e7f8c6564256a",
"fidelity_receipt": "b6aa5696947e5fc7fcd633c340cea26e983956f97a0a54b72eb035818d6a3d76",
"reference_screenshot": "35ff94a10d71d18318fa11e1c95fb6a32e2b1801ffff24ccc8e0f36afe187387",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>pink-script</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>9</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="pink-script"><div class="decision-buttons"><button type="button" data-family-id="pink-script" data-review-status="pass">pass</button><button type="button" data-family-id="pink-script" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="pink-script" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="pink-script">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="pink-script" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;pink-script&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;pink-nocturne-feature&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="toc" /></div><h2>2. toc</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-toc</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="stats" /></div><h2>3. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-4.png" alt="section" /></div><h2>4. section</h2><p>content / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-section</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="chart" /></div><h2>5. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="process" /></div><h2>6. process</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-process</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="matrix" /></div><h2>7. matrix</h2><p>content / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-matrix</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-8.png" alt="quote" /></div><h2>8. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/pink-script-1.png" alt="cta" /></div><h2>9. cta</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cta</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/pink-script.html",
"render_status": "missing_smoke",
"sha256": "b0b78d2776184009efaedb026d3c5dc4528a29f8fba7d7b6c5da4618fbd42497"
"sha256": "be97ade117aa12ee9ffcd562c2e2f905076db7c4ba21ebbc3efa92b4aa0890ae"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "b0b78d2776184009efaedb026d3c5dc4528a29f8fba7d7b6c5da4618fbd42497",
"contact_sheet": "be97ade117aa12ee9ffcd562c2e2f905076db7c4ba21ebbc3efa92b4aa0890ae",
"fidelity_receipt": "ff075c2947f7c09785c47c57f68d995722873676d91251a822747e0b096b88bf",
"reference_screenshot": "d39af58b620fe59ab0e28db0f070fd6e13214896115aa984be069369ef594ff7",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>playful</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="playful"><div class="decision-buttons"><button type="button" data-family-id="playful" data-review-status="pass">pass</button><button type="button" data-family-id="playful" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="playful" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="playful">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="playful" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;playful&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;playful-indie-launch&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="data_dashboard" /></div><h2>3. data_dashboard</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="data_dashboard-4" /></div><h2>4. data_dashboard-4</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="detail" /></div><h2>5. detail</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-6.png" alt="data_dashboard-6" /></div><h2>6. data_dashboard-6</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="process_or_timeline" /></div><h2>7. process_or_timeline</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-8.png" alt="data_dashboard-8" /></div><h2>8. data_dashboard-8</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="slide-9" /></div><h2>9. slide-9</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/playful-1.png" alt="closing" /></div><h2>10. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/playful.html",
"render_status": "missing_smoke",
"sha256": "8c06c02b5802f957b497d1332e8cb0ab3d3a2c1825f551c946d00c38244aadad"
"sha256": "dce30937bc181379275aeb74ef278b312b7cbceea99f2e2522aaefe6d6f16878"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "8c06c02b5802f957b497d1332e8cb0ab3d3a2c1825f551c946d00c38244aadad",
"contact_sheet": "dce30937bc181379275aeb74ef278b312b7cbceea99f2e2522aaefe6d6f16878",
"fidelity_receipt": "e828f367dda5704dca8c804fb833051e8e3888202e9b76169082ac50164873d8",
"reference_screenshot": "75c22cf0736c2c349599de769e984af4e55440dbf83fb4abac35e5c0842abe81",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>raw-grid</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="raw-grid"><div class="decision-buttons"><button type="button" data-family-id="raw-grid" data-review-status="pass">pass</button><button type="button" data-family-id="raw-grid" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="raw-grid" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="raw-grid">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="raw-grid" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;raw-grid&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;brutalist-matrix&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s1" /></div><h2>1. s1</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s2" /></div><h2>2. s2</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s3" /></div><h2>3. s3</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-4.png" alt="s4" /></div><h2>4. s4</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s5" /></div><h2>5. s5</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s6" /></div><h2>6. s6</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s7" /></div><h2>7. s7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-8.png" alt="s8" /></div><h2>8. s8</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s9" /></div><h2>9. s9</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/raw-grid-1.png" alt="s10" /></div><h2>10. s10</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>s10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/raw-grid.html",
"render_status": "missing_smoke",
"sha256": "87221867c254043e20ca653260daa52ccb0f88492fe1fc5595db51edb2d5c87a"
"sha256": "0fc408b566d5f90530b8afb2e380258a3d6013f7ed2089e4b53921eb49d97c57"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "87221867c254043e20ca653260daa52ccb0f88492fe1fc5595db51edb2d5c87a",
"contact_sheet": "0fc408b566d5f90530b8afb2e380258a3d6013f7ed2089e4b53921eb49d97c57",
"fidelity_receipt": "fee9ac2b5c6d69612a2a082849f1829f5b3c75f2a5c2d29b76657361f4fc04cc",
"reference_screenshot": "4056c85b9415ba7a9a988d45f5316cbdfbaf18ee959e3f7727e2ef90f59f42bc",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>retro-windows</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="retro-windows"><div class="decision-buttons"><button type="button" data-family-id="retro-windows" data-review-status="pass">pass</button><button type="button" data-family-id="retro-windows" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="retro-windows" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="retro-windows">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="retro-windows" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;retro-windows&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;retro-ui-dashboard&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-1" /></div><h2>1. slide-1</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-2" /></div><h2>2. slide-2</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-3" /></div><h2>3. slide-3</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-4.png" alt="slide-4" /></div><h2>4. slide-4</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-5" /></div><h2>5. slide-5</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-6" /></div><h2>6. slide-6</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-7" /></div><h2>7. slide-7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-8.png" alt="slide-8" /></div><h2>8. slide-8</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-8</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-9" /></div><h2>9. slide-9</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-9</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-windows-1.png" alt="slide-10" /></div><h2>10. slide-10</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-10</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/retro-windows.html",
"render_status": "missing_smoke",
"sha256": "847e69a200f8f595339c4816826ed87853faf0a4fc468a6b0672f6f2946cf8a3"
"sha256": "599e3dad5711c9a858067f8ce03036d104d9b8a01cc12c9eef04e7efd5550437"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "847e69a200f8f595339c4816826ed87853faf0a4fc468a6b0672f6f2946cf8a3",
"contact_sheet": "599e3dad5711c9a858067f8ce03036d104d9b8a01cc12c9eef04e7efd5550437",
"fidelity_receipt": "d9f718418fe0cba65d03c26230b5655764011c1197b9b52cb3ab15b0787cd8b6",
"reference_screenshot": "8d9fc0a05ab025310cc35f15c2d3b2de629c79a49df9fe1c7d63b2f7b8a00543",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>retro-zine</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>10</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="retro-zine"><div class="decision-buttons"><button type="button" data-family-id="retro-zine" data-review-status="pass">pass</button><button type="button" data-family-id="retro-zine" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="retro-zine" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="retro-zine">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="retro-zine" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;retro-zine&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;retro-zine-spread&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="hero" /></div><h2>1. hero</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-hero</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="split" /></div><h2>2. split</h2><p>content_split / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-split</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="statement" /></div><h2>3. statement</h2><p>quote_or_emphasis / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-4.png" alt="grid" /></div><h2>4. grid</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-grid</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="visual" /></div><h2>5. visual</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-visual</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="editorial" /></div><h2>6. editorial</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-editorial</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="numbers" /></div><h2>7. numbers</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-numbers</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-8.png" alt="collage" /></div><h2>8. collage</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-collage</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="rsvp" /></div><h2>9. rsvp</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-rsvp</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/retro-zine-1.png" alt="closing" /></div><h2>10. closing</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide-closing</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/retro-zine.html",
"render_status": "missing_smoke",
"sha256": "5328e4b636054dbd363032e7fdb7fea6f0b31eb39d87215ffb4badae2fe02a97"
"sha256": "2461333873da620b3c97e88c9ad80c1814ed28433cbc211c781f4999b1a62833"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "5328e4b636054dbd363032e7fdb7fea6f0b31eb39d87215ffb4badae2fe02a97",
"contact_sheet": "2461333873da620b3c97e88c9ad80c1814ed28433cbc211c781f4999b1a62833",
"fidelity_receipt": "70330ed527a665653b1934d49e3ad5f14e2f4f866de429f38615ca98f18657ba",
"reference_screenshot": "bd93d862d934f00253a36df8f03f4aef74f87fb1b0f870c777002b39ae7f2af9",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>sakura-chroma</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="sakura-chroma"><div class="decision-buttons"><button type="button" data-family-id="sakura-chroma" data-review-status="pass">pass</button><button type="button" data-family-id="sakura-chroma" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="sakura-chroma" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="sakura-chroma">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="sakura-chroma" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;sakura-chroma&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;product-ribbon&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-1.png" alt="manifesto" /></div><h2>2. manifesto</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-manifesto</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-3.png" alt="catalogue" /></div><h2>3. catalogue</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-catalogue</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-4.png" alt="stripe" /></div><h2>4. stripe</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stripe</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-1.png" alt="data" /></div><h2>5. data</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-data</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-1.png" alt="quote" /></div><h2>6. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-1.png" alt="cal" /></div><h2>7. cal</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cal</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/sakura-chroma-1.png" alt="colophon" /></div><h2>8. colophon</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-colophon</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/sakura-chroma.html",
"render_status": "missing_smoke",
"sha256": "2f4e9111d34cafd0344975f49c5a1d13c3ab8732ac520107a9d0f060b0486108"
"sha256": "fd7eb1ddf9e58fcdabc02eb17dd814491227a3ac00a735bfd8b4d7065c482bcf"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "2f4e9111d34cafd0344975f49c5a1d13c3ab8732ac520107a9d0f060b0486108",
"contact_sheet": "fd7eb1ddf9e58fcdabc02eb17dd814491227a3ac00a735bfd8b4d7065c482bcf",
"fidelity_receipt": "01ed753670341664ee282238d30060766dba929200e59bb279b31497ec8af736",
"reference_screenshot": "92bae8fc25051d0dbbb648f931befbfb653cbc331e876ea5e5aaf76afbad0733",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>scatterbrain</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>8</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="scatterbrain"><div class="decision-buttons"><button type="button" data-family-id="scatterbrain" data-review-status="pass">pass</button><button type="button" data-family-id="scatterbrain" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="scatterbrain" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="scatterbrain">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="scatterbrain" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;scatterbrain&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;sticky-workshop-board&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-1.png" alt="slide-1" /></div><h2>1. slide-1</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-1</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-1.png" alt="slide-2" /></div><h2>2. slide-2</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-2</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-1.png" alt="slide-3" /></div><h2>3. slide-3</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-3</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-4.png" alt="slide-4" /></div><h2>4. slide-4</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-4</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-1.png" alt="slide-5" /></div><h2>5. slide-5</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-5</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-1.png" alt="slide-6" /></div><h2>6. slide-6</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-6</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-1.png" alt="slide-7" /></div><h2>7. slide-7</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-7</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/scatterbrain-8.png" alt="slide-8" /></div><h2>8. slide-8</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>data-slide-8</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/scatterbrain.html",
"render_status": "missing_smoke",
"sha256": "4cf01462c6953780cc59a29d83f051278e5315763f9365240abc3138c204eca2"
"sha256": "5a5157baf391062f4ed34e0bde225c820785e216e69b9e7af3d7c460ffdb0c80"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "4cf01462c6953780cc59a29d83f051278e5315763f9365240abc3138c204eca2",
"contact_sheet": "5a5157baf391062f4ed34e0bde225c820785e216e69b9e7af3d7c460ffdb0c80",
"fidelity_receipt": "8f986c32012e5a26fff7d1e4b2c73fb73db59885a7bb3f8ba7fc7f1f0cfd927f",
"reference_screenshot": "c2ed8f8d89fd124c65976fa3ece9b153afe4f4542d95880c367922bb88d910ca",
"smoke_receipt": null,

File diff suppressed because one or more lines are too long

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/signal.html",
"render_status": "missing_smoke",
"sha256": "ab533fc6ac798c710cc537d93a18e247830e183fa813ce2a5ee08a582272c1e1"
"sha256": "c00894a3fff05448914443bf4fec131fcd6ca87b0ed2aabce5a9f239f3e4082a"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "ab533fc6ac798c710cc537d93a18e247830e183fa813ce2a5ee08a582272c1e1",
"contact_sheet": "c00894a3fff05448914443bf4fec131fcd6ca87b0ed2aabce5a9f239f3e4082a",
"fidelity_receipt": "f33e1fed9d3fe80ed000386d4649be14d1120ea455b57d33b8d97a87d2769231",
"reference_screenshot": "ca5487dc68264f209951400c5edddb93c4ae1fc7174b88c2b3dc54a82e0be64a",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>soft-editorial</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>12</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="soft-editorial"><div class="decision-buttons"><button type="button" data-family-id="soft-editorial" data-review-status="pass">pass</button><button type="button" data-family-id="soft-editorial" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="soft-editorial" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="soft-editorial">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="soft-editorial" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;soft-editorial&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;soft-editorial-feature&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="foreword" /></div><h2>2. foreword</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-foreword</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="method" /></div><h2>3. method</h2><p>detail / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-method</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="insights" /></div><h2>4. insights</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-insights</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="closer" /></div><h2>5. closer</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-closer</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-6.png" alt="numbers" /></div><h2>6. numbers</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-numbers</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="next" /></div><h2>8. next</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-next</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="consult" /></div><h2>9. consult</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-consult</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-10.png" alt="chart" /></div><h2>10. chart</h2><p>closing / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="process" /></div><h2>11. process</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-process</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/soft-editorial-4.png" alt="matrix" /></div><h2>12. matrix</h2><p>content / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-matrix</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/soft-editorial.html",
"render_status": "missing_smoke",
"sha256": "64eec701c1883f956200f4c07c18bb893e15272505132a612b554a942026bcee"
"sha256": "f377bd08e444ba86e0ebb24b2b6fb6147a292402479d5854424ad483450e6aa3"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "64eec701c1883f956200f4c07c18bb893e15272505132a612b554a942026bcee",
"contact_sheet": "f377bd08e444ba86e0ebb24b2b6fb6147a292402479d5854424ad483450e6aa3",
"fidelity_receipt": "a7543b7f841153c3dd8d182b0c43d5d3688dc128b4da2f392cb41ee20d275ff3",
"reference_screenshot": "3e37602cf749a0a383ef0f0a1f25db85e9633da1d74bafc2be76a91b004a866b",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>stencil-tablet</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>11</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="stencil-tablet"><div class="decision-buttons"><button type="button" data-family-id="stencil-tablet" data-review-status="pass">pass</button><button type="button" data-family-id="stencil-tablet" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="stencil-tablet" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="stencil-tablet">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="stencil-tablet" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;stencil-tablet&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;stencil-field-manual&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="agenda" /></div><h2>2. agenda</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-agenda</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-3.png" alt="princ" /></div><h2>3. princ</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-princ</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="sec" /></div><h2>4. sec</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-sec</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="consult" /></div><h2>5. consult</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-consult</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="chart" /></div><h2>6. chart</h2><p>process_or_timeline / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="process" /></div><h2>7. process</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-process</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-8.png" alt="matrix" /></div><h2>8. matrix</h2><p>process_or_timeline / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-matrix</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="stats" /></div><h2>9. stats</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="quote" /></div><h2>10. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/stencil-tablet-1.png" alt="cta" /></div><h2>11. cta</h2><p>process_or_timeline / process_or_timeline</p><p><span class="badge bad">missing_smoke</span></p><p><code>s-cta</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/stencil-tablet.html",
"render_status": "missing_smoke",
"sha256": "761d7d2063337a41bb0058766d75ed1d470584c07569ea68930e42ec37d2630a"
"sha256": "ca62bc4d64abeff11aafb248051fe51438501c1f6c3b486a414fc05d1c05c4c8"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "761d7d2063337a41bb0058766d75ed1d470584c07569ea68930e42ec37d2630a",
"contact_sheet": "ca62bc4d64abeff11aafb248051fe51438501c1f6c3b486a414fc05d1c05c4c8",
"fidelity_receipt": "bf32692b17d20d5a20c9c87ac02226c93739131b38f83c7f3b452a14451128fd",
"reference_screenshot": "b8321134113e99f90a0e17e44e326ab25e64f3735150dd82269e0b2daabaaa2b",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>studio</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>12</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="studio"><div class="decision-buttons"><button type="button" data-family-id="studio" data-review-status="pass">pass</button><button type="button" data-family-id="studio" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="studio" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="studio">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="studio" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;studio&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;type-mass-poster&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="chapter" /></div><h2>2. chapter</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="statement" /></div><h2>3. statement</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-4.png" alt="split" /></div><h2>4. split</h2><p>content_split / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--split</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="stats" /></div><h2>5. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="list" /></div><h2>6. list</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--list</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="quote" /></div><h2>7. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-8.png" alt="compare" /></div><h2>8. compare</h2><p>content / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--compare</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="chapter-9" /></div><h2>9. chapter-9</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chapter</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="statement-10" /></div><h2>10. statement-10</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="chart" /></div><h2>11. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/studio-1.png" alt="end" /></div><h2>12. end</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--end</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/studio.html",
"render_status": "missing_smoke",
"sha256": "2e5c78fc922e036219c15f98dc9608883d9013cda1c3e1b0f9f31d5d0bb8bbd6"
"sha256": "d05050e509a7940a4893fbda99624438c1130317d811140d6337fdecb6357b94"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "2e5c78fc922e036219c15f98dc9608883d9013cda1c3e1b0f9f31d5d0bb8bbd6",
"contact_sheet": "d05050e509a7940a4893fbda99624438c1130317d811140d6337fdecb6357b94",
"fidelity_receipt": "95baeec998aed196a738e4491cc7cab3ad34dbca2c3d5e96a94943f62075f60c",
"reference_screenshot": "0d7c0646a85c56b4b26e09f0cf8a0b658fe0b1cf36be38255900fd259d0c42d4",
"smoke_receipt": null,

View File

@@ -19,27 +19,175 @@
h2 { margin: 10px 0 4px; font-size: 15px; }
p { margin: 5px 0; font-size: 12px; color: #536071; }
code { word-break: break-all; font-size: 11px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
.bad { color: #991b1b; background: #fee2e2; }
.review-panel, .review-handoff { background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.decision-template { margin-top: 10px; }
pre, textarea { width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }
pre { overflow: auto; padding: 10px; font-size: 12px; }
textarea { min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>vellum</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>9</strong>source pages</div>
<div class="metric"><strong>blocked</strong>auto gate</div>
<div class="metric"><strong>missing</strong>smoke</div>
<div class="metric"><strong>passed</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
<div class="review-control" data-review-control-for="vellum"><div class="decision-buttons"><button type="button" data-family-id="vellum" data-review-status="pass">pass</button><button type="button" data-family-id="vellum" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="vellum" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="vellum">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="vellum" placeholder="optional apply-script context" /></label><details class="decision-template"><summary>Copyable decision JSON fragment</summary><pre>{
&quot;family_id&quot;: &quot;vellum&quot;,
&quot;human_review_status_before_selection&quot;: &quot;pending&quot;,
&quot;notes&quot;: &quot;&quot;,
&quot;promotion_action&quot;: &quot;no_change_until_human_pass&quot;,
&quot;review_status&quot;: &quot;pass | needs_fix | reject&quot;,
&quot;runtime_template_id&quot;: &quot;vellum-scholar-brief&quot;,
&quot;source_gallery_receipt_path&quot;: &quot;skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json&quot;
}</pre></details></div>
</div>
<p><strong>Known blockers:</strong> auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</p>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<main class="deck">
<section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="cover" /></div><h2>1. cover</h2><p>cover / cover</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--cover</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="statement" /></div><h2>2. statement</h2><p>agenda / agenda</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--statement</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="text" /></div><h2>3. text</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--text</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-4.png" alt="stats" /></div><h2>4. stats</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--stats</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="list" /></div><h2>5. list</h2><p>content / content</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--list</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="quote" /></div><h2>6. quote</h2><p>quote_or_emphasis / quote_or_emphasis</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--quote</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="compare" /></div><h2>7. compare</h2><p>data_dashboard / comparison_or_split</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--compare</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-8.png" alt="chart" /></div><h2>8. chart</h2><p>data_dashboard / data_or_structured</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--chart</code></p></section><section class="page"><div class="thumb"><img src="file:///Users/bytedance/bd-projects/beautiful-html-templates/screenshots/vellum-1.png" alt="end" /></div><h2>9. end</h2><p>closing / closing</p><p><span class="badge bad">missing_smoke</span></p><p><code>slide--end</code></p></section>
</main>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -10,11 +10,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/vellum.html",
"render_status": "missing_smoke",
"sha256": "d1cba07fdba73ba6d0b49076d091f1fba3e299f86f44d1bab7d2c2836b26551f"
"sha256": "ceadac634245686ba842f84a704d927fb688127f0c14b60eece6d7daa3805c10"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "d1cba07fdba73ba6d0b49076d091f1fba3e299f86f44d1bab7d2c2836b26551f",
"contact_sheet": "ceadac634245686ba842f84a704d927fb688127f0c14b60eece6d7daa3805c10",
"fidelity_receipt": "3152f66c029a0f4be72c43d417b2aec470b483239a8070136e5b87993e57ae68",
"reference_screenshot": "8c99c96677fec3c94235098b8fe36b9beeefd31ebfd173989f0ce358d91c4b73",
"smoke_receipt": null,

View File

@@ -12,11 +12,19 @@
.summary { display: flex; gap: 12px; flex-wrap: wrap; margin: 18px 0; }
.metric { background: #fff; border: 1px solid #dbe1ea; border-radius: 8px; padding: 10px 12px; min-width: 150px; }
.metric strong { display: block; font-size: 22px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
table { border-collapse: collapse; width: 100%; background: #fff; border: 1px solid #dbe1ea; }
th, td { border-bottom: 1px solid #e5e9f0; padding: 10px; text-align: left; vertical-align: top; font-size: 13px; }
th { background: #eef2f7; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
code { font-size: 11px; color: #4a5870; word-break: break-all; }
small { color: #65728a; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { width: min(220px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.review-handoff { background: #fff; border: 1px solid #dbe1ea; border-radius: 8px; padding: 14px; margin: 18px 0; max-width: 1180px; }
textarea { width: 100%; min-height: 180px; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
@@ -26,7 +34,7 @@
<body>
<header>
<h1>SVGlide Beautiful Production Review Gallery</h1>
<div class="warning">This gallery is review input only. It is not a promotion receipt and does not change production/default_selectable status.</div>
<div class="warning">This gallery is review input only. It is not a promotion receipt, does not change production/default_selectable status, and does not automatically modify production/default.</div>
<div class="summary">
<div class="metric"><strong>34</strong>candidates</div>
<div class="metric"><strong>1</strong>production + default</div>
@@ -34,6 +42,15 @@
<div class="metric"><strong>{&quot;missing&quot;: 33, &quot;passed&quot;: 1}</strong>smoke status counts</div>
</div>
</header>
<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status=pending</code> <code>promotion_action=no_change_until_human_pass</code></p>
<p>Machine-readable gallery receipt: <code>skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>python &lt;apply-script&gt; --gallery-receipt skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json --decisions &lt;exported-decisions.json&gt;</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
<table>
<thead>
<tr>
@@ -44,45 +61,162 @@
<th>Smoke</th>
<th>Fidelity</th>
<th>Known Blockers</th>
<th>Human Decision</th>
<th>Evidence</th>
</tr>
</thead>
<tbody>
<tr><td><strong><a href="families/8-bit-orbit.html">8-bit-orbit</a></strong><br><small>pixel-orbit-console</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/8-bit-orbit.pixel-orbit-console.json</code><br><code>beautiful-html-templates/screenshots/8-bit-orbit-1.png</code></td></tr>
<tr><td><strong><a href="families/biennale-yellow.html">biennale-yellow</a></strong><br><small>biennale-programme-poster</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/biennale-yellow.biennale-programme-poster.json</code><br><code>beautiful-html-templates/screenshots/biennale-yellow-1.png</code></td></tr>
<tr><td><strong><a href="families/block-frame.html">block-frame</a></strong><br><small>block-frame-grid</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/block-frame.block-frame-grid.json</code><br><code>beautiful-html-templates/screenshots/block-frame-1.png</code></td></tr>
<tr><td><strong><a href="families/blue-professional.html">blue-professional</a></strong><br><small>executive-dashboard</small></td><td>production<br><small>default=true</small></td><td>10 source<br><small>10 implemented</small></td><td><span class="badge ok">passed</span><br><small>human=pending</small></td><td>passed<br><small>10 rendered</small></td><td>passed</td><td>none</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/blue-professional.executive-dashboard.json</code><br><code>beautiful-html-templates/screenshots/blue-professional-1.png</code></td></tr>
<tr><td><strong><a href="families/bold-poster.html">bold-poster</a></strong><br><small>poster-stat-punch</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/bold-poster.poster-stat-punch.json</code><br><code>beautiful-html-templates/screenshots/bold-poster-1.png</code></td></tr>
<tr><td><strong><a href="families/broadside.html">broadside</a></strong><br><small>editorial-quote-chart</small></td><td>needs_review<br><small>default=false</small></td><td>16 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/broadside.editorial-quote-chart.json</code><br><code>beautiful-html-templates/screenshots/broadside-1.png</code></td></tr>
<tr><td><strong><a href="families/capsule.html">capsule</a></strong><br><small>capsule-card-system</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/capsule.capsule-card-system.json</code><br><code>beautiful-html-templates/screenshots/capsule-1.png</code></td></tr>
<tr><td><strong><a href="families/cartesian.html">cartesian</a></strong><br><small>architectural-spec</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/cartesian.architectural-spec.json</code><br><code>beautiful-html-templates/screenshots/cartesian-1.png</code></td></tr>
<tr><td><strong><a href="families/cobalt-grid.html">cobalt-grid</a></strong><br><small>trend-grid-report</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/cobalt-grid.trend-grid-report.json</code><br><code>beautiful-html-templates/screenshots/cobalt-grid-1.png</code></td></tr>
<tr><td><strong><a href="families/coral.html">coral</a></strong><br><small>coral-magazine-feature</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/coral.coral-magazine-feature.json</code><br><code>beautiful-html-templates/screenshots/coral-1.png</code></td></tr>
<tr><td><strong><a href="families/creative-mode.html">creative-mode</a></strong><br><small>creative-mode-grid</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/creative-mode.creative-mode-grid.json</code><br><code>beautiful-html-templates/screenshots/creative-mode-1.png</code></td></tr>
<tr><td><strong><a href="families/daisy-days.html">daisy-days</a></strong><br><small>daisy-workshop-playbook</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/daisy-days.daisy-workshop-playbook.json</code><br><code>beautiful-html-templates/screenshots/daisy-days-1.png</code></td></tr>
<tr><td><strong><a href="families/editorial-forest.html">editorial-forest</a></strong><br><small>serif-stat-editorial</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/editorial-forest.serif-stat-editorial.json</code><br><code>beautiful-html-templates/screenshots/editorial-forest-1.png</code></td></tr>
<tr><td><strong><a href="families/editorial-tri-tone.html">editorial-tri-tone</a></strong><br><small>tritone-editorial-spread</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/editorial-tri-tone.tritone-editorial-spread.json</code><br><code>beautiful-html-templates/screenshots/editorial-tri-tone-1.png</code></td></tr>
<tr><td><strong><a href="families/emerald-editorial.html">emerald-editorial</a></strong><br><small>emerald-editorial-cover</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/emerald-editorial.emerald-editorial-cover.json</code><br><code>beautiful-html-templates/screenshots/emerald-editorial-1.png</code></td></tr>
<tr><td><strong><a href="families/grove.html">grove</a></strong><br><small>grove-organic-brief</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/grove.grove-organic-brief.json</code><br><code>beautiful-html-templates/screenshots/grove-1.png</code></td></tr>
<tr><td><strong><a href="families/long-table.html">long-table</a></strong><br><small>printed-program</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/long-table.printed-program.json</code><br><code>beautiful-html-templates/screenshots/long-table-1.png</code></td></tr>
<tr><td><strong><a href="families/mat.html">mat</a></strong><br><small>mat-midcentury-board</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/mat.mat-midcentury-board.json</code><br><code>beautiful-html-templates/screenshots/mat-1.png</code></td></tr>
<tr><td><strong><a href="families/monochrome.html">monochrome</a></strong><br><small>ledger-briefing</small></td><td>needs_review<br><small>default=false</small></td><td>16 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/monochrome.ledger-briefing.json</code><br><code>beautiful-html-templates/screenshots/monochrome-1.png</code></td></tr>
<tr><td><strong><a href="families/neo-grid-bold.html">neo-grid-bold</a></strong><br><small>dense-panel-grid</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/neo-grid-bold.dense-panel-grid.json</code><br><code>beautiful-html-templates/screenshots/neo-grid-bold-1.png</code></td></tr>
<tr><td><strong><a href="families/peoples-platform.html">peoples-platform</a></strong><br><small>people-platform-manifesto</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/peoples-platform.people-platform-manifesto.json</code><br><code>beautiful-html-templates/screenshots/peoples-platform-1.png</code></td></tr>
<tr><td><strong><a href="families/pin-and-paper.html">pin-and-paper</a></strong><br><small>annotated-field-board</small></td><td>needs_review<br><small>default=false</small></td><td>11 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/pin-and-paper.annotated-field-board.json</code><br><code>beautiful-html-templates/screenshots/pin-and-paper-1.png</code></td></tr>
<tr><td><strong><a href="families/pink-script.html">pink-script</a></strong><br><small>pink-nocturne-feature</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/pink-script.pink-nocturne-feature.json</code><br><code>beautiful-html-templates/screenshots/pink-script-1.png</code></td></tr>
<tr><td><strong><a href="families/playful.html">playful</a></strong><br><small>playful-indie-launch</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/playful.playful-indie-launch.json</code><br><code>beautiful-html-templates/screenshots/playful-1.png</code></td></tr>
<tr><td><strong><a href="families/raw-grid.html">raw-grid</a></strong><br><small>brutalist-matrix</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/raw-grid.brutalist-matrix.json</code><br><code>beautiful-html-templates/screenshots/raw-grid-1.png</code></td></tr>
<tr><td><strong><a href="families/retro-windows.html">retro-windows</a></strong><br><small>retro-ui-dashboard</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/retro-windows.retro-ui-dashboard.json</code><br><code>beautiful-html-templates/screenshots/retro-windows-1.png</code></td></tr>
<tr><td><strong><a href="families/retro-zine.html">retro-zine</a></strong><br><small>retro-zine-spread</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/retro-zine.retro-zine-spread.json</code><br><code>beautiful-html-templates/screenshots/retro-zine-1.png</code></td></tr>
<tr><td><strong><a href="families/sakura-chroma.html">sakura-chroma</a></strong><br><small>product-ribbon</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/sakura-chroma.product-ribbon.json</code><br><code>beautiful-html-templates/screenshots/sakura-chroma-1.png</code></td></tr>
<tr><td><strong><a href="families/scatterbrain.html">scatterbrain</a></strong><br><small>sticky-workshop-board</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/scatterbrain.sticky-workshop-board.json</code><br><code>beautiful-html-templates/screenshots/scatterbrain-1.png</code></td></tr>
<tr><td><strong><a href="families/signal.html">signal</a></strong><br><small>intelligence-brief</small></td><td>needs_review<br><small>default=false</small></td><td>18 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/signal.intelligence-brief.json</code><br><code>beautiful-html-templates/screenshots/signal-1.png</code></td></tr>
<tr><td><strong><a href="families/soft-editorial.html">soft-editorial</a></strong><br><small>soft-editorial-feature</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/soft-editorial.soft-editorial-feature.json</code><br><code>beautiful-html-templates/screenshots/soft-editorial-4.png</code></td></tr>
<tr><td><strong><a href="families/stencil-tablet.html">stencil-tablet</a></strong><br><small>stencil-field-manual</small></td><td>needs_review<br><small>default=false</small></td><td>11 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/stencil-tablet.stencil-field-manual.json</code><br><code>beautiful-html-templates/screenshots/stencil-tablet-1.png</code></td></tr>
<tr><td><strong><a href="families/studio.html">studio</a></strong><br><small>type-mass-poster</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/studio.type-mass-poster.json</code><br><code>beautiful-html-templates/screenshots/studio-1.png</code></td></tr>
<tr><td><strong><a href="families/vellum.html">vellum</a></strong><br><small>vellum-scholar-brief</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human=pending</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><code>skills/lark-slides/references/visual-contracts/beautiful/vellum.vellum-scholar-brief.json</code><br><code>beautiful-html-templates/screenshots/vellum-1.png</code></td></tr>
<tr><td><strong><a href="families/8-bit-orbit.html">8-bit-orbit</a></strong><br><small>pixel-orbit-console</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="8-bit-orbit"><div class="decision-buttons"><button type="button" data-family-id="8-bit-orbit" data-review-status="pass">pass</button><button type="button" data-family-id="8-bit-orbit" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="8-bit-orbit" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="8-bit-orbit">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="8-bit-orbit" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/8-bit-orbit.pixel-orbit-console.json</code><br><code>beautiful-html-templates/screenshots/8-bit-orbit-1.png</code></td></tr>
<tr><td><strong><a href="families/biennale-yellow.html">biennale-yellow</a></strong><br><small>biennale-programme-poster</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="biennale-yellow"><div class="decision-buttons"><button type="button" data-family-id="biennale-yellow" data-review-status="pass">pass</button><button type="button" data-family-id="biennale-yellow" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="biennale-yellow" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="biennale-yellow">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="biennale-yellow" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/biennale-yellow.biennale-programme-poster.json</code><br><code>beautiful-html-templates/screenshots/biennale-yellow-1.png</code></td></tr>
<tr><td><strong><a href="families/block-frame.html">block-frame</a></strong><br><small>block-frame-grid</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="block-frame"><div class="decision-buttons"><button type="button" data-family-id="block-frame" data-review-status="pass">pass</button><button type="button" data-family-id="block-frame" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="block-frame" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="block-frame">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="block-frame" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/block-frame.block-frame-grid.json</code><br><code>beautiful-html-templates/screenshots/block-frame-1.png</code></td></tr>
<tr><td><strong><a href="families/blue-professional.html">blue-professional</a></strong><br><small>executive-dashboard</small></td><td>production<br><small>default=true</small></td><td>10 source<br><small>10 implemented</small></td><td><span class="badge ok">passed</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>passed<br><small>10 rendered</small></td><td>passed</td><td>none</td><td><div class="review-control" data-review-control-for="blue-professional"><div class="decision-buttons"><button type="button" data-family-id="blue-professional" data-review-status="pass">pass</button><button type="button" data-family-id="blue-professional" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="blue-professional" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="blue-professional">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="blue-professional" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/blue-professional.executive-dashboard.json</code><br><code>beautiful-html-templates/screenshots/blue-professional-1.png</code></td></tr>
<tr><td><strong><a href="families/bold-poster.html">bold-poster</a></strong><br><small>poster-stat-punch</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="bold-poster"><div class="decision-buttons"><button type="button" data-family-id="bold-poster" data-review-status="pass">pass</button><button type="button" data-family-id="bold-poster" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="bold-poster" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="bold-poster">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="bold-poster" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/bold-poster.poster-stat-punch.json</code><br><code>beautiful-html-templates/screenshots/bold-poster-1.png</code></td></tr>
<tr><td><strong><a href="families/broadside.html">broadside</a></strong><br><small>editorial-quote-chart</small></td><td>needs_review<br><small>default=false</small></td><td>16 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="broadside"><div class="decision-buttons"><button type="button" data-family-id="broadside" data-review-status="pass">pass</button><button type="button" data-family-id="broadside" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="broadside" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="broadside">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="broadside" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/broadside.editorial-quote-chart.json</code><br><code>beautiful-html-templates/screenshots/broadside-1.png</code></td></tr>
<tr><td><strong><a href="families/capsule.html">capsule</a></strong><br><small>capsule-card-system</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="capsule"><div class="decision-buttons"><button type="button" data-family-id="capsule" data-review-status="pass">pass</button><button type="button" data-family-id="capsule" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="capsule" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="capsule">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="capsule" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/capsule.capsule-card-system.json</code><br><code>beautiful-html-templates/screenshots/capsule-1.png</code></td></tr>
<tr><td><strong><a href="families/cartesian.html">cartesian</a></strong><br><small>architectural-spec</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="cartesian"><div class="decision-buttons"><button type="button" data-family-id="cartesian" data-review-status="pass">pass</button><button type="button" data-family-id="cartesian" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="cartesian" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="cartesian">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="cartesian" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/cartesian.architectural-spec.json</code><br><code>beautiful-html-templates/screenshots/cartesian-1.png</code></td></tr>
<tr><td><strong><a href="families/cobalt-grid.html">cobalt-grid</a></strong><br><small>trend-grid-report</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="cobalt-grid"><div class="decision-buttons"><button type="button" data-family-id="cobalt-grid" data-review-status="pass">pass</button><button type="button" data-family-id="cobalt-grid" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="cobalt-grid" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="cobalt-grid">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="cobalt-grid" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/cobalt-grid.trend-grid-report.json</code><br><code>beautiful-html-templates/screenshots/cobalt-grid-1.png</code></td></tr>
<tr><td><strong><a href="families/coral.html">coral</a></strong><br><small>coral-magazine-feature</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="coral"><div class="decision-buttons"><button type="button" data-family-id="coral" data-review-status="pass">pass</button><button type="button" data-family-id="coral" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="coral" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="coral">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="coral" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/coral.coral-magazine-feature.json</code><br><code>beautiful-html-templates/screenshots/coral-1.png</code></td></tr>
<tr><td><strong><a href="families/creative-mode.html">creative-mode</a></strong><br><small>creative-mode-grid</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="creative-mode"><div class="decision-buttons"><button type="button" data-family-id="creative-mode" data-review-status="pass">pass</button><button type="button" data-family-id="creative-mode" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="creative-mode" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="creative-mode">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="creative-mode" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/creative-mode.creative-mode-grid.json</code><br><code>beautiful-html-templates/screenshots/creative-mode-1.png</code></td></tr>
<tr><td><strong><a href="families/daisy-days.html">daisy-days</a></strong><br><small>daisy-workshop-playbook</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="daisy-days"><div class="decision-buttons"><button type="button" data-family-id="daisy-days" data-review-status="pass">pass</button><button type="button" data-family-id="daisy-days" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="daisy-days" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="daisy-days">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="daisy-days" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/daisy-days.daisy-workshop-playbook.json</code><br><code>beautiful-html-templates/screenshots/daisy-days-1.png</code></td></tr>
<tr><td><strong><a href="families/editorial-forest.html">editorial-forest</a></strong><br><small>serif-stat-editorial</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="editorial-forest"><div class="decision-buttons"><button type="button" data-family-id="editorial-forest" data-review-status="pass">pass</button><button type="button" data-family-id="editorial-forest" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="editorial-forest" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="editorial-forest">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="editorial-forest" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/editorial-forest.serif-stat-editorial.json</code><br><code>beautiful-html-templates/screenshots/editorial-forest-1.png</code></td></tr>
<tr><td><strong><a href="families/editorial-tri-tone.html">editorial-tri-tone</a></strong><br><small>tritone-editorial-spread</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="editorial-tri-tone"><div class="decision-buttons"><button type="button" data-family-id="editorial-tri-tone" data-review-status="pass">pass</button><button type="button" data-family-id="editorial-tri-tone" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="editorial-tri-tone" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="editorial-tri-tone">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="editorial-tri-tone" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/editorial-tri-tone.tritone-editorial-spread.json</code><br><code>beautiful-html-templates/screenshots/editorial-tri-tone-1.png</code></td></tr>
<tr><td><strong><a href="families/emerald-editorial.html">emerald-editorial</a></strong><br><small>emerald-editorial-cover</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="emerald-editorial"><div class="decision-buttons"><button type="button" data-family-id="emerald-editorial" data-review-status="pass">pass</button><button type="button" data-family-id="emerald-editorial" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="emerald-editorial" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="emerald-editorial">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="emerald-editorial" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/emerald-editorial.emerald-editorial-cover.json</code><br><code>beautiful-html-templates/screenshots/emerald-editorial-1.png</code></td></tr>
<tr><td><strong><a href="families/grove.html">grove</a></strong><br><small>grove-organic-brief</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="grove"><div class="decision-buttons"><button type="button" data-family-id="grove" data-review-status="pass">pass</button><button type="button" data-family-id="grove" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="grove" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="grove">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="grove" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/grove.grove-organic-brief.json</code><br><code>beautiful-html-templates/screenshots/grove-1.png</code></td></tr>
<tr><td><strong><a href="families/long-table.html">long-table</a></strong><br><small>printed-program</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="long-table"><div class="decision-buttons"><button type="button" data-family-id="long-table" data-review-status="pass">pass</button><button type="button" data-family-id="long-table" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="long-table" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="long-table">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="long-table" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/long-table.printed-program.json</code><br><code>beautiful-html-templates/screenshots/long-table-1.png</code></td></tr>
<tr><td><strong><a href="families/mat.html">mat</a></strong><br><small>mat-midcentury-board</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="mat"><div class="decision-buttons"><button type="button" data-family-id="mat" data-review-status="pass">pass</button><button type="button" data-family-id="mat" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="mat" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="mat">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="mat" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/mat.mat-midcentury-board.json</code><br><code>beautiful-html-templates/screenshots/mat-1.png</code></td></tr>
<tr><td><strong><a href="families/monochrome.html">monochrome</a></strong><br><small>ledger-briefing</small></td><td>needs_review<br><small>default=false</small></td><td>16 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="monochrome"><div class="decision-buttons"><button type="button" data-family-id="monochrome" data-review-status="pass">pass</button><button type="button" data-family-id="monochrome" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="monochrome" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="monochrome">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="monochrome" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/monochrome.ledger-briefing.json</code><br><code>beautiful-html-templates/screenshots/monochrome-1.png</code></td></tr>
<tr><td><strong><a href="families/neo-grid-bold.html">neo-grid-bold</a></strong><br><small>dense-panel-grid</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="neo-grid-bold"><div class="decision-buttons"><button type="button" data-family-id="neo-grid-bold" data-review-status="pass">pass</button><button type="button" data-family-id="neo-grid-bold" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="neo-grid-bold" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="neo-grid-bold">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="neo-grid-bold" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/neo-grid-bold.dense-panel-grid.json</code><br><code>beautiful-html-templates/screenshots/neo-grid-bold-1.png</code></td></tr>
<tr><td><strong><a href="families/peoples-platform.html">peoples-platform</a></strong><br><small>people-platform-manifesto</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing</td><td><div class="review-control" data-review-control-for="peoples-platform"><div class="decision-buttons"><button type="button" data-family-id="peoples-platform" data-review-status="pass">pass</button><button type="button" data-family-id="peoples-platform" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="peoples-platform" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="peoples-platform">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="peoples-platform" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/peoples-platform.people-platform-manifesto.json</code><br><code>beautiful-html-templates/screenshots/peoples-platform-1.png</code></td></tr>
<tr><td><strong><a href="families/pin-and-paper.html">pin-and-paper</a></strong><br><small>annotated-field-board</small></td><td>needs_review<br><small>default=false</small></td><td>11 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="pin-and-paper"><div class="decision-buttons"><button type="button" data-family-id="pin-and-paper" data-review-status="pass">pass</button><button type="button" data-family-id="pin-and-paper" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="pin-and-paper" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="pin-and-paper">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="pin-and-paper" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/pin-and-paper.annotated-field-board.json</code><br><code>beautiful-html-templates/screenshots/pin-and-paper-1.png</code></td></tr>
<tr><td><strong><a href="families/pink-script.html">pink-script</a></strong><br><small>pink-nocturne-feature</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="pink-script"><div class="decision-buttons"><button type="button" data-family-id="pink-script" data-review-status="pass">pass</button><button type="button" data-family-id="pink-script" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="pink-script" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="pink-script">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="pink-script" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/pink-script.pink-nocturne-feature.json</code><br><code>beautiful-html-templates/screenshots/pink-script-1.png</code></td></tr>
<tr><td><strong><a href="families/playful.html">playful</a></strong><br><small>playful-indie-launch</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="playful"><div class="decision-buttons"><button type="button" data-family-id="playful" data-review-status="pass">pass</button><button type="button" data-family-id="playful" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="playful" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="playful">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="playful" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/playful.playful-indie-launch.json</code><br><code>beautiful-html-templates/screenshots/playful-1.png</code></td></tr>
<tr><td><strong><a href="families/raw-grid.html">raw-grid</a></strong><br><small>brutalist-matrix</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="raw-grid"><div class="decision-buttons"><button type="button" data-family-id="raw-grid" data-review-status="pass">pass</button><button type="button" data-family-id="raw-grid" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="raw-grid" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="raw-grid">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="raw-grid" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/raw-grid.brutalist-matrix.json</code><br><code>beautiful-html-templates/screenshots/raw-grid-1.png</code></td></tr>
<tr><td><strong><a href="families/retro-windows.html">retro-windows</a></strong><br><small>retro-ui-dashboard</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="retro-windows"><div class="decision-buttons"><button type="button" data-family-id="retro-windows" data-review-status="pass">pass</button><button type="button" data-family-id="retro-windows" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="retro-windows" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="retro-windows">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="retro-windows" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/retro-windows.retro-ui-dashboard.json</code><br><code>beautiful-html-templates/screenshots/retro-windows-1.png</code></td></tr>
<tr><td><strong><a href="families/retro-zine.html">retro-zine</a></strong><br><small>retro-zine-spread</small></td><td>needs_review<br><small>default=false</small></td><td>10 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="retro-zine"><div class="decision-buttons"><button type="button" data-family-id="retro-zine" data-review-status="pass">pass</button><button type="button" data-family-id="retro-zine" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="retro-zine" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="retro-zine">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="retro-zine" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/retro-zine.retro-zine-spread.json</code><br><code>beautiful-html-templates/screenshots/retro-zine-1.png</code></td></tr>
<tr><td><strong><a href="families/sakura-chroma.html">sakura-chroma</a></strong><br><small>product-ribbon</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="sakura-chroma"><div class="decision-buttons"><button type="button" data-family-id="sakura-chroma" data-review-status="pass">pass</button><button type="button" data-family-id="sakura-chroma" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="sakura-chroma" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="sakura-chroma">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="sakura-chroma" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/sakura-chroma.product-ribbon.json</code><br><code>beautiful-html-templates/screenshots/sakura-chroma-1.png</code></td></tr>
<tr><td><strong><a href="families/scatterbrain.html">scatterbrain</a></strong><br><small>sticky-workshop-board</small></td><td>needs_review<br><small>default=false</small></td><td>8 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="scatterbrain"><div class="decision-buttons"><button type="button" data-family-id="scatterbrain" data-review-status="pass">pass</button><button type="button" data-family-id="scatterbrain" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="scatterbrain" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="scatterbrain">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="scatterbrain" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/scatterbrain.sticky-workshop-board.json</code><br><code>beautiful-html-templates/screenshots/scatterbrain-1.png</code></td></tr>
<tr><td><strong><a href="families/signal.html">signal</a></strong><br><small>intelligence-brief</small></td><td>needs_review<br><small>default=false</small></td><td>18 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing</td><td><div class="review-control" data-review-control-for="signal"><div class="decision-buttons"><button type="button" data-family-id="signal" data-review-status="pass">pass</button><button type="button" data-family-id="signal" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="signal" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="signal">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="signal" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/signal.intelligence-brief.json</code><br><code>beautiful-html-templates/screenshots/signal-1.png</code></td></tr>
<tr><td><strong><a href="families/soft-editorial.html">soft-editorial</a></strong><br><small>soft-editorial-feature</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="soft-editorial"><div class="decision-buttons"><button type="button" data-family-id="soft-editorial" data-review-status="pass">pass</button><button type="button" data-family-id="soft-editorial" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="soft-editorial" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="soft-editorial">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="soft-editorial" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/soft-editorial.soft-editorial-feature.json</code><br><code>beautiful-html-templates/screenshots/soft-editorial-4.png</code></td></tr>
<tr><td><strong><a href="families/stencil-tablet.html">stencil-tablet</a></strong><br><small>stencil-field-manual</small></td><td>needs_review<br><small>default=false</small></td><td>11 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="stencil-tablet"><div class="decision-buttons"><button type="button" data-family-id="stencil-tablet" data-review-status="pass">pass</button><button type="button" data-family-id="stencil-tablet" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="stencil-tablet" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="stencil-tablet">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="stencil-tablet" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/stencil-tablet.stencil-field-manual.json</code><br><code>beautiful-html-templates/screenshots/stencil-tablet-1.png</code></td></tr>
<tr><td><strong><a href="families/studio.html">studio</a></strong><br><small>type-mass-poster</small></td><td>needs_review<br><small>default=false</small></td><td>12 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="studio"><div class="decision-buttons"><button type="button" data-family-id="studio" data-review-status="pass">pass</button><button type="button" data-family-id="studio" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="studio" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="studio">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="studio" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/studio.type-mass-poster.json</code><br><code>beautiful-html-templates/screenshots/studio-1.png</code></td></tr>
<tr><td><strong><a href="families/vellum.html">vellum</a></strong><br><small>vellum-scholar-brief</small></td><td>needs_review<br><small>default=false</small></td><td>9 source<br><small>0 implemented</small></td><td><span class="badge bad">blocked</span><br><small>human_review_status=pending</small><br><small>promotion_action=no_change_until_human_pass</small></td><td>missing<br><small> rendered</small></td><td>passed</td><td>auto_gate_blocked, missing_smoke, page_family_smoke_missing_or_failed, production_review_pending, quality_gate_integration_pending, selector_gate_missing, source_core_roles_missing</td><td><div class="review-control" data-review-control-for="vellum"><div class="decision-buttons"><button type="button" data-family-id="vellum" data-review-status="pass">pass</button><button type="button" data-family-id="vellum" data-review-status="needs_fix">needs_fix</button><button type="button" data-family-id="vellum" data-review-status="reject">reject</button></div><div class="review-current">Selected: <strong data-review-current-for="vellum">pending</strong></div><label class="notes-label">Notes <input type="text" data-review-notes-for="vellum" placeholder="optional apply-script context" /></label></div></td><td><code>skills/lark-slides/references/visual-contracts/beautiful/vellum.vellum-scholar-brief.json</code><br><code>beautiful-html-templates/screenshots/vellum-1.png</code></td></tr>
</tbody>
</table>
<script>
(function () {
var storageKey = "beautiful-production-review-decisions-v1";
var schemaVersion = "svglide-beautiful-human-review-decisions/v1";
var reviewBatchId = "beautiful-34";
var receiptPath = "skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json";
var pendingHumanReviewStatus = "pending";
var promotionAction = "no_change_until_human_pass";
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
</body>
</html>

View File

@@ -13,11 +13,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/8-bit-orbit.html",
"render_status": "missing_smoke",
"sha256": "86070d51ad2d5f1cef0438e4d5505c160c16f3f5b701a0ef17a950f13f520f19"
"sha256": "6700d6ce17310762eeb43dec97eee6a0c706da5ab7082cdf6c0d0dda83a2453d"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "86070d51ad2d5f1cef0438e4d5505c160c16f3f5b701a0ef17a950f13f520f19",
"contact_sheet": "6700d6ce17310762eeb43dec97eee6a0c706da5ab7082cdf6c0d0dda83a2453d",
"fidelity_receipt": "31bab9cafb1fabb4453980f01a8255d16c9a79e1f882d01585b319dee779d556",
"reference_screenshot": "c1f0517225fbe17807d69de03a7260881738d25bc456bd4151af67fabbb15281",
"smoke_receipt": null,
@@ -1256,11 +1256,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/biennale-yellow.html",
"render_status": "missing_smoke",
"sha256": "d0b40a3bfc2420a4c9c8b4c9baaf3cdf08c204a8e504d0917f1458a9b90e01e8"
"sha256": "1c72a9c2b36088f74069f44fc0226aff8002f0b3507243531da6edf96ae4aff7"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "d0b40a3bfc2420a4c9c8b4c9baaf3cdf08c204a8e504d0917f1458a9b90e01e8",
"contact_sheet": "1c72a9c2b36088f74069f44fc0226aff8002f0b3507243531da6edf96ae4aff7",
"fidelity_receipt": "27b20213513d6a895ae84c07aea6d784f5acd5a5fcd4b5a6baf0d1868f4a7dfe",
"reference_screenshot": "8acd74e991ff533d6982f60fc2934ad2020d5ea8e03c5d79d00c24899d6f9e8d",
"smoke_receipt": null,
@@ -2265,11 +2265,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/block-frame.html",
"render_status": "missing_smoke",
"sha256": "e1eebb164177c32de707e461d85253b10fd4789cddd64ec87f390779f2b69802"
"sha256": "cfd16fda1c5b8104b5e6f3c990b3fc2d2b829f79deaea3dae5cb1157444ea9e6"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "e1eebb164177c32de707e461d85253b10fd4789cddd64ec87f390779f2b69802",
"contact_sheet": "cfd16fda1c5b8104b5e6f3c990b3fc2d2b829f79deaea3dae5cb1157444ea9e6",
"fidelity_receipt": "e35a3eb5441b55568413e926f2275e9593c0b01d95a4345337995c995ffffd95",
"reference_screenshot": "3fd1774d38f1bfbda05df46fc7f2b98a1780de45ced4d71f4925136bbf2460a0",
"smoke_receipt": null,
@@ -3514,11 +3514,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/blue-professional.html",
"render_status": "passed",
"sha256": "28d5646879b9daf6f8841e968e2337c2dceb316feea8bd83ae416ae65f54a7d2"
"sha256": "315b18dd7cd44f6cb18061c82b58a74a54c88ca797b93232011edb322653e51b"
},
"default_selectable": true,
"evidence_hashes": {
"contact_sheet": "28d5646879b9daf6f8841e968e2337c2dceb316feea8bd83ae416ae65f54a7d2",
"contact_sheet": "315b18dd7cd44f6cb18061c82b58a74a54c88ca797b93232011edb322653e51b",
"fidelity_receipt": "f6a4a0a015c09f14cb9e987f69734cbb05a06e79bba9c9b1ba2ca16ed6bc597a",
"reference_screenshot": "0f08aefe70cb14ca7f3126ecc2f34319ca8f281ecdf81c6d6486ea93b2236f8c",
"smoke_receipt": "ae3cfa9a3ba970c0f4d6903148d7291375019dd3d12a8c3619599c5520742804",
@@ -4889,11 +4889,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/bold-poster.html",
"render_status": "missing_smoke",
"sha256": "55b5c1c1fb0a11183ee0779e02f4a374cb989adceb4e3999f754dcf815f2e161"
"sha256": "17a715b8c3cab33d9e80c8abbbd902fa00ae702f63a86ad87fa0bdeb68913433"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "55b5c1c1fb0a11183ee0779e02f4a374cb989adceb4e3999f754dcf815f2e161",
"contact_sheet": "17a715b8c3cab33d9e80c8abbbd902fa00ae702f63a86ad87fa0bdeb68913433",
"fidelity_receipt": "5cb7f128615cbb801b3e66df177a5c1d61b3339c92cba3a04b9db00aadce0635",
"reference_screenshot": "95a9351619463053bda29bdf472702ed4bc650a4510fa6b3cfcc34d5e3ba79b1",
"smoke_receipt": null,
@@ -6102,11 +6102,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/broadside.html",
"render_status": "missing_smoke",
"sha256": "3f823b2d1e5a98af40443c0f04c5180e2d40c0ae8dab5a5b5c81f80494298822"
"sha256": "db1ffb89fb710b18e5e23c50bd04a5c500bea3a9602bc7148def1cd9b712572c"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "3f823b2d1e5a98af40443c0f04c5180e2d40c0ae8dab5a5b5c81f80494298822",
"contact_sheet": "db1ffb89fb710b18e5e23c50bd04a5c500bea3a9602bc7148def1cd9b712572c",
"fidelity_receipt": "fd3c0b8d0ae82ecad0cbeb13974361d5bf8f9e76083619edf5a88d77b0b5f664",
"reference_screenshot": "96805bd67e4502f94b078b723d252717183fe8eb34f2eb529c44b772b4dcdce4",
"smoke_receipt": null,
@@ -7935,11 +7935,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/capsule.html",
"render_status": "missing_smoke",
"sha256": "35b0d6c1d01dd97448bcf50981754d1f0155439b4431efeeaa2b9d4208f7378f"
"sha256": "b89c818def92fdd5638e4d0c343bdfd8a1ae201087c5701f9740e66d21d41636"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "35b0d6c1d01dd97448bcf50981754d1f0155439b4431efeeaa2b9d4208f7378f",
"contact_sheet": "b89c818def92fdd5638e4d0c343bdfd8a1ae201087c5701f9740e66d21d41636",
"fidelity_receipt": "38ef8db0e9fdaf4d3c4f83f3b9ab1a2c956661315784c6090c301faac93f2f8c",
"reference_screenshot": "468b1b618668660274e7a46a528d0a323fb926c3e47f7e5895ec03189efd35b3",
"smoke_receipt": null,
@@ -9162,11 +9162,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/cartesian.html",
"render_status": "missing_smoke",
"sha256": "c1f6795edcce9b5f104edd8f19b1674ceee66b19b905b330f20f1328fde6baa4"
"sha256": "3a68f9f0984b0c0dcd526bfb1bd7deec743e293c739d09529d31ec8dc31c548d"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "c1f6795edcce9b5f104edd8f19b1674ceee66b19b905b330f20f1328fde6baa4",
"contact_sheet": "3a68f9f0984b0c0dcd526bfb1bd7deec743e293c739d09529d31ec8dc31c548d",
"fidelity_receipt": "d7bec45b7684b8ab2e98755e76624fffdf5048fd864aa64d7092aeb6aba3a62d",
"reference_screenshot": "59af0f5ee20b85f07ada82a1d6bb8ab5e69b81bb08b5abf2a7520eca4934e93e",
"smoke_receipt": null,
@@ -10307,11 +10307,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/cobalt-grid.html",
"render_status": "missing_smoke",
"sha256": "f9970bf563b9fc18a08f6617c1a1769cbc8cebd4ec98dcf042c1be12398c8f46"
"sha256": "4fd837a9e9c7fc3da874f451915c9942f7c35b2f179f07986e2523c8fb0e2e9f"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "f9970bf563b9fc18a08f6617c1a1769cbc8cebd4ec98dcf042c1be12398c8f46",
"contact_sheet": "4fd837a9e9c7fc3da874f451915c9942f7c35b2f179f07986e2523c8fb0e2e9f",
"fidelity_receipt": "fd2b394777733364723f20d0d732a346f93edba0a748628ce9a1e5596726cb02",
"reference_screenshot": "e85989914eb7ca3bb279e03cc792df19c5d06f8d3ba0e59515211164fca5ae2d",
"smoke_receipt": null,
@@ -11332,11 +11332,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/coral.html",
"render_status": "missing_smoke",
"sha256": "402b5732bbb22f8145a73ec00176e0653a5f2744245bf10ec9ea757f8b6c1e70"
"sha256": "b47a477b472ff5e219ff685d2fd247587ea389cdbd726d2276ffabbbfebf5403"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "402b5732bbb22f8145a73ec00176e0653a5f2744245bf10ec9ea757f8b6c1e70",
"contact_sheet": "b47a477b472ff5e219ff685d2fd247587ea389cdbd726d2276ffabbbfebf5403",
"fidelity_receipt": "dd795f5b763b8b5769e173a07ba63f2a2da2345fefaf96cb48989b7a5ba4ef2c",
"reference_screenshot": "3cce11542e0c380396c14d2e7ac7406af704af163e7ba85b8ce9e2fdf7d12015",
"smoke_receipt": null,
@@ -12559,11 +12559,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/creative-mode.html",
"render_status": "missing_smoke",
"sha256": "224db100187b471bfeb2b4d38360dc8efa283251be6ebf174da10d74700b080e"
"sha256": "d25bb924c36879bf68e1282a46c1818b201962ec80ad0d845a1b2bef6d5b2292"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "224db100187b471bfeb2b4d38360dc8efa283251be6ebf174da10d74700b080e",
"contact_sheet": "d25bb924c36879bf68e1282a46c1818b201962ec80ad0d845a1b2bef6d5b2292",
"fidelity_receipt": "51de4317d40671c7a4ba0868cacfa3c86ca2de0d14eecb8d07177f6c53506acf",
"reference_screenshot": "aaac87da4e7f0e1e294f8f3d88616b067174687f4b89dafcad0acb4b967e9633",
"smoke_receipt": null,
@@ -13571,11 +13571,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/daisy-days.html",
"render_status": "missing_smoke",
"sha256": "60ae07dae1e5cb86fbefc0ffb62eb9bdf8c371f121793ad9d9e4cee23c993443"
"sha256": "4df7e9d7a65b8e6749d3e487481302defbcfb6d0efd98fc00bb5afc6921e20cc"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "60ae07dae1e5cb86fbefc0ffb62eb9bdf8c371f121793ad9d9e4cee23c993443",
"contact_sheet": "4df7e9d7a65b8e6749d3e487481302defbcfb6d0efd98fc00bb5afc6921e20cc",
"fidelity_receipt": "926bc15a8016d24e25c00a42eb878578dbb825471d6ba2abc316bf48016ab5bc",
"reference_screenshot": "65f6615ff2ec51a3d4a77573c2a53471b356724a58bd33dffdb55ed69ab2b73b",
"smoke_receipt": null,
@@ -14715,11 +14715,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/editorial-forest.html",
"render_status": "missing_smoke",
"sha256": "6966fb4b3014525f5b221bd6ad46a06c7f98b2046882f23d9a96c35876453e30"
"sha256": "a72d3845093b54b819d538e7549951871fe1cb07d991b6eb84b48b2a398c653f"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "6966fb4b3014525f5b221bd6ad46a06c7f98b2046882f23d9a96c35876453e30",
"contact_sheet": "a72d3845093b54b819d538e7549951871fe1cb07d991b6eb84b48b2a398c653f",
"fidelity_receipt": "64abadb7a840271a45d482c1f3a7e8f4e75909ac007ef2c13d4ac0f77c77fdaf",
"reference_screenshot": "a081f3b16a3dd72dd16d9fdfcf30aa61cf66c79c865189eb380d22bd425c2a1c",
"smoke_receipt": null,
@@ -15732,11 +15732,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/editorial-tri-tone.html",
"render_status": "missing_smoke",
"sha256": "ba27daa57e94914e24e341b6a8ae1d7434dfb715f5bc6a54643173865839fb10"
"sha256": "dfa4ea5c54fbd6428d4c98cba1707e4e7a6fa3f11b74dc8879c25305b20ca07f"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "ba27daa57e94914e24e341b6a8ae1d7434dfb715f5bc6a54643173865839fb10",
"contact_sheet": "dfa4ea5c54fbd6428d4c98cba1707e4e7a6fa3f11b74dc8879c25305b20ca07f",
"fidelity_receipt": "5bf44805d7dc674b07da8f0ac8f0a749bfc78893371e921567db82e5bf3a251b",
"reference_screenshot": "0b89022af5bfcc26356b7bdb48156510ba16b643e9bc01027ae8197092ead507",
"smoke_receipt": null,
@@ -16765,11 +16765,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/emerald-editorial.html",
"render_status": "missing_smoke",
"sha256": "e082713ef62b3a90e195a07823726c77e4909aaed1cde7ca7b57b4b888860833"
"sha256": "ae8042a321313b12a03e9b25379c89544421c4a9e8886b08f87990638f02d7da"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "e082713ef62b3a90e195a07823726c77e4909aaed1cde7ca7b57b4b888860833",
"contact_sheet": "ae8042a321313b12a03e9b25379c89544421c4a9e8886b08f87990638f02d7da",
"fidelity_receipt": "7aa06118b44f3dcc6202b56e64ec03134f5487d3e48a25279a9ccfeb09c1c81b",
"reference_screenshot": "fda35bb4c4810369a5c5bccd70cbcd9d474691027c79a0d94ebf59dbf673c150",
"smoke_receipt": null,
@@ -17798,11 +17798,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/grove.html",
"render_status": "missing_smoke",
"sha256": "35333c79ea1ad148e7763b55a6d5886dae6c077cd65c49430a954e69d5997eb7"
"sha256": "da6b1ce28c3ae75ea17159bc4a656369fc659bdbfcff3b953aa9ac3ca4c74e28"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "35333c79ea1ad148e7763b55a6d5886dae6c077cd65c49430a954e69d5997eb7",
"contact_sheet": "da6b1ce28c3ae75ea17159bc4a656369fc659bdbfcff3b953aa9ac3ca4c74e28",
"fidelity_receipt": "72a5d983bb922049b536f086eedb89d0e3a7959b72480aab5fcfce63842d7455",
"reference_screenshot": "6a01598d4b183837b96c698eb9453962fea4bea072a431ee4d71aef6e09da3eb",
"smoke_receipt": null,
@@ -19256,11 +19256,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/long-table.html",
"render_status": "missing_smoke",
"sha256": "03eff66d27ff955a40c9ff4fda6f840251594bcaa9698d1452cc3527118a7317"
"sha256": "451fb96587eb1e8dad65a4e7e34a40c7f81ce178256f9e61f72fb57090c4c61a"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "03eff66d27ff955a40c9ff4fda6f840251594bcaa9698d1452cc3527118a7317",
"contact_sheet": "451fb96587eb1e8dad65a4e7e34a40c7f81ce178256f9e61f72fb57090c4c61a",
"fidelity_receipt": "96948f5547801870efb639d755ee4b944114cd0925c3fd03f6d15cafe935119e",
"reference_screenshot": "79f7956399971a6038c6b98ba7850b8d232c593bafb1c484c7127e5d3fd60bba",
"smoke_receipt": null,
@@ -20277,11 +20277,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/mat.html",
"render_status": "missing_smoke",
"sha256": "80cc3f0b8990075017711519795bc91a6a73eb5e748ec350fcf1dbbec092738f"
"sha256": "45c1a37544d752c06e326d5789a8ad1a51ba2a7926e27db048490526898423b4"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "80cc3f0b8990075017711519795bc91a6a73eb5e748ec350fcf1dbbec092738f",
"contact_sheet": "45c1a37544d752c06e326d5789a8ad1a51ba2a7926e27db048490526898423b4",
"fidelity_receipt": "e1e95e38f4ea8124a378b7de4a0eb81593f192811ea42e7b31085ed84410cf34",
"reference_screenshot": "acac0ac30af8fbb206adfb6810573c72d3ca96b00293f9f850fdeefed1ae11dc",
"smoke_receipt": null,
@@ -21421,11 +21421,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/monochrome.html",
"render_status": "missing_smoke",
"sha256": "98ff05a96dc1ba8c6d1567cdc05e07d956cf6c4d8acb8ff95ec73df343d9e6d7"
"sha256": "3d2584d894dc76b41f1abd78da0a0dba991a1b9cbc6e63672bb9cb45f75418a1"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "98ff05a96dc1ba8c6d1567cdc05e07d956cf6c4d8acb8ff95ec73df343d9e6d7",
"contact_sheet": "3d2584d894dc76b41f1abd78da0a0dba991a1b9cbc6e63672bb9cb45f75418a1",
"fidelity_receipt": "7fd4a1a4f9929a0add47861c0f489f80b3cfe4dd9e91dc13014ec264811c78c5",
"reference_screenshot": "bac6b00bf1d0b3c97b19d2a0c45edf44af5cbf369f2cf3ebe78a207a7b6b8c7b",
"smoke_receipt": null,
@@ -23264,11 +23264,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/neo-grid-bold.html",
"render_status": "missing_smoke",
"sha256": "ceebdd152351e3d9124f365de2ea46b5b03bd90f8ca532d7f99f79bc29cfd95d"
"sha256": "dfdb0c6be0e75f49ecd5d5a782eff136bb25cc679bfbfd17540b9aa47d14356e"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "ceebdd152351e3d9124f365de2ea46b5b03bd90f8ca532d7f99f79bc29cfd95d",
"contact_sheet": "dfdb0c6be0e75f49ecd5d5a782eff136bb25cc679bfbfd17540b9aa47d14356e",
"fidelity_receipt": "9d0ced3d64a642e028edf86ff6457c36def39175b3079fff6a4c97b645803228",
"reference_screenshot": "c53ba5da0f1b85b23ad1975da65edafaee84f029f06c468b2fbd036031ce15e5",
"smoke_receipt": null,
@@ -24692,11 +24692,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/peoples-platform.html",
"render_status": "missing_smoke",
"sha256": "6cde51c31f47436c3b5b6db4fbaccb4181b795fb84213c6a1e0ace77cd88eb66"
"sha256": "35f74a4093000ea952bfbfef2a211fd0d47f6c926ecbc6cb6fc95a07f3946acf"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "6cde51c31f47436c3b5b6db4fbaccb4181b795fb84213c6a1e0ace77cd88eb66",
"contact_sheet": "35f74a4093000ea952bfbfef2a211fd0d47f6c926ecbc6cb6fc95a07f3946acf",
"fidelity_receipt": "679368f5526815a2cb311d583f0f86871000639c85643e6b47099ab91566d5cc",
"reference_screenshot": "9a0c40acaa0fb9c058745cbd16c875f9b7a0417d46c6c37dede388e32cf52d25",
"smoke_receipt": null,
@@ -25918,11 +25918,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/pin-and-paper.html",
"render_status": "missing_smoke",
"sha256": "d3300e5df932d79e82fd0853a9af8c252aa090d1e1df988d77b4d1045ca63002"
"sha256": "063652158d00662045c6a94a70a8e7ae36f00aabf3ea5216463e7f8c6564256a"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "d3300e5df932d79e82fd0853a9af8c252aa090d1e1df988d77b4d1045ca63002",
"contact_sheet": "063652158d00662045c6a94a70a8e7ae36f00aabf3ea5216463e7f8c6564256a",
"fidelity_receipt": "b6aa5696947e5fc7fcd633c340cea26e983956f97a0a54b72eb035818d6a3d76",
"reference_screenshot": "35ff94a10d71d18318fa11e1c95fb6a32e2b1801ffff24ccc8e0f36afe187387",
"smoke_receipt": null,
@@ -27274,11 +27274,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/pink-script.html",
"render_status": "missing_smoke",
"sha256": "b0b78d2776184009efaedb026d3c5dc4528a29f8fba7d7b6c5da4618fbd42497"
"sha256": "be97ade117aa12ee9ffcd562c2e2f905076db7c4ba21ebbc3efa92b4aa0890ae"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "b0b78d2776184009efaedb026d3c5dc4528a29f8fba7d7b6c5da4618fbd42497",
"contact_sheet": "be97ade117aa12ee9ffcd562c2e2f905076db7c4ba21ebbc3efa92b4aa0890ae",
"fidelity_receipt": "ff075c2947f7c09785c47c57f68d995722873676d91251a822747e0b096b88bf",
"reference_screenshot": "d39af58b620fe59ab0e28db0f070fd6e13214896115aa984be069369ef594ff7",
"smoke_receipt": null,
@@ -28400,11 +28400,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/playful.html",
"render_status": "missing_smoke",
"sha256": "8c06c02b5802f957b497d1332e8cb0ab3d3a2c1825f551c946d00c38244aadad"
"sha256": "dce30937bc181379275aeb74ef278b312b7cbceea99f2e2522aaefe6d6f16878"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "8c06c02b5802f957b497d1332e8cb0ab3d3a2c1825f551c946d00c38244aadad",
"contact_sheet": "dce30937bc181379275aeb74ef278b312b7cbceea99f2e2522aaefe6d6f16878",
"fidelity_receipt": "e828f367dda5704dca8c804fb833051e8e3888202e9b76169082ac50164873d8",
"reference_screenshot": "75c22cf0736c2c349599de769e984af4e55440dbf83fb4abac35e5c0842abe81",
"smoke_receipt": null,
@@ -29637,11 +29637,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/raw-grid.html",
"render_status": "missing_smoke",
"sha256": "87221867c254043e20ca653260daa52ccb0f88492fe1fc5595db51edb2d5c87a"
"sha256": "0fc408b566d5f90530b8afb2e380258a3d6013f7ed2089e4b53921eb49d97c57"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "87221867c254043e20ca653260daa52ccb0f88492fe1fc5595db51edb2d5c87a",
"contact_sheet": "0fc408b566d5f90530b8afb2e380258a3d6013f7ed2089e4b53921eb49d97c57",
"fidelity_receipt": "fee9ac2b5c6d69612a2a082849f1829f5b3c75f2a5c2d29b76657361f4fc04cc",
"reference_screenshot": "4056c85b9415ba7a9a988d45f5316cbdfbaf18ee959e3f7727e2ef90f59f42bc",
"smoke_receipt": null,
@@ -30871,11 +30871,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/retro-windows.html",
"render_status": "missing_smoke",
"sha256": "847e69a200f8f595339c4816826ed87853faf0a4fc468a6b0672f6f2946cf8a3"
"sha256": "599e3dad5711c9a858067f8ce03036d104d9b8a01cc12c9eef04e7efd5550437"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "847e69a200f8f595339c4816826ed87853faf0a4fc468a6b0672f6f2946cf8a3",
"contact_sheet": "599e3dad5711c9a858067f8ce03036d104d9b8a01cc12c9eef04e7efd5550437",
"fidelity_receipt": "d9f718418fe0cba65d03c26230b5655764011c1197b9b52cb3ab15b0787cd8b6",
"reference_screenshot": "8d9fc0a05ab025310cc35f15c2d3b2de629c79a49df9fe1c7d63b2f7b8a00543",
"smoke_receipt": null,
@@ -32133,11 +32133,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/retro-zine.html",
"render_status": "missing_smoke",
"sha256": "5328e4b636054dbd363032e7fdb7fea6f0b31eb39d87215ffb4badae2fe02a97"
"sha256": "2461333873da620b3c97e88c9ad80c1814ed28433cbc211c781f4999b1a62833"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "5328e4b636054dbd363032e7fdb7fea6f0b31eb39d87215ffb4badae2fe02a97",
"contact_sheet": "2461333873da620b3c97e88c9ad80c1814ed28433cbc211c781f4999b1a62833",
"fidelity_receipt": "70330ed527a665653b1934d49e3ad5f14e2f4f866de429f38615ca98f18657ba",
"reference_screenshot": "bd93d862d934f00253a36df8f03f4aef74f87fb1b0f870c777002b39ae7f2af9",
"smoke_receipt": null,
@@ -33343,11 +33343,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/sakura-chroma.html",
"render_status": "missing_smoke",
"sha256": "2f4e9111d34cafd0344975f49c5a1d13c3ab8732ac520107a9d0f060b0486108"
"sha256": "fd7eb1ddf9e58fcdabc02eb17dd814491227a3ac00a735bfd8b4d7065c482bcf"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "2f4e9111d34cafd0344975f49c5a1d13c3ab8732ac520107a9d0f060b0486108",
"contact_sheet": "fd7eb1ddf9e58fcdabc02eb17dd814491227a3ac00a735bfd8b4d7065c482bcf",
"fidelity_receipt": "01ed753670341664ee282238d30060766dba929200e59bb279b31497ec8af736",
"reference_screenshot": "92bae8fc25051d0dbbb648f931befbfb653cbc331e876ea5e5aaf76afbad0733",
"smoke_receipt": null,
@@ -34344,11 +34344,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/scatterbrain.html",
"render_status": "missing_smoke",
"sha256": "4cf01462c6953780cc59a29d83f051278e5315763f9365240abc3138c204eca2"
"sha256": "5a5157baf391062f4ed34e0bde225c820785e216e69b9e7af3d7c460ffdb0c80"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "4cf01462c6953780cc59a29d83f051278e5315763f9365240abc3138c204eca2",
"contact_sheet": "5a5157baf391062f4ed34e0bde225c820785e216e69b9e7af3d7c460ffdb0c80",
"fidelity_receipt": "8f986c32012e5a26fff7d1e4b2c73fb73db59885a7bb3f8ba7fc7f1f0cfd927f",
"reference_screenshot": "c2ed8f8d89fd124c65976fa3ece9b153afe4f4542d95880c367922bb88d910ca",
"smoke_receipt": null,
@@ -35389,11 +35389,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/signal.html",
"render_status": "missing_smoke",
"sha256": "ab533fc6ac798c710cc537d93a18e247830e183fa813ce2a5ee08a582272c1e1"
"sha256": "c00894a3fff05448914443bf4fec131fcd6ca87b0ed2aabce5a9f239f3e4082a"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "ab533fc6ac798c710cc537d93a18e247830e183fa813ce2a5ee08a582272c1e1",
"contact_sheet": "c00894a3fff05448914443bf4fec131fcd6ca87b0ed2aabce5a9f239f3e4082a",
"fidelity_receipt": "f33e1fed9d3fe80ed000386d4649be14d1120ea455b57d33b8d97a87d2769231",
"reference_screenshot": "ca5487dc68264f209951400c5edddb93c4ae1fc7174b88c2b3dc54a82e0be64a",
"smoke_receipt": null,
@@ -37437,11 +37437,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/soft-editorial.html",
"render_status": "missing_smoke",
"sha256": "64eec701c1883f956200f4c07c18bb893e15272505132a612b554a942026bcee"
"sha256": "f377bd08e444ba86e0ebb24b2b6fb6147a292402479d5854424ad483450e6aa3"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "64eec701c1883f956200f4c07c18bb893e15272505132a612b554a942026bcee",
"contact_sheet": "f377bd08e444ba86e0ebb24b2b6fb6147a292402479d5854424ad483450e6aa3",
"fidelity_receipt": "a7543b7f841153c3dd8d182b0c43d5d3688dc128b4da2f392cb41ee20d275ff3",
"reference_screenshot": "3e37602cf749a0a383ef0f0a1f25db85e9633da1d74bafc2be76a91b004a866b",
"smoke_receipt": null,
@@ -38856,11 +38856,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/stencil-tablet.html",
"render_status": "missing_smoke",
"sha256": "761d7d2063337a41bb0058766d75ed1d470584c07569ea68930e42ec37d2630a"
"sha256": "ca62bc4d64abeff11aafb248051fe51438501c1f6c3b486a414fc05d1c05c4c8"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "761d7d2063337a41bb0058766d75ed1d470584c07569ea68930e42ec37d2630a",
"contact_sheet": "ca62bc4d64abeff11aafb248051fe51438501c1f6c3b486a414fc05d1c05c4c8",
"fidelity_receipt": "bf32692b17d20d5a20c9c87ac02226c93739131b38f83c7f3b452a14451128fd",
"reference_screenshot": "b8321134113e99f90a0e17e44e326ab25e64f3735150dd82269e0b2daabaaa2b",
"smoke_receipt": null,
@@ -40215,11 +40215,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/studio.html",
"render_status": "missing_smoke",
"sha256": "2e5c78fc922e036219c15f98dc9608883d9013cda1c3e1b0f9f31d5d0bb8bbd6"
"sha256": "d05050e509a7940a4893fbda99624438c1130317d811140d6337fdecb6357b94"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "2e5c78fc922e036219c15f98dc9608883d9013cda1c3e1b0f9f31d5d0bb8bbd6",
"contact_sheet": "d05050e509a7940a4893fbda99624438c1130317d811140d6337fdecb6357b94",
"fidelity_receipt": "95baeec998aed196a738e4491cc7cab3ad34dbca2c3d5e96a94943f62075f60c",
"reference_screenshot": "0d7c0646a85c56b4b26e09f0cf8a0b658fe0b1cf36be38255900fd259d0c42d4",
"smoke_receipt": null,
@@ -41649,11 +41649,11 @@
"artifact_kind": "smoke_deck_contact_sheet_review_model",
"html_path": "families/vellum.html",
"render_status": "missing_smoke",
"sha256": "d1cba07fdba73ba6d0b49076d091f1fba3e299f86f44d1bab7d2c2836b26551f"
"sha256": "ceadac634245686ba842f84a704d927fb688127f0c14b60eece6d7daa3805c10"
},
"default_selectable": false,
"evidence_hashes": {
"contact_sheet": "d1cba07fdba73ba6d0b49076d091f1fba3e299f86f44d1bab7d2c2836b26551f",
"contact_sheet": "ceadac634245686ba842f84a704d927fb688127f0c14b60eece6d7daa3805c10",
"fidelity_receipt": "3152f66c029a0f4be72c43d417b2aec470b483239a8070136e5b87993e57ae68",
"reference_screenshot": "8c99c96677fec3c94235098b8fe36b9beeefd31ebfd173989f0ce358d91c4b73",
"smoke_receipt": null,

View File

@@ -9,7 +9,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "86070d51ad2d5f1cef0438e4d5505c160c16f3f5b701a0ef17a950f13f520f19",
"contact_sheet": "6700d6ce17310762eeb43dec97eee6a0c706da5ab7082cdf6c0d0dda83a2453d",
"fidelity_receipt": "31bab9cafb1fabb4453980f01a8255d16c9a79e1f882d01585b319dee779d556",
"reference_screenshot": "c1f0517225fbe17807d69de03a7260881738d25bc456bd4151af67fabbb15281",
"smoke_receipt": null,
@@ -51,7 +51,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "d0b40a3bfc2420a4c9c8b4c9baaf3cdf08c204a8e504d0917f1458a9b90e01e8",
"contact_sheet": "1c72a9c2b36088f74069f44fc0226aff8002f0b3507243531da6edf96ae4aff7",
"fidelity_receipt": "27b20213513d6a895ae84c07aea6d784f5acd5a5fcd4b5a6baf0d1868f4a7dfe",
"reference_screenshot": "8acd74e991ff533d6982f60fc2934ad2020d5ea8e03c5d79d00c24899d6f9e8d",
"smoke_receipt": null,
@@ -93,7 +93,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "e1eebb164177c32de707e461d85253b10fd4789cddd64ec87f390779f2b69802",
"contact_sheet": "cfd16fda1c5b8104b5e6f3c990b3fc2d2b829f79deaea3dae5cb1157444ea9e6",
"fidelity_receipt": "e35a3eb5441b55568413e926f2275e9593c0b01d95a4345337995c995ffffd95",
"reference_screenshot": "3fd1774d38f1bfbda05df46fc7f2b98a1780de45ced4d71f4925136bbf2460a0",
"smoke_receipt": null,
@@ -135,7 +135,7 @@
],
"auto_gate_status": "passed",
"evidence_hashes": {
"contact_sheet": "28d5646879b9daf6f8841e968e2337c2dceb316feea8bd83ae416ae65f54a7d2",
"contact_sheet": "315b18dd7cd44f6cb18061c82b58a74a54c88ca797b93232011edb322653e51b",
"fidelity_receipt": "f6a4a0a015c09f14cb9e987f69734cbb05a06e79bba9c9b1ba2ca16ed6bc597a",
"reference_screenshot": "0f08aefe70cb14ca7f3126ecc2f34319ca8f281ecdf81c6d6486ea93b2236f8c",
"smoke_receipt": "ae3cfa9a3ba970c0f4d6903148d7291375019dd3d12a8c3619599c5520742804",
@@ -168,7 +168,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "55b5c1c1fb0a11183ee0779e02f4a374cb989adceb4e3999f754dcf815f2e161",
"contact_sheet": "17a715b8c3cab33d9e80c8abbbd902fa00ae702f63a86ad87fa0bdeb68913433",
"fidelity_receipt": "5cb7f128615cbb801b3e66df177a5c1d61b3339c92cba3a04b9db00aadce0635",
"reference_screenshot": "95a9351619463053bda29bdf472702ed4bc650a4510fa6b3cfcc34d5e3ba79b1",
"smoke_receipt": null,
@@ -210,7 +210,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "3f823b2d1e5a98af40443c0f04c5180e2d40c0ae8dab5a5b5c81f80494298822",
"contact_sheet": "db1ffb89fb710b18e5e23c50bd04a5c500bea3a9602bc7148def1cd9b712572c",
"fidelity_receipt": "fd3c0b8d0ae82ecad0cbeb13974361d5bf8f9e76083619edf5a88d77b0b5f664",
"reference_screenshot": "96805bd67e4502f94b078b723d252717183fe8eb34f2eb529c44b772b4dcdce4",
"smoke_receipt": null,
@@ -252,7 +252,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "35b0d6c1d01dd97448bcf50981754d1f0155439b4431efeeaa2b9d4208f7378f",
"contact_sheet": "b89c818def92fdd5638e4d0c343bdfd8a1ae201087c5701f9740e66d21d41636",
"fidelity_receipt": "38ef8db0e9fdaf4d3c4f83f3b9ab1a2c956661315784c6090c301faac93f2f8c",
"reference_screenshot": "468b1b618668660274e7a46a528d0a323fb926c3e47f7e5895ec03189efd35b3",
"smoke_receipt": null,
@@ -294,7 +294,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "c1f6795edcce9b5f104edd8f19b1674ceee66b19b905b330f20f1328fde6baa4",
"contact_sheet": "3a68f9f0984b0c0dcd526bfb1bd7deec743e293c739d09529d31ec8dc31c548d",
"fidelity_receipt": "d7bec45b7684b8ab2e98755e76624fffdf5048fd864aa64d7092aeb6aba3a62d",
"reference_screenshot": "59af0f5ee20b85f07ada82a1d6bb8ab5e69b81bb08b5abf2a7520eca4934e93e",
"smoke_receipt": null,
@@ -336,7 +336,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "f9970bf563b9fc18a08f6617c1a1769cbc8cebd4ec98dcf042c1be12398c8f46",
"contact_sheet": "4fd837a9e9c7fc3da874f451915c9942f7c35b2f179f07986e2523c8fb0e2e9f",
"fidelity_receipt": "fd2b394777733364723f20d0d732a346f93edba0a748628ce9a1e5596726cb02",
"reference_screenshot": "e85989914eb7ca3bb279e03cc792df19c5d06f8d3ba0e59515211164fca5ae2d",
"smoke_receipt": null,
@@ -378,7 +378,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "402b5732bbb22f8145a73ec00176e0653a5f2744245bf10ec9ea757f8b6c1e70",
"contact_sheet": "b47a477b472ff5e219ff685d2fd247587ea389cdbd726d2276ffabbbfebf5403",
"fidelity_receipt": "dd795f5b763b8b5769e173a07ba63f2a2da2345fefaf96cb48989b7a5ba4ef2c",
"reference_screenshot": "3cce11542e0c380396c14d2e7ac7406af704af163e7ba85b8ce9e2fdf7d12015",
"smoke_receipt": null,
@@ -420,7 +420,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "224db100187b471bfeb2b4d38360dc8efa283251be6ebf174da10d74700b080e",
"contact_sheet": "d25bb924c36879bf68e1282a46c1818b201962ec80ad0d845a1b2bef6d5b2292",
"fidelity_receipt": "51de4317d40671c7a4ba0868cacfa3c86ca2de0d14eecb8d07177f6c53506acf",
"reference_screenshot": "aaac87da4e7f0e1e294f8f3d88616b067174687f4b89dafcad0acb4b967e9633",
"smoke_receipt": null,
@@ -462,7 +462,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "60ae07dae1e5cb86fbefc0ffb62eb9bdf8c371f121793ad9d9e4cee23c993443",
"contact_sheet": "4df7e9d7a65b8e6749d3e487481302defbcfb6d0efd98fc00bb5afc6921e20cc",
"fidelity_receipt": "926bc15a8016d24e25c00a42eb878578dbb825471d6ba2abc316bf48016ab5bc",
"reference_screenshot": "65f6615ff2ec51a3d4a77573c2a53471b356724a58bd33dffdb55ed69ab2b73b",
"smoke_receipt": null,
@@ -504,7 +504,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "6966fb4b3014525f5b221bd6ad46a06c7f98b2046882f23d9a96c35876453e30",
"contact_sheet": "a72d3845093b54b819d538e7549951871fe1cb07d991b6eb84b48b2a398c653f",
"fidelity_receipt": "64abadb7a840271a45d482c1f3a7e8f4e75909ac007ef2c13d4ac0f77c77fdaf",
"reference_screenshot": "a081f3b16a3dd72dd16d9fdfcf30aa61cf66c79c865189eb380d22bd425c2a1c",
"smoke_receipt": null,
@@ -546,7 +546,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "ba27daa57e94914e24e341b6a8ae1d7434dfb715f5bc6a54643173865839fb10",
"contact_sheet": "dfa4ea5c54fbd6428d4c98cba1707e4e7a6fa3f11b74dc8879c25305b20ca07f",
"fidelity_receipt": "5bf44805d7dc674b07da8f0ac8f0a749bfc78893371e921567db82e5bf3a251b",
"reference_screenshot": "0b89022af5bfcc26356b7bdb48156510ba16b643e9bc01027ae8197092ead507",
"smoke_receipt": null,
@@ -588,7 +588,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "e082713ef62b3a90e195a07823726c77e4909aaed1cde7ca7b57b4b888860833",
"contact_sheet": "ae8042a321313b12a03e9b25379c89544421c4a9e8886b08f87990638f02d7da",
"fidelity_receipt": "7aa06118b44f3dcc6202b56e64ec03134f5487d3e48a25279a9ccfeb09c1c81b",
"reference_screenshot": "fda35bb4c4810369a5c5bccd70cbcd9d474691027c79a0d94ebf59dbf673c150",
"smoke_receipt": null,
@@ -630,7 +630,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "35333c79ea1ad148e7763b55a6d5886dae6c077cd65c49430a954e69d5997eb7",
"contact_sheet": "da6b1ce28c3ae75ea17159bc4a656369fc659bdbfcff3b953aa9ac3ca4c74e28",
"fidelity_receipt": "72a5d983bb922049b536f086eedb89d0e3a7959b72480aab5fcfce63842d7455",
"reference_screenshot": "6a01598d4b183837b96c698eb9453962fea4bea072a431ee4d71aef6e09da3eb",
"smoke_receipt": null,
@@ -672,7 +672,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "03eff66d27ff955a40c9ff4fda6f840251594bcaa9698d1452cc3527118a7317",
"contact_sheet": "451fb96587eb1e8dad65a4e7e34a40c7f81ce178256f9e61f72fb57090c4c61a",
"fidelity_receipt": "96948f5547801870efb639d755ee4b944114cd0925c3fd03f6d15cafe935119e",
"reference_screenshot": "79f7956399971a6038c6b98ba7850b8d232c593bafb1c484c7127e5d3fd60bba",
"smoke_receipt": null,
@@ -714,7 +714,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "80cc3f0b8990075017711519795bc91a6a73eb5e748ec350fcf1dbbec092738f",
"contact_sheet": "45c1a37544d752c06e326d5789a8ad1a51ba2a7926e27db048490526898423b4",
"fidelity_receipt": "e1e95e38f4ea8124a378b7de4a0eb81593f192811ea42e7b31085ed84410cf34",
"reference_screenshot": "acac0ac30af8fbb206adfb6810573c72d3ca96b00293f9f850fdeefed1ae11dc",
"smoke_receipt": null,
@@ -756,7 +756,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "98ff05a96dc1ba8c6d1567cdc05e07d956cf6c4d8acb8ff95ec73df343d9e6d7",
"contact_sheet": "3d2584d894dc76b41f1abd78da0a0dba991a1b9cbc6e63672bb9cb45f75418a1",
"fidelity_receipt": "7fd4a1a4f9929a0add47861c0f489f80b3cfe4dd9e91dc13014ec264811c78c5",
"reference_screenshot": "bac6b00bf1d0b3c97b19d2a0c45edf44af5cbf369f2cf3ebe78a207a7b6b8c7b",
"smoke_receipt": null,
@@ -798,7 +798,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "ceebdd152351e3d9124f365de2ea46b5b03bd90f8ca532d7f99f79bc29cfd95d",
"contact_sheet": "dfdb0c6be0e75f49ecd5d5a782eff136bb25cc679bfbfd17540b9aa47d14356e",
"fidelity_receipt": "9d0ced3d64a642e028edf86ff6457c36def39175b3079fff6a4c97b645803228",
"reference_screenshot": "c53ba5da0f1b85b23ad1975da65edafaee84f029f06c468b2fbd036031ce15e5",
"smoke_receipt": null,
@@ -840,7 +840,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "6cde51c31f47436c3b5b6db4fbaccb4181b795fb84213c6a1e0ace77cd88eb66",
"contact_sheet": "35f74a4093000ea952bfbfef2a211fd0d47f6c926ecbc6cb6fc95a07f3946acf",
"fidelity_receipt": "679368f5526815a2cb311d583f0f86871000639c85643e6b47099ab91566d5cc",
"reference_screenshot": "9a0c40acaa0fb9c058745cbd16c875f9b7a0417d46c6c37dede388e32cf52d25",
"smoke_receipt": null,
@@ -880,7 +880,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "d3300e5df932d79e82fd0853a9af8c252aa090d1e1df988d77b4d1045ca63002",
"contact_sheet": "063652158d00662045c6a94a70a8e7ae36f00aabf3ea5216463e7f8c6564256a",
"fidelity_receipt": "b6aa5696947e5fc7fcd633c340cea26e983956f97a0a54b72eb035818d6a3d76",
"reference_screenshot": "35ff94a10d71d18318fa11e1c95fb6a32e2b1801ffff24ccc8e0f36afe187387",
"smoke_receipt": null,
@@ -922,7 +922,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "b0b78d2776184009efaedb026d3c5dc4528a29f8fba7d7b6c5da4618fbd42497",
"contact_sheet": "be97ade117aa12ee9ffcd562c2e2f905076db7c4ba21ebbc3efa92b4aa0890ae",
"fidelity_receipt": "ff075c2947f7c09785c47c57f68d995722873676d91251a822747e0b096b88bf",
"reference_screenshot": "d39af58b620fe59ab0e28db0f070fd6e13214896115aa984be069369ef594ff7",
"smoke_receipt": null,
@@ -964,7 +964,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "8c06c02b5802f957b497d1332e8cb0ab3d3a2c1825f551c946d00c38244aadad",
"contact_sheet": "dce30937bc181379275aeb74ef278b312b7cbceea99f2e2522aaefe6d6f16878",
"fidelity_receipt": "e828f367dda5704dca8c804fb833051e8e3888202e9b76169082ac50164873d8",
"reference_screenshot": "75c22cf0736c2c349599de769e984af4e55440dbf83fb4abac35e5c0842abe81",
"smoke_receipt": null,
@@ -1006,7 +1006,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "87221867c254043e20ca653260daa52ccb0f88492fe1fc5595db51edb2d5c87a",
"contact_sheet": "0fc408b566d5f90530b8afb2e380258a3d6013f7ed2089e4b53921eb49d97c57",
"fidelity_receipt": "fee9ac2b5c6d69612a2a082849f1829f5b3c75f2a5c2d29b76657361f4fc04cc",
"reference_screenshot": "4056c85b9415ba7a9a988d45f5316cbdfbaf18ee959e3f7727e2ef90f59f42bc",
"smoke_receipt": null,
@@ -1048,7 +1048,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "847e69a200f8f595339c4816826ed87853faf0a4fc468a6b0672f6f2946cf8a3",
"contact_sheet": "599e3dad5711c9a858067f8ce03036d104d9b8a01cc12c9eef04e7efd5550437",
"fidelity_receipt": "d9f718418fe0cba65d03c26230b5655764011c1197b9b52cb3ab15b0787cd8b6",
"reference_screenshot": "8d9fc0a05ab025310cc35f15c2d3b2de629c79a49df9fe1c7d63b2f7b8a00543",
"smoke_receipt": null,
@@ -1090,7 +1090,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "5328e4b636054dbd363032e7fdb7fea6f0b31eb39d87215ffb4badae2fe02a97",
"contact_sheet": "2461333873da620b3c97e88c9ad80c1814ed28433cbc211c781f4999b1a62833",
"fidelity_receipt": "70330ed527a665653b1934d49e3ad5f14e2f4f866de429f38615ca98f18657ba",
"reference_screenshot": "bd93d862d934f00253a36df8f03f4aef74f87fb1b0f870c777002b39ae7f2af9",
"smoke_receipt": null,
@@ -1132,7 +1132,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "2f4e9111d34cafd0344975f49c5a1d13c3ab8732ac520107a9d0f060b0486108",
"contact_sheet": "fd7eb1ddf9e58fcdabc02eb17dd814491227a3ac00a735bfd8b4d7065c482bcf",
"fidelity_receipt": "01ed753670341664ee282238d30060766dba929200e59bb279b31497ec8af736",
"reference_screenshot": "92bae8fc25051d0dbbb648f931befbfb653cbc331e876ea5e5aaf76afbad0733",
"smoke_receipt": null,
@@ -1174,7 +1174,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "4cf01462c6953780cc59a29d83f051278e5315763f9365240abc3138c204eca2",
"contact_sheet": "5a5157baf391062f4ed34e0bde225c820785e216e69b9e7af3d7c460ffdb0c80",
"fidelity_receipt": "8f986c32012e5a26fff7d1e4b2c73fb73db59885a7bb3f8ba7fc7f1f0cfd927f",
"reference_screenshot": "c2ed8f8d89fd124c65976fa3ece9b153afe4f4542d95880c367922bb88d910ca",
"smoke_receipt": null,
@@ -1216,7 +1216,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "ab533fc6ac798c710cc537d93a18e247830e183fa813ce2a5ee08a582272c1e1",
"contact_sheet": "c00894a3fff05448914443bf4fec131fcd6ca87b0ed2aabce5a9f239f3e4082a",
"fidelity_receipt": "f33e1fed9d3fe80ed000386d4649be14d1120ea455b57d33b8d97a87d2769231",
"reference_screenshot": "ca5487dc68264f209951400c5edddb93c4ae1fc7174b88c2b3dc54a82e0be64a",
"smoke_receipt": null,
@@ -1256,7 +1256,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "64eec701c1883f956200f4c07c18bb893e15272505132a612b554a942026bcee",
"contact_sheet": "f377bd08e444ba86e0ebb24b2b6fb6147a292402479d5854424ad483450e6aa3",
"fidelity_receipt": "a7543b7f841153c3dd8d182b0c43d5d3688dc128b4da2f392cb41ee20d275ff3",
"reference_screenshot": "3e37602cf749a0a383ef0f0a1f25db85e9633da1d74bafc2be76a91b004a866b",
"smoke_receipt": null,
@@ -1298,7 +1298,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "761d7d2063337a41bb0058766d75ed1d470584c07569ea68930e42ec37d2630a",
"contact_sheet": "ca62bc4d64abeff11aafb248051fe51438501c1f6c3b486a414fc05d1c05c4c8",
"fidelity_receipt": "bf32692b17d20d5a20c9c87ac02226c93739131b38f83c7f3b452a14451128fd",
"reference_screenshot": "b8321134113e99f90a0e17e44e326ab25e64f3735150dd82269e0b2daabaaa2b",
"smoke_receipt": null,
@@ -1340,7 +1340,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "2e5c78fc922e036219c15f98dc9608883d9013cda1c3e1b0f9f31d5d0bb8bbd6",
"contact_sheet": "d05050e509a7940a4893fbda99624438c1130317d811140d6337fdecb6357b94",
"fidelity_receipt": "95baeec998aed196a738e4491cc7cab3ad34dbca2c3d5e96a94943f62075f60c",
"reference_screenshot": "0d7c0646a85c56b4b26e09f0cf8a0b658fe0b1cf36be38255900fd259d0c42d4",
"smoke_receipt": null,
@@ -1382,7 +1382,7 @@
],
"auto_gate_status": "blocked",
"evidence_hashes": {
"contact_sheet": "d1cba07fdba73ba6d0b49076d091f1fba3e299f86f44d1bab7d2c2836b26551f",
"contact_sheet": "ceadac634245686ba842f84a704d927fb688127f0c14b60eece6d7daa3805c10",
"fidelity_receipt": "3152f66c029a0f4be72c43d417b2aec470b483239a8070136e5b87993e57ae68",
"reference_screenshot": "8c99c96677fec3c94235098b8fe36b9beeefd31ebfd173989f0ce358d91c4b73",
"smoke_receipt": null,
@@ -1429,7 +1429,7 @@
},
"review_batch_id": "beautiful-34",
"schema_version": "svglide-beautiful-production-review-gallery/v2",
"source_manifest_sha256": "9195c9e2ed8ab146411dcd4a15270500c08b75d85d7047f6307b1b78bfed2e8e",
"source_manifest_sha256": "273dd37eda72bca25176baa9f8f899a201e1a852fe5e8415d0218bc1b3d6cfd1",
"summary": {
"auto_gate_blocked_count": 33,
"auto_gate_passed_count": 1,

View File

@@ -0,0 +1,319 @@
#!/usr/bin/env python3
# Copyright (c) 2026 Lark Technologies Pte. Ltd.
# SPDX-License-Identifier: MIT
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
from typing import Any
SCRIPT_DIR = Path(__file__).resolve().parent
REFERENCES_DIR = SCRIPT_DIR.parent / "references"
MATRIX_PATH = REFERENCES_DIR / "beautiful-template-executable-matrix.json"
DEFAULT_GALLERY_RECEIPT = REFERENCES_DIR / "receipts" / "production-review" / "beautiful-34-gallery.json"
DEFAULT_HUMAN_REVIEW_RECEIPT = REFERENCES_DIR / "receipts" / "production-review" / "beautiful-34-human-review.json"
SCHEMA_VERSION = "svglide-beautiful-human-review/v1"
ALLOWED_HUMAN_STATUS = ["pending", "pass", "needs_fix", "reject"]
ALLOWED_REVIEW_STATUS = set(ALLOWED_HUMAN_STATUS)
def read_json(path: Path) -> dict[str, Any]:
payload = read_json_value(path)
if not isinstance(payload, dict):
raise ValueError(f"expected JSON object: {path}")
return payload
def read_json_value(path: Path) -> Any:
return json.loads(path.read_text(encoding="utf-8"))
def file_sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def _as_list(value: object) -> list[Any]:
return value if isinstance(value, list) else []
def _normalise_decisions(payload: object | None) -> dict[str, dict[str, Any]]:
if not payload:
return {}
raw = payload.get("decisions", payload.get("families", payload)) if isinstance(payload, dict) else payload
decisions: dict[str, dict[str, Any]] = {}
if isinstance(raw, dict):
for family_id, value in raw.items():
if isinstance(value, dict):
decisions[str(family_id)] = value
elif isinstance(raw, list):
for item in raw:
if not isinstance(item, dict) or not item.get("family_id"):
continue
decisions[str(item["family_id"])] = item
return decisions
def _summary_counts(families: list[dict[str, Any]]) -> dict[str, Any]:
counts = {status: 0 for status in ALLOWED_HUMAN_STATUS}
for family in families:
status = str(family.get("human_review_status") or "pending")
counts[status] = counts.get(status, 0) + 1
return {
"family_count": len(families),
"status_counts": counts,
"pending_count": counts.get("pending", 0),
"pass_count": counts.get("pass", 0),
"needs_fix_count": counts.get("needs_fix", 0),
"reject_count": counts.get("reject", 0),
}
def _matrix_status_summary() -> dict[str, Any]:
matrix = read_json(MATRIX_PATH)
rows = [row for row in _as_list(matrix.get("candidates")) if isinstance(row, dict)]
production_default_families = [
str(row.get("family_id"))
for row in rows
if row.get("promotion_status") == "production" and row.get("default_selectable") is True
]
return {
"matrix_candidate_count": len(rows),
"production_count": sum(1 for row in rows if row.get("promotion_status") == "production"),
"default_selectable_count": sum(1 for row in rows if row.get("default_selectable") is True),
"production_default_selectable_count": len(production_default_families),
"production_default_selectable_families": production_default_families,
}
def _gallery_url(base_family: dict[str, Any]) -> object:
if base_family.get("gallery_url"):
return base_family.get("gallery_url")
contact_sheet = base_family.get("contact_sheet")
if isinstance(contact_sheet, dict):
return contact_sheet.get("html_path")
return None
def _review_family(base_family: dict[str, Any], decision: dict[str, Any], *, reviewer: str, reviewed_at: str) -> dict[str, Any]:
status = str(decision.get("human_review_status") or decision.get("status") or base_family.get("human_review_status") or "pending")
note = str(decision.get("human_review_note") or decision.get("note") or "").strip()
issue_codes = [str(item) for item in _as_list(decision.get("issue_codes")) if str(item).strip()]
if status not in ALLOWED_REVIEW_STATUS:
status = "pending"
issue_codes.append("invalid_human_review_status")
validation_issues: list[str] = []
if status in {"needs_fix", "reject"} and not note and not issue_codes:
validation_issues.append("human_review_note_or_issue_codes_required")
auto_gate_status = str(base_family.get("auto_gate_status") or "blocked")
promotion_eligible = auto_gate_status == "passed" and status == "pass"
return {
"family_id": base_family.get("family_id"),
"runtime_template_id": base_family.get("runtime_template_id"),
"gallery_url": _gallery_url(base_family),
"auto_gate_status": auto_gate_status,
"allowed_human_status": ALLOWED_HUMAN_STATUS,
"human_review_status": status,
"human_review_note": note,
"issue_codes": issue_codes,
"reviewer": str(decision.get("reviewer") or reviewer),
"reviewed_at": str(decision.get("reviewed_at") or reviewed_at),
"promotion_eligible": promotion_eligible,
"promotion_action": "candidate_for_m9_production_review" if promotion_eligible else "no_change",
"known_blockers": _as_list(base_family.get("known_blockers")),
"missing_roles": _as_list(base_family.get("missing_roles")),
"evidence_hashes": base_family.get("evidence_hashes") if isinstance(base_family.get("evidence_hashes"), dict) else {},
"validation_issues": validation_issues,
}
def _promotion_candidates(families: list[dict[str, Any]]) -> list[dict[str, Any]]:
return [
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "create_separate_production_review_receipt",
"reason": "auto_gate_status=passed and human_review_status=pass",
"evidence_hashes": family["evidence_hashes"],
}
for family in families
if family["promotion_eligible"]
]
def _fix_queue(families: list[dict[str, Any]]) -> list[dict[str, Any]]:
return [
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "fix_and_resubmit_human_review",
"note": family["human_review_note"],
"issue_codes": family["issue_codes"] or family["known_blockers"],
}
for family in families
if family["human_review_status"] == "needs_fix"
]
def _reject_queue(families: list[dict[str, Any]]) -> list[dict[str, Any]]:
return [
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "keep_out_of_promotion_pool",
"note": family["human_review_note"],
"issue_codes": family["issue_codes"] or family["known_blockers"],
}
for family in families
if family["human_review_status"] == "reject"
]
def _next_actions(families: list[dict[str, Any]]) -> list[dict[str, Any]]:
actions: list[dict[str, Any]] = []
for family in families:
status = family["human_review_status"]
if status == "pending":
actions.append(
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "await_human_review",
"reason": "human_review_status=pending",
}
)
elif status == "pass" and not family["promotion_eligible"]:
actions.append(
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "human_pass_waiting_for_auto_gate",
"reason": f"auto_gate_status={family['auto_gate_status']}",
}
)
elif status == "needs_fix":
actions.append(
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "fix_and_resubmit_human_review",
"reason": family["human_review_note"] or "needs_fix",
}
)
elif status == "reject":
actions.append(
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"action": "keep_out_of_promotion_pool",
"reason": family["human_review_note"] or "reject",
}
)
return actions
def build_human_review_receipt(
*,
gallery_receipt_path: Path = DEFAULT_GALLERY_RECEIPT,
decisions_path: Path | None = None,
reviewer: str = "user",
reviewed_at: str = "pending",
) -> dict[str, Any]:
gallery_receipt = read_json(gallery_receipt_path)
if gallery_receipt.get("not_promotion_receipt") is not True:
raise ValueError("gallery receipt must be marked not_promotion_receipt")
decisions = _normalise_decisions(read_json_value(decisions_path) if decisions_path else None)
families = []
for family in _as_list(gallery_receipt.get("families")):
if not isinstance(family, dict) or not family.get("family_id"):
continue
decision = decisions.get(str(family["family_id"]), {})
families.append(_review_family(family, decision, reviewer=reviewer, reviewed_at=reviewed_at))
promotion_candidates = _promotion_candidates(families)
fix_queue = _fix_queue(families)
reject_queue = _reject_queue(families)
next_actions = _next_actions(families)
invalid_reviews = [
{
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"validation_issues": family["validation_issues"],
}
for family in families
if family["validation_issues"]
]
return {
"schema_version": SCHEMA_VERSION,
"artifact_kind": "human_review_receipt",
"review_batch_id": gallery_receipt.get("review_batch_id"),
"review_surface": "local_html_gallery",
"not_promotion_receipt": True,
"does_not_modify_matrix": True,
"allowed_human_status": ALLOWED_HUMAN_STATUS,
"source_gallery_receipt": str(gallery_receipt_path),
"source_gallery": str(gallery_receipt_path),
"source_gallery_receipt_sha256": file_sha256(gallery_receipt_path),
"source_manifest_sha256": gallery_receipt.get("source_manifest_sha256"),
"summary": {
**_summary_counts(families),
**_matrix_status_summary(),
"promotion_candidates": [item["family_id"] for item in promotion_candidates],
"fix_queue": [item["family_id"] for item in fix_queue],
"reject_queue": [item["family_id"] for item in reject_queue],
"promotion_candidate_count": len(promotion_candidates),
"fix_queue_count": len(fix_queue),
"reject_queue_count": len(reject_queue),
"next_action_count": len(next_actions),
"invalid_review_count": len(invalid_reviews),
},
"policy": {
"human_review_pass_does_not_promote_without_auto_gate": True,
"human_review_pass_does_not_modify_matrix": True,
"apply_does_not_write_matrix": True,
"apply_outputs_candidates_or_next_actions_only": True,
"promotion_requires_separate_production_review_receipt": True,
},
"families": families,
"promotion_candidates": promotion_candidates,
"fix_queue": fix_queue,
"reject_queue": reject_queue,
"next_actions": next_actions,
"invalid_reviews": invalid_reviews,
}
def write_human_review_receipt(receipt: dict[str, Any], output_path: Path = DEFAULT_HUMAN_REVIEW_RECEIPT) -> Path:
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(json.dumps(receipt, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8")
return output_path
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("command", nargs="?", choices=["seed", "apply"], default="seed")
parser.add_argument("--gallery-receipt", "--gallery-source", dest="gallery_receipt", default=str(DEFAULT_GALLERY_RECEIPT))
parser.add_argument("--decisions")
parser.add_argument("--output", default=str(DEFAULT_HUMAN_REVIEW_RECEIPT))
parser.add_argument("--reviewer", default="user")
parser.add_argument("--reviewed-at", default="pending")
parser.add_argument("--stdout", action="store_true")
parser.add_argument("--pretty", action="store_true")
args = parser.parse_args()
receipt = build_human_review_receipt(
gallery_receipt_path=Path(args.gallery_receipt),
decisions_path=Path(args.decisions) if args.decisions else None,
reviewer=args.reviewer,
reviewed_at=args.reviewed_at,
)
if args.stdout:
print(json.dumps(receipt, ensure_ascii=False, indent=2 if args.pretty else None, sort_keys=True))
return 0 if not receipt["invalid_reviews"] else 1
output_path = write_human_review_receipt(receipt, Path(args.output))
print(json.dumps({"output_path": str(output_path), **receipt["summary"]}, ensure_ascii=False, indent=2 if args.pretty else None, sort_keys=True))
return 0 if not receipt["invalid_reviews"] else 1
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,151 @@
#!/usr/bin/env python3
# Copyright (c) 2026 Lark Technologies Pte. Ltd.
# SPDX-License-Identifier: MIT
from __future__ import annotations
import json
import sys
import tempfile
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import beautiful_template_production_review_apply as apply
REFERENCES_DIR = Path(__file__).resolve().parent.parent / "references"
def write_json(path: Path, payload: dict[str, object]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
class BeautifulTemplateProductionReviewApplyTest(unittest.TestCase):
def test_seed_human_review_receipt_contains_34_pending_families(self) -> None:
receipt = apply.build_human_review_receipt()
self.assertEqual("human_review_receipt", receipt["artifact_kind"])
self.assertTrue(receipt["not_promotion_receipt"])
self.assertTrue(receipt["does_not_modify_matrix"])
self.assertEqual("beautiful-34", receipt["review_batch_id"])
self.assertEqual(["pending", "pass", "needs_fix", "reject"], receipt["allowed_human_status"])
self.assertEqual(34, receipt["summary"]["family_count"])
self.assertEqual({"pending": 34, "pass": 0, "needs_fix": 0, "reject": 0}, receipt["summary"]["status_counts"])
self.assertEqual(34, receipt["summary"]["pending_count"])
self.assertEqual(0, receipt["summary"]["promotion_candidate_count"])
self.assertEqual(["blue-professional"], receipt["summary"]["production_default_selectable_families"])
self.assertEqual(34, len(receipt["families"]))
for family in receipt["families"]:
self.assertEqual(["pending", "pass", "needs_fix", "reject"], family["allowed_human_status"])
self.assertEqual("pending", family["human_review_status"])
self.assertEqual("no_change", family["promotion_action"])
self.assertIn("evidence_hashes", family)
def test_can_seed_from_gallery_manifest_contact_sheet_fields(self) -> None:
manifest_path = REFERENCES_DIR / "production-review" / "beautiful" / "manifest.json"
receipt = apply.build_human_review_receipt(gallery_receipt_path=manifest_path)
self.assertEqual(34, receipt["summary"]["family_count"])
blue = next(item for item in receipt["families"] if item["family_id"] == "blue-professional")
self.assertEqual("families/blue-professional.html", blue["gallery_url"])
self.assertEqual("passed", blue["auto_gate_status"])
def test_decisions_route_pass_fix_reject_without_modifying_matrix(self) -> None:
matrix_path = REFERENCES_DIR / "beautiful-template-executable-matrix.json"
before = apply.file_sha256(matrix_path)
with tempfile.TemporaryDirectory() as tmp:
decisions_path = Path(tmp) / "decisions.json"
output_path = Path(tmp) / "human-review.json"
write_json(
decisions_path,
{
"decisions": [
{
"family_id": "blue-professional",
"status": "pass",
"note": "整体可用,继续进入逐套 production review。",
},
{
"family_id": "8-bit-orbit",
"status": "needs_fix",
"note": "缺 page-family smoke数据页需要复刻。",
},
{
"family_id": "bold-poster",
"status": "reject",
"note": "当前不适合默认链路。",
},
]
},
)
receipt = apply.build_human_review_receipt(decisions_path=decisions_path, reviewed_at="2026-06-24T00:00:00+08:00")
apply.write_human_review_receipt(receipt, output_path)
self.assertTrue(output_path.is_file())
after = apply.file_sha256(matrix_path)
self.assertEqual(before, after)
self.assertEqual(1, receipt["summary"]["promotion_candidate_count"])
self.assertEqual(1, receipt["summary"]["fix_queue_count"])
self.assertEqual(1, receipt["summary"]["reject_queue_count"])
self.assertEqual(["blue-professional"], receipt["summary"]["promotion_candidates"])
self.assertEqual(["8-bit-orbit"], receipt["summary"]["fix_queue"])
self.assertEqual(["bold-poster"], receipt["summary"]["reject_queue"])
self.assertEqual(["blue-professional"], [item["family_id"] for item in receipt["promotion_candidates"]])
self.assertEqual(["8-bit-orbit"], [item["family_id"] for item in receipt["fix_queue"]])
self.assertEqual(["bold-poster"], [item["family_id"] for item in receipt["reject_queue"]])
self.assertTrue(receipt["next_actions"])
for item in receipt["promotion_candidates"] + receipt["next_actions"]:
self.assertNotIn("promotion_status", item)
self.assertNotIn("default_selectable", item)
def test_human_pass_on_blocked_family_does_not_create_promotion_candidate(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
decisions_path = Path(tmp) / "decisions.json"
write_json(
decisions_path,
{
"families": {
"8-bit-orbit": {
"human_review_status": "pass",
"human_review_note": "人工觉得好看,但自动门禁仍 blocked。",
}
}
},
)
receipt = apply.build_human_review_receipt(decisions_path=decisions_path)
family = next(item for item in receipt["families"] if item["family_id"] == "8-bit-orbit")
self.assertFalse(family["promotion_eligible"])
self.assertEqual("no_change", family["promotion_action"])
self.assertEqual([], receipt["promotion_candidates"])
self.assertEqual(0, receipt["summary"]["invalid_review_count"])
self.assertIn("human_pass_waiting_for_auto_gate", [item["action"] for item in receipt["next_actions"]])
def test_needs_fix_and_reject_require_note_or_issue_codes(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
decisions_path = Path(tmp) / "decisions.json"
write_json(
decisions_path,
{
"families": {
"8-bit-orbit": {"human_review_status": "needs_fix"},
"bold-poster": {"human_review_status": "reject", "issue_codes": ["visual_quality_low"]},
}
},
)
receipt = apply.build_human_review_receipt(decisions_path=decisions_path)
bad = next(item for item in receipt["families"] if item["family_id"] == "8-bit-orbit")
good = next(item for item in receipt["families"] if item["family_id"] == "bold-poster")
self.assertIn("human_review_note_or_issue_codes_required", bad["validation_issues"])
self.assertEqual([], good["validation_issues"])
if __name__ == "__main__":
unittest.main()

View File

@@ -20,6 +20,11 @@ DEFAULT_OUTPUT_DIR = REFERENCES_DIR / "production-review" / "beautiful"
DEFAULT_RECEIPT_PATH = REFERENCES_DIR / "receipts" / "production-review" / "beautiful-34-gallery.json"
GENERATOR_VERSION = "svglide-beautiful-production-review-gallery/v2"
REVIEW_BATCH_ID = "beautiful-34"
HUMAN_REVIEW_STATUS = "pending"
PROMOTION_ACTION = "no_change_until_human_pass"
REVIEW_STATUSES = ("pass", "needs_fix", "reject")
REVIEW_STORAGE_KEY = "beautiful-production-review-decisions-v1"
REVIEW_DECISIONS_SCHEMA_VERSION = "svglide-beautiful-human-review-decisions/v1"
CORE_REVIEW_ROLES = [
"cover",
@@ -463,9 +468,9 @@ def _family_review(row: dict[str, Any]) -> dict[str, Any]:
"page_family_promotion_gate_status": promotion_gate["status"],
"page_family_promotion_gate": promotion_gate,
"auto_gate_status": auto_gate_status,
"human_review_status": "pending",
"allowed_human_status": ["pass", "needs_fix", "reject"],
"promotion_action": "no_change_until_human_pass",
"human_review_status": HUMAN_REVIEW_STATUS,
"allowed_human_status": list(REVIEW_STATUSES),
"promotion_action": PROMOTION_ACTION,
"evidence_hashes": evidence_hashes,
"contact_sheet": {
"artifact_kind": "smoke_deck_contact_sheet_review_model",
@@ -563,6 +568,189 @@ def _badge(value: object) -> str:
return f'<span class="badge {css}">{text}</span>'
def _review_receipt_relpath() -> str:
return relpath(DEFAULT_RECEIPT_PATH) or DEFAULT_RECEIPT_PATH.as_posix()
def _review_decision_template(family: dict[str, Any]) -> dict[str, Any]:
return {
"family_id": family["family_id"],
"runtime_template_id": family["runtime_template_id"],
"review_status": "pass | needs_fix | reject",
"human_review_status_before_selection": HUMAN_REVIEW_STATUS,
"promotion_action": PROMOTION_ACTION,
"source_gallery_receipt_path": _review_receipt_relpath(),
"notes": "",
}
def _review_controls_html(family: dict[str, Any], *, include_snippet: bool = False) -> str:
family_id = str(family["family_id"])
safe_family_id = html.escape(family_id, quote=True)
buttons = "".join(
f'<button type="button" data-family-id="{safe_family_id}" data-review-status="{html.escape(status, quote=True)}">{html.escape(status)}</button>'
for status in REVIEW_STATUSES
)
snippet = ""
if include_snippet:
template = json.dumps(_review_decision_template(family), ensure_ascii=False, indent=2, sort_keys=True)
snippet = (
'<details class="decision-template">'
"<summary>Copyable decision JSON fragment</summary>"
f"<pre>{html.escape(template)}</pre>"
"</details>"
)
return (
f'<div class="review-control" data-review-control-for="{safe_family_id}">'
f'<div class="decision-buttons">{buttons}</div>'
f'<div class="review-current">Selected: <strong data-review-current-for="{safe_family_id}">pending</strong></div>'
f'<label class="notes-label">Notes <input type="text" data-review-notes-for="{safe_family_id}" placeholder="optional apply-script context" /></label>'
f"{snippet}"
"</div>"
)
def _review_handoff_html() -> str:
receipt_path = _review_receipt_relpath()
command = f"python <apply-script> --gallery-receipt {receipt_path} --decisions <exported-decisions.json>"
return f"""<section class="review-handoff">
<h2>Human Review Export</h2>
<div class="warning">This local UI does not automatically modify production/default. It only stores browser-local decisions and exports JSON for a separate apply script.</div>
<p><code>human_review_status={html.escape(HUMAN_REVIEW_STATUS)}</code> <code>promotion_action={html.escape(PROMOTION_ACTION)}</code></p>
<p>Machine-readable gallery receipt: <code>{html.escape(receipt_path)}</code></p>
<p>Apply script input: save this textarea as decisions JSON, then pass it to the apply script, for example <code>{html.escape(command)}</code>.</p>
<textarea id="review-decisions-json" readonly spellcheck="false"></textarea>
</section>
"""
def _review_script_html() -> str:
receipt_path = _review_receipt_relpath()
return """ <script>
(function () {
var storageKey = %(storage_key)s;
var schemaVersion = %(schema_version)s;
var reviewBatchId = %(review_batch_id)s;
var receiptPath = %(receipt_path)s;
var pendingHumanReviewStatus = %(pending_status)s;
var promotionAction = %(promotion_action)s;
function readState() {
try {
var parsed = JSON.parse(localStorage.getItem(storageKey) || "{}");
if (parsed && typeof parsed === "object" && parsed.decisions && typeof parsed.decisions === "object") {
return parsed;
}
} catch (error) {
// Ignore malformed local state and rebuild below.
}
return { decisions: {} };
}
function writeState(state) {
localStorage.setItem(storageKey, JSON.stringify(state));
}
function buildExport(state) {
var decisions = Object.keys(state.decisions || {}).sort().map(function (familyId) {
return state.decisions[familyId];
});
return {
schema_version: schemaVersion,
artifact_kind: "beautiful_template_human_review_decisions",
review_batch_id: reviewBatchId,
source_gallery_receipt_path: receiptPath,
not_promotion_receipt: true,
policy: {
does_not_automatically_modify_production_default: true,
apply_script_must_validate_gallery_receipt: true
},
decisions: decisions
};
}
function render(state) {
document.querySelectorAll("[data-review-current-for]").forEach(function (node) {
var familyId = node.getAttribute("data-review-current-for");
var decision = state.decisions[familyId];
node.textContent = decision ? decision.review_status : "pending";
});
document.querySelectorAll("[data-review-status]").forEach(function (button) {
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var decision = state.decisions[familyId];
button.classList.toggle("selected", Boolean(decision && decision.review_status === status));
});
document.querySelectorAll("[data-review-notes-for]").forEach(function (input) {
var familyId = input.getAttribute("data-review-notes-for");
var decision = state.decisions[familyId];
if (decision && input.value !== decision.notes) {
input.value = decision.notes || "";
}
});
var textarea = document.getElementById("review-decisions-json");
if (textarea) {
textarea.value = JSON.stringify(buildExport(state), null, 2);
}
}
document.addEventListener("click", function (event) {
var button = event.target.closest("[data-review-status]");
if (!button) {
return;
}
var state = readState();
var familyId = button.getAttribute("data-family-id");
var status = button.getAttribute("data-review-status");
var existing = state.decisions[familyId] || {};
state.decisions[familyId] = {
family_id: familyId,
review_status: status,
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
notes: existing.notes || "",
updated_at: new Date().toISOString()
};
writeState(state);
render(state);
});
document.addEventListener("input", function (event) {
var input = event.target.closest("[data-review-notes-for]");
if (!input) {
return;
}
var state = readState();
var familyId = input.getAttribute("data-review-notes-for");
var existing = state.decisions[familyId] || {
family_id: familyId,
review_status: "needs_fix",
human_review_status_before_selection: pendingHumanReviewStatus,
promotion_action: promotionAction,
source_gallery_receipt_path: receiptPath,
updated_at: new Date().toISOString()
};
existing.notes = input.value;
existing.updated_at = new Date().toISOString();
state.decisions[familyId] = existing;
writeState(state);
render(state);
});
render(readState());
})();
</script>
""" % {
"storage_key": json.dumps(REVIEW_STORAGE_KEY),
"schema_version": json.dumps(REVIEW_DECISIONS_SCHEMA_VERSION),
"review_batch_id": json.dumps(REVIEW_BATCH_ID),
"receipt_path": json.dumps(receipt_path),
"pending_status": json.dumps(HUMAN_REVIEW_STATUS),
"promotion_action": json.dumps(PROMOTION_ACTION),
}
def _render_family_html(family: dict[str, Any]) -> str:
pages = []
for page in family["pages"]:
@@ -601,28 +789,45 @@ def _render_family_html(family: dict[str, Any]) -> str:
h2 {{ margin: 10px 0 4px; font-size: 15px; }}
p {{ margin: 5px 0; font-size: 12px; color: #536071; }}
code {{ word-break: break-all; font-size: 11px; }}
button {{ cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }}
button.selected {{ border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }}
.badge {{ display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }}
.ok {{ color: #065f46; background: #d1fae5; }}
.warn {{ color: #92400e; background: #fef3c7; }}
.bad {{ color: #991b1b; background: #fee2e2; }}
.review-panel, .review-handoff {{ background: #fff; border: 1px solid #dfe5ee; border-radius: 8px; padding: 14px; margin: 16px 0; }}
.decision-buttons {{ display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }}
.review-current {{ font-size: 12px; color: #536071; margin-bottom: 8px; }}
.notes-label {{ display: block; color: #536071; font-size: 12px; }}
.notes-label input {{ margin-left: 8px; min-width: min(520px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }}
.decision-template {{ margin-top: 10px; }}
pre, textarea {{ width: 100%; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; }}
pre {{ overflow: auto; padding: 10px; font-size: 12px; }}
textarea {{ min-height: 180px; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }}
</style>
</head>
<body>
<header>
<p><a href="../index.html">Back to gallery</a></p>
<h1>{html.escape(family['family_id'])}</h1>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt.</div>
<div class="warning">Review input only. This contact sheet is not a production promotion receipt and does not automatically modify production/default.</div>
<div class="meta">
<div class="metric"><strong>{html.escape(str(family['page_variant_count']))}</strong>source pages</div>
<div class="metric"><strong>{html.escape(str(family['auto_gate_status']))}</strong>auto gate</div>
<div class="metric"><strong>{html.escape(str(family['smoke_status']))}</strong>smoke</div>
<div class="metric"><strong>{html.escape(str(family['fidelity_status']))}</strong>fidelity</div>
</div>
<div class="review-panel">
<h2>Human decision</h2>
{_review_controls_html(family, include_snippet=True)}
</div>
<p><strong>Known blockers:</strong> {html.escape(blockers)}</p>
</header>
{_review_handoff_html()}
<main class="deck">
{"".join(pages)}
</main>
{_review_script_html()}
</body>
</html>
"""
@@ -639,10 +844,11 @@ def _render_html(manifest: dict[str, Any]) -> str:
f"<td><strong><a href=\"{html.escape(contact)}\">{html.escape(family['family_id'])}</a></strong><br><small>{html.escape(family['runtime_template_id'])}</small></td>"
f"<td>{html.escape(str(family['promotion_status']))}<br><small>default={html.escape(str(family['default_selectable']).lower())}</small></td>"
f"<td>{family['page_variant_count']} source<br><small>{family['implemented_page_variant_count']} implemented</small></td>"
f"<td>{_badge(family['auto_gate_status'])}<br><small>human={html.escape(str(family['human_review_status']))}</small></td>"
f"<td>{_badge(family['auto_gate_status'])}<br><small>human_review_status={html.escape(str(family['human_review_status']))}</small><br><small>promotion_action={html.escape(str(family['promotion_action']))}</small></td>"
f"<td>{html.escape(str(family['smoke_status']))}<br><small>{html.escape(str(family['smoke'].get('rendered_pages') or ''))} rendered</small></td>"
f"<td>{html.escape(str(family['fidelity_status']))}</td>"
f"<td>{html.escape(blocker_text)}</td>"
f"<td>{_review_controls_html(family)}</td>"
f"<td><code>{html.escape(str(family['visual_contract_path']))}</code><br><code>{html.escape(str(family['reference_screenshot']))}</code></td>"
"</tr>"
)
@@ -660,11 +866,19 @@ def _render_html(manifest: dict[str, Any]) -> str:
.summary { display: flex; gap: 12px; flex-wrap: wrap; margin: 18px 0; }
.metric { background: #fff; border: 1px solid #dbe1ea; border-radius: 8px; padding: 10px 12px; min-width: 150px; }
.metric strong { display: block; font-size: 22px; }
button { cursor: pointer; border: 1px solid #b8c2d2; background: #fff; color: #172033; border-radius: 6px; padding: 6px 9px; font-weight: 700; }
button.selected { border-color: #1d4ed8; background: #dbeafe; color: #1e3a8a; }
table { border-collapse: collapse; width: 100%%; background: #fff; border: 1px solid #dbe1ea; }
th, td { border-bottom: 1px solid #e5e9f0; padding: 10px; text-align: left; vertical-align: top; font-size: 13px; }
th { background: #eef2f7; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
code { font-size: 11px; color: #4a5870; word-break: break-all; }
small { color: #65728a; }
.decision-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.review-current { font-size: 12px; color: #536071; margin-bottom: 8px; }
.notes-label { display: block; color: #536071; font-size: 12px; }
.notes-label input { width: min(220px, 80vw); padding: 6px 8px; border: 1px solid #c7d0df; border-radius: 6px; }
.review-handoff { background: #fff; border: 1px solid #dbe1ea; border-radius: 8px; padding: 14px; margin: 18px 0; max-width: 1180px; }
textarea { width: 100%%; min-height: 180px; box-sizing: border-box; border: 1px solid #c7d0df; border-radius: 6px; background: #f8fafc; color: #172033; padding: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.badge { display: inline-block; border-radius: 999px; padding: 2px 7px; font-size: 11px; font-weight: 700; }
.ok { color: #065f46; background: #d1fae5; }
.warn { color: #92400e; background: #fef3c7; }
@@ -674,7 +888,7 @@ def _render_html(manifest: dict[str, Any]) -> str:
<body>
<header>
<h1>SVGlide Beautiful Production Review Gallery</h1>
<div class="warning">This gallery is review input only. It is not a promotion receipt and does not change production/default_selectable status.</div>
<div class="warning">This gallery is review input only. It is not a promotion receipt, does not change production/default_selectable status, and does not automatically modify production/default.</div>
<div class="summary">
<div class="metric"><strong>%(candidate_count)s</strong>candidates</div>
<div class="metric"><strong>%(production_default)s</strong>production + default</div>
@@ -682,6 +896,7 @@ def _render_html(manifest: dict[str, Any]) -> str:
<div class="metric"><strong>%(smoke_counts)s</strong>smoke status counts</div>
</div>
</header>
%(handoff)s
<table>
<thead>
<tr>
@@ -692,6 +907,7 @@ def _render_html(manifest: dict[str, Any]) -> str:
<th>Smoke</th>
<th>Fidelity</th>
<th>Known Blockers</th>
<th>Human Decision</th>
<th>Evidence</th>
</tr>
</thead>
@@ -699,6 +915,7 @@ def _render_html(manifest: dict[str, Any]) -> str:
%(rows)s
</tbody>
</table>
%(script)s
</body>
</html>
""" % {
@@ -706,7 +923,9 @@ def _render_html(manifest: dict[str, Any]) -> str:
"production_default": html.escape(str(summary["production_default_selectable_count"])),
"auto_passed": html.escape(str(summary["auto_gate_passed_count"])),
"smoke_counts": html.escape(json.dumps(summary["smoke_status_counts"], sort_keys=True)),
"handoff": _review_handoff_html(),
"rows": "\n".join(rows),
"script": _review_script_html(),
}
@@ -743,12 +962,33 @@ def write_gallery_artifacts(output_dir: Path = DEFAULT_OUTPUT_DIR, receipt_path:
}
def write_gallery_html_artifacts(output_dir: Path = DEFAULT_OUTPUT_DIR) -> dict[str, Any]:
output_dir.mkdir(parents=True, exist_ok=True)
families_dir = output_dir / "families"
families_dir.mkdir(parents=True, exist_ok=True)
manifest = build_gallery_manifest()
for family in manifest["families"]:
family_html_path = families_dir / f"{family['family_id']}.html"
family_html_path.write_text(_render_family_html(family), encoding="utf-8")
html_path = output_dir / "index.html"
html_path.write_text(_render_html(manifest), encoding="utf-8")
return {
"html_path": str(html_path),
"family_html_count": len(manifest["families"]),
"candidate_count": manifest["summary"]["candidate_count"],
"production_default_selectable_count": manifest["summary"]["production_default_selectable_count"],
"default_selectable_count": manifest["summary"]["default_selectable_count"],
"auto_gate_passed_count": manifest["summary"]["auto_gate_passed_count"],
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--output-dir", default=str(DEFAULT_OUTPUT_DIR))
parser.add_argument("--receipt-path", default=str(DEFAULT_RECEIPT_PATH))
parser.add_argument("--stdout", action="store_true", help="print manifest only and do not write artifacts")
parser.add_argument("--receipt-stdout", action="store_true", help="print gallery receipt only and do not write artifacts")
parser.add_argument("--html-only", action="store_true", help="write index/family HTML only and leave manifest/receipt JSON unchanged")
parser.add_argument("--pretty", action="store_true")
args = parser.parse_args()
if args.stdout:
@@ -759,6 +999,10 @@ def main() -> int:
receipt = build_gallery_receipt()
print(json.dumps(receipt, ensure_ascii=False, indent=2 if args.pretty else None, sort_keys=True))
return 0
if args.html_only:
result = write_gallery_html_artifacts(Path(args.output_dir))
print(json.dumps(result, ensure_ascii=False, indent=2 if args.pretty else None, sort_keys=True))
return 0
result = write_gallery_artifacts(Path(args.output_dir), Path(args.receipt_path))
print(json.dumps(result, ensure_ascii=False, indent=2 if args.pretty else None, sort_keys=True))
return 0

View File

@@ -104,7 +104,7 @@ class BeautifulTemplateProductionReviewGalleryTest(unittest.TestCase):
def test_write_artifacts_keeps_production_default_counts_unchanged(self) -> None:
before = gallery.matrix_status_counts()
with tempfile.TemporaryDirectory() as tmpdir:
result = gallery.write_gallery_artifacts(Path(tmpdir))
result = gallery.write_gallery_artifacts(Path(tmpdir), Path(tmpdir) / "receipt.json")
manifest_path = Path(result["manifest_path"])
html_path = Path(result["html_path"])
@@ -119,6 +119,26 @@ class BeautifulTemplateProductionReviewGalleryTest(unittest.TestCase):
self.assertEqual(34, manifest["summary"]["candidate_count"])
self.assertTrue(manifest["not_promotion_receipt"])
def test_rendered_html_is_human_review_entrypoint_not_promotion_action(self) -> None:
with tempfile.TemporaryDirectory() as tmpdir:
result = gallery.write_gallery_artifacts(Path(tmpdir), Path(tmpdir) / "receipt.json")
output_dir = Path(tmpdir)
index_html = Path(result["html_path"]).read_text(encoding="utf-8")
family_html = (output_dir / "families" / "blue-professional.html").read_text(encoding="utf-8")
for page_html in (index_html, family_html):
self.assertIn('data-review-status="pass"', page_html)
self.assertIn('data-review-status="needs_fix"', page_html)
self.assertIn('data-review-status="reject"', page_html)
self.assertIn("human_review_status=pending", page_html)
self.assertIn("promotion_action=no_change_until_human_pass", page_html)
self.assertIn("beautiful-production-review-decisions-v1", page_html)
self.assertIn("review-decisions-json", page_html)
self.assertIn("does not automatically modify production/default", page_html)
self.assertIn("skills/lark-slides/references/receipts/production-review/beautiful-34-gallery.json", page_html)
self.assertIn("apply script", page_html)
if __name__ == "__main__":
unittest.main()