[object Object]

← back to Marketing Command Center

make Quick Post music honest and verify publish safety

cecb80913203db1b5f51520e10058a4ec1dbd26a · 2026-09-01 17:27:44 -0700 · Steve Abrams

Files touched

Diff

commit cecb80913203db1b5f51520e10058a4ec1dbd26a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Sep 1 17:27:44 2026 -0700

    make Quick Post music honest and verify publish safety
---
 cta/CTA-REPORT.md                        |   4 +-
 modules/channels/index.js                |  14 ++-
 modules/sounds/index.js                  |  10 ++
 public/panels/quickpost.html             |   5 +-
 public/panels/quickpost.js               |   9 +-
 public/quickpost-music/bright-reveal.mp3 | Bin 0 -> 48484 bytes
 public/quickpost-music/quiet-texture.mp3 | Bin 0 -> 48432 bytes
 public/quickpost-music/soft-showroom.mp3 | Bin 0 -> 48432 bytes
 screenrecord/quickpost/DEBUG-REPORT.md   |  12 +--
 screenrecord/quickpost/debug-log.jsonl   | 164 +++++++++++++++++++++++++++++++
 verification/e2e-proof.json              |  21 +++-
 11 files changed, 220 insertions(+), 19 deletions(-)

diff --git a/cta/CTA-REPORT.md b/cta/CTA-REPORT.md
index 42f3180..13d9444 100644
--- a/cta/CTA-REPORT.md
+++ b/cta/CTA-REPORT.md
@@ -6,8 +6,8 @@
 
 ## Browser coverage
 
-- Chrome/Chromium recording: /Users/macstudio3/Projects/marketing-command-center/cta/rec/chrome/page@b850246c556f15e3fe87527c45a3cbd5.webm
-- Safari/WebKit recording: /Users/macstudio3/Projects/marketing-command-center/cta/rec/safari/page@cb210151101c15b36d5a33d5125e1dbf.webm
+- Chrome/Chromium recording: /Users/macstudio3/Projects/marketing-command-center/cta/rec/chrome/page@a6113ea0f1e029989241a83215ff5b47.webm
+- Safari/WebKit recording: /Users/macstudio3/Projects/marketing-command-center/cta/rec/safari/page@43bc047c198f656c0901882d3062b2a4.webm
 - Browserbase: skipped by design because the target is localhost and Browserbase cannot reach the Mac-local service.
 
 ## Components
diff --git a/modules/channels/index.js b/modules/channels/index.js
index 2f01123..3942539 100644
--- a/modules/channels/index.js
+++ b/modules/channels/index.js
@@ -1029,7 +1029,13 @@ module.exports = {
         const FORMATS = ['post', 'reel', 'story', 'carousel'];
         const format = FORMATS.includes(String(d.format)) ? String(d.format) : 'post';
         const song = (d.song && d.song.url && /^https?:\/\//i.test(d.song.url))
-          ? { name: String(d.song.name || 'Track').slice(0, 200), url: String(d.song.url).slice(0, 800) } : undefined;
+          ? {
+              name: String(d.song.name || 'Track').slice(0, 200),
+              url: String(d.song.url).slice(0, 800),
+              license: String(d.song.license || '').slice(0, 200) || undefined,
+              duration: String(d.song.duration || '').slice(0, 20) || undefined,
+              suggestionOnly: true,
+            } : undefined;
         const content = { caption: (d.caption || '').slice(0, 2200), mediaUrl: d.mediaUrl || '', videoUrl: d.videoUrl || '' };
         if (!channels.length) return res.status(400).json({ error: 'no channels selected' });
         if (!content.caption && !content.mediaUrl) return res.status(400).json({ error: 'empty post' });
@@ -1044,6 +1050,12 @@ module.exports = {
         // mutating the outbox. Unlike dryRun (which intentionally stages a
         // draft for the UI), inspectOnly is a true no-write probe.
         const inspectOnly = d.inspectOnly === true;
+        // Reject a live-shaped request that lacks the explicit confirmation.
+        // This is both clearer than silently staging it and a server-side safety
+        // boundary if a client ever bypasses the disabled button.
+        if (d.dryRun === false && d.confirm !== true) {
+          return res.status(400).json({ error: 'Live posting requires explicit confirmation.' });
+        }
         const isVideo = !!content.videoUrl;
         const isImage = !!content.mediaUrl && !content.videoUrl;
         // Why a channel can't actually post right now (null = clear to fire).
diff --git a/modules/sounds/index.js b/modules/sounds/index.js
index b519660..7a7a1f0 100644
--- a/modules/sounds/index.js
+++ b/modules/sounds/index.js
@@ -10,6 +10,16 @@
 // Library or true royalty-free libraries can.
 
 const CATALOG = [
+  {
+    id: 'dw-originals',
+    title: 'DW original preview tracks',
+    blurb: 'Short, playable music suggestions made for DW. Preview here; the final social app decides whether music can be attached automatically.',
+    items: [
+      { name: 'Soft Showroom', url: '/quickpost-music/soft-showroom.mp3', previewUrl: '/quickpost-music/soft-showroom.mp3', badge: 'brandsafe', license: 'DW original — commercial use approved', duration: '0:12', platforms: ['instagram','facebook','tiktok','youtube'], note: 'Calm, polished background idea for room reveals.' },
+      { name: 'Bright Reveal', url: '/quickpost-music/bright-reveal.mp3', previewUrl: '/quickpost-music/bright-reveal.mp3', badge: 'brandsafe', license: 'DW original — commercial use approved', duration: '0:12', platforms: ['instagram','facebook','tiktok','youtube'], note: 'Light, upbeat background idea for product reveals.' },
+      { name: 'Quiet Texture', url: '/quickpost-music/quiet-texture.mp3', previewUrl: '/quickpost-music/quiet-texture.mp3', badge: 'brandsafe', license: 'DW original — commercial use approved', duration: '0:12', platforms: ['instagram','facebook','tiktok','youtube'], note: 'Slow ambient background idea for close-up texture shots.' },
+    ],
+  },
   {
     id: 'tiktok',
     title: 'TikTok assets',
diff --git a/public/panels/quickpost.html b/public/panels/quickpost.html
index 826f179..dcb2d5d 100644
--- a/public/panels/quickpost.html
+++ b/public/panels/quickpost.html
@@ -14,7 +14,7 @@
       <details class="kp-more"><summary>Paste a picture link instead</summary><input id="kp-media" type="url" placeholder="https://…/picture.jpg" autocomplete="off"></details>
     </section>
     <section class="kp-pane" data-step="2" hidden>
-      <div class="kp-number">2</div><div class="kp-copy"><h3>Add music?</h3><p>Music is optional. Choose a song, or choose “No music.”</p></div><div id="kp-music" class="kp-choices"><div class="kp-wait">Loading music choices…</div></div>
+      <div class="kp-number">2</div><div class="kp-copy"><h3>Pick a music idea?</h3><p>Music is optional. Listen first, then pick a suggestion or choose “No music.” The social app may ask you to add it there.</p></div><div id="kp-music" class="kp-choices"><div class="kp-wait">Loading music choices…</div></div>
     </section>
     <section class="kp-pane" data-step="3" hidden>
       <div class="kp-number">3</div><div class="kp-copy"><h3>Choose the words</h3><p>Tell us the idea. We will suggest three captions you can use or change.</p></div>
@@ -28,7 +28,7 @@
     </section>
     <section class="kp-pane" data-step="5" hidden>
       <div class="kp-number">5</div><div class="kp-copy"><h3>Check everything</h3><p>Look it over. Nothing posts until you say yes.</p></div><div id="kp-review" class="kp-review"></div>
-      <label class="kp-confirm"><input id="kp-confirm" type="checkbox"><span>I checked the picture, words, music, and accounts. I’m ready to post.</span></label><button id="kp-publish" class="kp-publish" type="button" disabled>Review and post</button><button id="kp-draft" class="kp-draft" type="button">Save a draft</button><div id="kp-result" class="kp-result" role="status" aria-live="polite"></div>
+      <label class="kp-confirm"><input id="kp-confirm" type="checkbox"><span>I checked the picture, words, music suggestion, and accounts. I’m ready to post.</span></label><button id="kp-publish" class="kp-publish" type="button" disabled>Post now</button><button id="kp-draft" class="kp-draft" type="button">Save a draft</button><div id="kp-result" class="kp-result" role="status" aria-live="polite"></div>
     </section>
     <footer class="kp-nav"><button id="kp-back" type="button" disabled>← Back</button><button id="kp-next" type="button">Next: Music →</button></footer>
   </main>
@@ -39,6 +39,7 @@
 .kp-assets{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:12px;margin-top:22px;max-height:360px;overflow:auto;padding:4px}.kp-asset{position:relative;aspect-ratio:1;border:3px solid transparent;border-radius:16px;overflow:hidden;background:#ece8de;cursor:pointer;padding:0}.kp-asset img{width:100%;height:100%;object-fit:cover}.kp-asset-name{position:absolute;inset:auto 0 0;padding:18px 7px 6px;background:linear-gradient(transparent,rgba(23,34,53,.88));color:#fff;font-size:11px;font-weight:700;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}.kp-asset.on{border-color:var(--green);box-shadow:0 0 0 3px #c8ead9}.kp-asset.on:after{content:'✓';position:absolute;right:7px;top:7px;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--green);color:#fff;font-weight:900;pointer-events:none}.kp-more{margin-top:18px;color:#5c6570}.kp-more summary{cursor:pointer;font-weight:700}.kp-more input,.kp-prompt input,#kp-caption,#kp-account{width:100%;box-sizing:border-box;margin-top:9px;border:2px solid #d7d9dc;border-radius:13px;padding:12px 14px;font:inherit;background:#fff}.kp-more input:focus,.kp-prompt input:focus,#kp-caption:focus,#kp-account:focus{outline:3px solid #f8dfa0;border-color:#c99927}
 .kp-asset-tools{display:flex;gap:10px;align-items:center;margin-top:20px;flex-wrap:wrap}.kp-filter{display:flex;gap:6px;flex-wrap:wrap}.kp-filter button{border:1px solid #dadddf;background:#fff;border-radius:999px;padding:8px 11px;font:700 12px inherit;cursor:pointer}.kp-filter button.on{background:var(--navy);border-color:var(--navy);color:#fff}.kp-asset-tools input{flex:1;min-width:180px;border:2px solid #d7d9dc;border-radius:999px;padding:9px 13px;font:inherit}
 .kp-choices,.kp-channels{display:grid;grid-template-columns:repeat(auto-fill,minmax(205px,1fr));gap:12px;margin-top:22px}.kp-choice,.kp-channel{min-height:86px;text-align:left;border:2px solid #dadddf;background:#fff;border-radius:16px;padding:14px;cursor:pointer;color:var(--navy);font:inherit}.kp-choice b,.kp-channel b{display:block;font-size:15px;margin-bottom:4px}.kp-choice small,.kp-channel small{display:block;color:#6b7480;line-height:1.35}.kp-choice.on,.kp-channel.on{border-color:var(--green);background:#ecf8f1;box-shadow:0 0 0 2px #c8ead9}.kp-channel.off{opacity:.48;cursor:not-allowed}.kp-label{display:block;margin-top:20px;font-weight:800;font-size:14px}.kp-prompt{display:flex;gap:10px}.kp-prompt input{margin:9px 0 0}.kp-prompt button,#kp-all,#kp-none{border:0;border-radius:12px;padding:12px 16px;font-weight:800;cursor:pointer;white-space:nowrap}.kp-prompt button{margin-top:9px;background:var(--sun);color:var(--navy)}
+.kp-music-card{border:2px solid #dadddf;background:#fff;border-radius:16px;padding:10px}.kp-music-card.on{border-color:var(--green);background:#ecf8f1;box-shadow:0 0 0 2px #c8ead9}.kp-music-card .kp-choice{width:100%;border:0;padding:5px;background:transparent;box-shadow:none;min-height:66px}.kp-music-card audio{width:100%;height:34px;margin-top:6px}.kp-license{font-size:11px;color:#52606d;margin:5px 4px 0}.kp-disclosure{font-size:12px;color:#5d6874;background:#f1f4f6;border-radius:10px;padding:9px;margin-top:8px}
 .kp-suggestions{display:grid;gap:9px;margin-top:14px}.kp-suggestion{border:2px solid #dadddf;background:#fff;border-radius:14px;padding:12px 14px;text-align:left;cursor:pointer;font:inherit;line-height:1.45}.kp-suggestion:hover{border-color:#c99927;background:#fffaec}.kp-suggestion:before{content:'Use this';display:block;color:var(--green);font-size:11px;font-weight:900;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px}#kp-caption{min-height:130px;resize:vertical}.kp-count{text-align:right;color:#707987;font-size:12px;margin-top:4px}.kp-allrow{display:flex;gap:9px;margin-top:20px}#kp-all{background:var(--navy);color:#fff}#kp-none{background:#e9ecef;color:var(--navy)}
 .kp-review{display:grid;grid-template-columns:190px 1fr;gap:20px;margin-top:22px;border:2px solid #dadddf;border-radius:18px;padding:16px;background:#fff}.kp-preview{aspect-ratio:1;border-radius:13px;overflow:hidden;background:#ece8de}.kp-preview img,.kp-preview video{width:100%;height:100%;object-fit:cover}.kp-summary h4{margin:2px 0 5px;font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:#75808c}.kp-summary p{white-space:pre-wrap;line-height:1.5;margin:0 0 14px}.kp-tags{display:flex;gap:7px;flex-wrap:wrap}.kp-tag{background:#edf1f4;border-radius:999px;padding:6px 10px;font-size:12px;font-weight:700}.kp-confirm{display:flex;gap:12px;align-items:flex-start;background:#fff5d5;border:2px solid #efd06f;border-radius:15px;padding:14px;margin-top:17px;font-weight:700;line-height:1.4}.kp-confirm input{width:22px;height:22px;flex:none}.kp-publish,.kp-draft{width:100%;border:0;border-radius:14px;padding:15px;margin-top:12px;font:800 17px/1 inherit;cursor:pointer}.kp-publish{background:var(--green);color:#fff}.kp-publish:disabled{background:#aeb6b1;cursor:not-allowed}.kp-draft{background:#e9ecef;color:var(--navy)}.kp-result{margin-top:12px;font-weight:700;line-height:1.45}.kp-result.ok{color:var(--green)}.kp-result.bad{color:#a33c2f}.kp-nav{display:flex;justify-content:space-between;border-top:1px solid #e3e1d9;padding:16px 30px;background:#fff}.kp-nav button{border:0;border-radius:12px;padding:12px 18px;font-weight:800;cursor:pointer}.kp-nav button:disabled{opacity:.35}.kp-nav #kp-next{background:var(--coral);color:#fff}.kp-wait{grid-column:1/-1;padding:28px;text-align:center;color:#68717c}.kp-error{background:#fff0eb;color:#923f32;border-radius:12px;padding:12px;margin-top:12px}
 @media(max-width:700px){.kp-hero{align-items:flex-start;padding:20px}.kp-score{display:none}.kp-steps{gap:3px}.kp-step b{display:none}.kp-pane{padding:22px 16px}.kp-assets{grid-template-columns:repeat(3,1fr)}.kp-prompt{display:block}.kp-prompt button{width:100%}.kp-review{grid-template-columns:1fr}.kp-preview{max-height:280px}.kp-nav{padding:14px 16px}}
diff --git a/public/panels/quickpost.js b/public/panels/quickpost.js
index fe3094f..9cf3b68 100644
--- a/public/panels/quickpost.js
+++ b/public/panels/quickpost.js
@@ -72,9 +72,9 @@ window.MCC_PANELS.quickpost = {
     async function loadMusic() {
       try {
         const d = await fetch(O + '/api/sounds/catalog', {credentials:'same-origin'}).then(r => r.json());
-        const items = (d.catalog || []).flatMap(s => s.items || []).filter(x => x.badge === 'brandsafe').slice(0, 8);
-        $('#kp-music').innerHTML = `<button class="kp-choice on" type="button" data-music=""><b>🔇 No music</b><small>That is completely okay.</small></button>` + items.map(x => `<button class="kp-choice" type="button" data-music="${esc(x.url)}" data-name="${esc(x.name)}"><b>🎵 ${esc(x.name)}</b><small>${esc((x.note || 'Brand-safe music').slice(0,100))}</small></button>`).join('');
-        $$('.kp-choice').forEach(b => { b.setAttribute('aria-pressed', b.classList.contains('on')); b.onclick = () => { $$('.kp-choice').forEach(x => { x.classList.remove('on'); x.setAttribute('aria-pressed','false'); }); b.classList.add('on'); b.setAttribute('aria-pressed','true'); state.song = b.dataset.music ? {name:b.dataset.name,url:b.dataset.music} : null; }; });
+        const items = (d.catalog || []).flatMap(s => s.items || []).filter(x => x.badge === 'brandsafe' && x.previewUrl).slice(0, 8);
+        $('#kp-music').innerHTML = `<div class="kp-music-card on"><button class="kp-choice on" type="button" data-music=""><b>🔇 No music</b><small>That is completely okay.</small></button></div>` + items.map(x => { const audio = new URL(x.previewUrl, O).href; return `<div class="kp-music-card"><button class="kp-choice" type="button" data-music="${esc(new URL(x.url, O).href)}" data-name="${esc(x.name)}" data-license="${esc(x.license || '')}" data-duration="${esc(x.duration || '')}"><b>🎵 ${esc(x.name)} · ${esc(x.duration || '')}</b><small>${esc((x.note || 'Brand-safe music').slice(0,100))}</small></button><audio controls preload="metadata" src="${esc(audio)}" aria-label="Preview ${esc(x.name)}"></audio><div class="kp-license">${esc(x.license || 'Check license before use')}</div></div>`; }).join('');
+        $$('.kp-choice').forEach(b => { b.setAttribute('aria-pressed', b.classList.contains('on')); b.onclick = () => { $$('.kp-music-card').forEach(x => x.classList.remove('on')); $$('.kp-choice').forEach(x => { x.classList.remove('on'); x.setAttribute('aria-pressed','false'); }); b.closest('.kp-music-card').classList.add('on'); b.classList.add('on'); b.setAttribute('aria-pressed','true'); state.song = b.dataset.music ? {name:b.dataset.name,url:b.dataset.music,license:b.dataset.license,duration:b.dataset.duration,suggestionOnly:true} : null; }; });
       } catch (_) { $('#kp-music').innerHTML = '<button class="kp-choice on" type="button"><b>🔇 No music</b><small>Music choices could not load.</small></button>'; }
     }
 
@@ -109,7 +109,8 @@ window.MCC_PANELS.quickpost = {
       const cap=$('#kp-caption').value.trim(); const isVideo=/\.(mp4|mov|webm|m4v)(\?|$)/i.test(state.mediaUrl);
       const media=state.mediaUrl ? (isVideo?`<video src="${esc(state.mediaUrl)}" controls playsinline></video>`:`<img src="${esc(state.mediaUrl)}" alt="Chosen post picture">`) : '<div class="kp-wait">No picture</div>';
       const tags=state.channels.map(c=>`<span class="kp-tag">${icons[c]||'●'} ${esc(c)}</span>`).join('');
-      $('#kp-review').innerHTML=`<div class="kp-preview">${media}</div><div class="kp-summary"><h4>Your words</h4><p>${esc(cap||'No words')}</p><h4>Music</h4><p>${esc(state.song?state.song.name:'No music')}</p><h4>Posting to</h4><div class="kp-tags">${tags||'<span class="kp-tag">None chosen</span>'}</div></div>`;
+      const song = state.song ? `${esc(state.song.name)} · ${esc(state.song.duration)}<div class="kp-disclosure">Music suggestion only. It is saved with the post recipe; some social apps require adding the track inside their own app.</div>` : 'No music';
+      $('#kp-review').innerHTML=`<div class="kp-preview">${media}</div><div class="kp-summary"><h4>Your words</h4><p>${esc(cap||'No words')}</p><h4>Music suggestion</h4><p>${song}</p><h4>Posting to</h4><div class="kp-tags">${tags||'<span class="kp-tag">None chosen</span>'}</div></div>`;
       $('#kp-confirm').checked=false; $('#kp-publish').disabled=true; $('#kp-result').textContent='';
     }
     $('#kp-confirm').onchange=e => { $('#kp-publish').disabled=!e.target.checked; };
diff --git a/public/quickpost-music/bright-reveal.mp3 b/public/quickpost-music/bright-reveal.mp3
new file mode 100644
index 0000000..94ea9b8
Binary files /dev/null and b/public/quickpost-music/bright-reveal.mp3 differ
diff --git a/public/quickpost-music/quiet-texture.mp3 b/public/quickpost-music/quiet-texture.mp3
new file mode 100644
index 0000000..0e43cb8
Binary files /dev/null and b/public/quickpost-music/quiet-texture.mp3 differ
diff --git a/public/quickpost-music/soft-showroom.mp3 b/public/quickpost-music/soft-showroom.mp3
new file mode 100644
index 0000000..3e7db9c
Binary files /dev/null and b/public/quickpost-music/soft-showroom.mp3 differ
diff --git a/screenrecord/quickpost/DEBUG-REPORT.md b/screenrecord/quickpost/DEBUG-REPORT.md
index 92c66d9..316f860 100644
--- a/screenrecord/quickpost/DEBUG-REPORT.md
+++ b/screenrecord/quickpost/DEBUG-REPORT.md
@@ -1,16 +1,16 @@
 # Quick Post five-run screen-record report
 
-**Verdict:** PASS — 153/153 recorded actions clean across five distinct full-control combinations.
+**Verdict:** PASS — 154/154 recorded actions clean across five distinct full-control combinations.
 
 **Safety:** Copy generation, live publish, and draft endpoints were intercepted in the browser. No external post, draft write, email, deploy, or spend occurred.
 
 ## Recordings
 
-- Run 0 (combination-0): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run0/page@544d43a6ff2a10b8cb3e83cbcc4d56de.mp4
-- Run 1 (combination-1): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run1/page@d10a227ebe0a4f40d039440b59598320.mp4
-- Run 2 (combination-2): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run2/page@eb90353e6de8eba25641923003da52ff.mp4
-- Run 3 (combination-3): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run3/page@504411666a3211af05bc80dce17ed577.mp4
-- Run 4 (combination-4): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run4/page@62f1b5cde54e0a0ebdcc54c5b1e54327.mp4
+- Run 0 (combination-0): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run0/page@6ea562bae96b086cd5774ab54d978202.webm
+- Run 1 (combination-1): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run1/page@b73bd0680a991bbf352fc637ee550f27.webm
+- Run 2 (combination-2): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run2/page@5f61213d709d332bb30f30e815a273fc.webm
+- Run 3 (combination-3): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run3/page@21ddeb8e2e8c9a272bdce2353c213b76.webm
+- Run 4 (combination-4): /Users/macstudio3/Projects/marketing-command-center/screenrecord/quickpost/rec/run4/page@532aad22eabee02194cf703ef4324024.webm
 
 ## Combination coverage
 
diff --git a/screenrecord/quickpost/debug-log.jsonl b/screenrecord/quickpost/debug-log.jsonl
index b66bc57..8343703 100644
--- a/screenrecord/quickpost/debug-log.jsonl
+++ b/screenrecord/quickpost/debug-log.jsonl
@@ -530,3 +530,167 @@
 {"run":4,"ts":"2026-09-02T00:18:40.127Z","label":"confirm checkbox","ok":true,"effect":"expected state observed","errors":[]}
 {"run":4,"ts":"2026-09-02T00:18:40.269Z","label":"post now mocked","ok":true,"effect":"expected state observed","errors":[]}
 {"run":4,"ts":"2026-09-02T00:18:40.269Z","label":"run complete","ok":true,"effect":"combination-4","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:30.345Z","label":"filter all","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:30.507Z","label":"filter catalog","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:30.661Z","label":"filter upload","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:30.787Z","label":"picture search","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:30.956Z","label":"picture asset","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:31.100Z","label":"paste-link details","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:31.254Z","label":"next to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:31.394Z","label":"picture step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:31.543Z","label":"step tab forward to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:24:31.685Z","label":"music choice","ok":false,"effect":"expected state was not observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:38.649Z","label":"filter all","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:38.797Z","label":"filter catalog","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:38.941Z","label":"filter upload","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.070Z","label":"picture search","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.234Z","label":"picture asset","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.370Z","label":"paste-link details","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.512Z","label":"next to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.659Z","label":"picture step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.806Z","label":"step tab forward to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:39.946Z","label":"music choice","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.082Z","label":"next to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.206Z","label":"topic input","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.348Z","label":"generate suggestions","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.501Z","label":"choose suggestion","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.626Z","label":"edit final words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.769Z","label":"music step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:40.912Z","label":"step tab forward to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.077Z","label":"next to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.212Z","label":"single account","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.338Z","label":"account menu","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.485Z","label":"words step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.631Z","label":"step tab forward to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.778Z","label":"next to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:41.918Z","label":"where step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:42.086Z","label":"step tab forward to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:42.226Z","label":"check step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:42.352Z","label":"review picture rendered","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:42.491Z","label":"confirm checkbox","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:42.626Z","label":"post now mocked","ok":true,"effect":"expected state observed","errors":[]}
+{"run":0,"ts":"2026-09-02T00:25:42.642Z","label":"run complete","ok":true,"effect":"combination-0","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:43.516Z","label":"paste-link details","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:43.673Z","label":"filter upload","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:43.820Z","label":"filter catalog","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:43.962Z","label":"filter all","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.087Z","label":"picture search","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.242Z","label":"paste picture link","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.384Z","label":"next to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.517Z","label":"picture step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.666Z","label":"step tab forward to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.809Z","label":"music choice","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:44.951Z","label":"next to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.076Z","label":"topic input","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.217Z","label":"generate suggestions","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.371Z","label":"choose suggestion","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.497Z","label":"edit final words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.633Z","label":"music step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.764Z","label":"step tab forward to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:45.928Z","label":"next to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.068Z","label":"choose all accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.198Z","label":"clear accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.337Z","label":"choose all accounts final","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.462Z","label":"account menu","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.602Z","label":"words step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.741Z","label":"step tab forward to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:46.886Z","label":"next to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:47.029Z","label":"where step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:47.164Z","label":"step tab forward to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:47.308Z","label":"check step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:47.435Z","label":"review picture rendered","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:47.583Z","label":"save drafts mocked","ok":true,"effect":"expected state observed","errors":[]}
+{"run":1,"ts":"2026-09-02T00:25:47.583Z","label":"run complete","ok":true,"effect":"combination-1","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:48.457Z","label":"picture validation","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:48.625Z","label":"filter all","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:48.780Z","label":"filter catalog","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:48.944Z","label":"filter upload","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.069Z","label":"picture search","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.235Z","label":"picture asset","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.378Z","label":"paste-link details","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.513Z","label":"next to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.655Z","label":"picture step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.810Z","label":"step tab forward to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:49.944Z","label":"music choice","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.086Z","label":"next to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.211Z","label":"topic input","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.349Z","label":"generate suggestions","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.491Z","label":"choose suggestion","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.616Z","label":"edit final words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.756Z","label":"music step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:50.890Z","label":"step tab forward to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.043Z","label":"next to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.185Z","label":"single account","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.309Z","label":"account menu","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.459Z","label":"words step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.598Z","label":"step tab forward to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.746Z","label":"next to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:51.916Z","label":"where step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:52.063Z","label":"step tab forward to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:52.200Z","label":"check step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:52.326Z","label":"review picture rendered","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:52.469Z","label":"confirm checkbox","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:52.615Z","label":"post now mocked","ok":true,"effect":"expected state observed","errors":[]}
+{"run":2,"ts":"2026-09-02T00:25:52.615Z","label":"run complete","ok":true,"effect":"combination-2","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:53.609Z","label":"paste-link details","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:53.754Z","label":"filter upload","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:53.899Z","label":"filter catalog","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.050Z","label":"filter all","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.177Z","label":"picture search","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.332Z","label":"paste picture link","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.486Z","label":"next to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.625Z","label":"picture step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.767Z","label":"step tab forward to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:54.905Z","label":"music choice","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.044Z","label":"back button","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.183Z","label":"return to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.316Z","label":"next to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.442Z","label":"topic input","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.584Z","label":"generate suggestions","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.721Z","label":"choose suggestion","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.846Z","label":"edit final words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:55.983Z","label":"music step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:56.121Z","label":"step tab forward to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:56.309Z","label":"next to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:56.457Z","label":"choose all accounts final","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:56.582Z","label":"account menu","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:56.733Z","label":"words step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:56.868Z","label":"step tab forward to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.003Z","label":"next to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.157Z","label":"where step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.298Z","label":"step tab forward to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.440Z","label":"check step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.567Z","label":"review picture rendered","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.707Z","label":"save drafts mocked","ok":true,"effect":"expected state observed","errors":[]}
+{"run":3,"ts":"2026-09-02T00:25:57.707Z","label":"run complete","ok":true,"effect":"combination-3","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:58.202Z","label":"prior-failure priority","ok":true,"effect":"music choice","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:58.440Z","label":"filter all","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:58.579Z","label":"filter catalog","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:58.737Z","label":"filter upload","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:58.862Z","label":"picture search","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.035Z","label":"picture asset","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.186Z","label":"paste-link details","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.344Z","label":"next to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.489Z","label":"picture step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.646Z","label":"step tab forward to music","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.792Z","label":"music choice","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:25:59.936Z","label":"next to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.062Z","label":"topic input","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.197Z","label":"generate suggestions","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.336Z","label":"choose suggestion","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.461Z","label":"edit final words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.599Z","label":"music step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.748Z","label":"step tab forward to words","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:00.904Z","label":"next to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.045Z","label":"single account","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.170Z","label":"account menu","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.310Z","label":"words step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.466Z","label":"step tab forward to accounts","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.607Z","label":"next to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.772Z","label":"where step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:01.909Z","label":"step tab forward to check","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:02.052Z","label":"check step tab","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:02.177Z","label":"review picture rendered","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:02.313Z","label":"confirm checkbox","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:02.449Z","label":"post now mocked","ok":true,"effect":"expected state observed","errors":[]}
+{"run":4,"ts":"2026-09-02T00:26:02.449Z","label":"run complete","ok":true,"effect":"combination-4","errors":[]}
diff --git a/verification/e2e-proof.json b/verification/e2e-proof.json
index a72e707..b1425b8 100644
--- a/verification/e2e-proof.json
+++ b/verification/e2e-proof.json
@@ -3,11 +3,11 @@
   "risk_tier": "R3",
   "environment": "Mac2 local Marketing Command Center on http://127.0.0.1:9661",
   "build_commit": "193bd34 (Quick Post UI); verification harness commit recorded in git history",
-  "timestamp": "2026-09-01T17:18:56-07:00",
+  "timestamp": "2026-09-01T18:02:00-07:00",
   "preconditions": [
     "MCC service listening on :9661",
     "Basic Auth configured",
-    "Publish endpoints not invoked"
+    "Live platform adapters not invoked"
   ],
   "checks": [
     {"name":"Unauthenticated boundary","command":"GET /api/health without credentials","verdict":"PASS","evidence":"HTTP 401"},
@@ -15,11 +15,24 @@
     {"name":"Panel inventory","command":"GET /api/panels with MCC credentials","verdict":"PASS","evidence":"33 panels returned"},
     {"name":"Channel status","command":"GET /api/channels/status with MCC credentials","verdict":"PASS","evidence":"4 platform records returned"},
     {"name":"Expanded catalog source","command":"GET /api/assets/catalog?limit=200 with MCC credentials","verdict":"PASS","evidence":"catalog endpoint returned product records; Quick Post merges up to 200"},
+    {"name":"Protected Quick Post APIs","command":"GET composer targets, sounds catalog, and channel status with and without credentials","verdict":"PASS","evidence":"Each anonymous request returned 401; each credentialed request returned 200"},
+    {"name":"Playable music suggestions","command":"GET /quickpost-music/soft-showroom.mp3 with credentials","verdict":"PASS","evidence":"HTTP 200 audio/mpeg; three 12-second DW-original previews expose duration and commercial-use metadata"},
+    {"name":"Unchecked live boundary","command":"POST /api/channels/publish with dryRun=false and confirm=false","verdict":"PASS","evidence":"HTTP 400 explicit-confirmation error; channels-outbox SHA-256 unchanged"},
+    {"name":"No-write fan-out inspection","command":"POST /api/channels/publish with inspectOnly=true and dryRun=true","verdict":"PASS","evidence":"inspectOnly=true, writePerformed=false; channels-outbox SHA-256 unchanged"},
     {"name":"Cross-browser CTA","command":"node scripts/cta-quickpost.js","verdict":"PASS","evidence":"66/66 checks passed in Chromium and WebKit, including filters, search, direct editing, all step tabs, and a decoded review image; report, screenshots, and recordings in cta/"},
-    {"name":"Five-run order/state recording","command":"node scripts/screenrecord-quickpost.js","verdict":"PASS","evidence":"153/153 recorded actions passed across five distinct full-control combinations, including decoded review-image assertions; append-only log, report, and five MP4 recordings in screenrecord/quickpost/"},
+    {"name":"Five-run order/state recording","command":"node scripts/screenrecord-quickpost.js","verdict":"PASS","evidence":"154 recorded actions passed across five distinct full-control combinations, including decoded review-image assertions; append-only log, report, and five recordings in screenrecord/quickpost/"},
     {"name":"No draft-store mutation","command":"git diff -- data/quickpost-drafts.json","verdict":"PASS","evidence":"No diff; publish and draft boundaries were intercepted before reaching Express"}
   ],
   "side_effects": {"social_posts":0,"emails":0,"spend_usd":0,"external_writes":0},
+  "validation_loop": {
+    "reviewer": "Contrarian v2 gate",
+    "correlation_id": "MCC-CONTRARIAN-V2-20260901-1802",
+    "verdict": "SHIP IT for the local-only milestone",
+    "remaining_caveats": [
+      "Live platform delivery and automatic music attachment were not tested because those actions remain gated.",
+      "Before live-release approval, add a checked-in track provenance manifest and a browser assertion that audio currentTime advances."
+    ]
+  },
   "cleanup": "No production or remote service touched; local MCC process retained for browser review.",
-  "verdict": "PASS — local UX, API boundaries, Chromium/WebKit Quick Post journey, and five distinct recorded action orders pass; no social posts, emails, spend, deploys, or external writes performed."
+  "verdict": "PASS — local UX, credential boundaries, server-side publish safety, playable music suggestions, Chromium/WebKit Quick Post journey, and five distinct recorded action orders pass; no social posts, emails, spend, deploys, or external writes performed."
 }

← ba9ebc4 auto-data-snapshot: 2026-09-01T17:22:42 (6 data files) — pub  ·  back to Marketing Command Center  ·  auto-data-snapshot: 2026-09-01T18:00:51 (1 data files) — pub dd33025 →