|
| 1 | +<!doctype html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <meta charset="utf-8"> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 6 | + <title>PR #79 - Gatekeeper optional origin correction</title> |
| 7 | + <style> |
| 8 | + :root { color-scheme: light dark; --accent:#0a7a68; --card:#ffffff12; --border:#7f8c8d55; } |
| 9 | + body { font: 16px/1.55 system-ui, sans-serif; max-width: 960px; margin: 0 auto; padding: 2rem; } |
| 10 | + h1,h2 { line-height:1.2; } h1 { color:var(--accent); } |
| 11 | + section { border:1px solid var(--border); background:var(--card); border-radius:12px; padding:1.1rem 1.3rem; margin:1rem 0; } |
| 12 | + code,pre { font-family:ui-monospace, monospace; } pre { overflow:auto; padding:1rem; border-radius:8px; background:#111; color:#eee; } |
| 13 | + .flow { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:.6rem; text-align:center; } |
| 14 | + .flow div { padding:.8rem; border:1px solid var(--border); border-radius:8px; } |
| 15 | + .good { color:#17a673; font-weight:700; } .pending { color:#d89500; font-weight:700; } |
| 16 | + .quiz label { display:block; margin:.45rem 0; } button { padding:.5rem .8rem; cursor:pointer; } |
| 17 | + .answer { min-height:1.5rem; font-weight:700; } |
| 18 | + </style> |
| 19 | +</head> |
| 20 | +<body> |
| 21 | + <h1>PR #79: accept an omitted Gatekeeper origin</h1> |
| 22 | + <p><strong>Pinned source:</strong> <code>31da295f7359c25347b96a9d979421bed565671b</code></p> |
| 23 | + <p>This correction accepts a real Gatekeeper assessment that omitted one optional display field. It does not weaken PortReeve's independent signing identity, Team ID, hardened-runtime, timestamp, notarization, staple, architecture, or publication checks.</p> |
| 24 | + |
| 25 | + <section> |
| 26 | + <h2>What happened</h2> |
| 27 | + <div class="flow"> |
| 28 | + <div>Apple notarized preview .7</div><div><code>spctl</code> exited zero</div><div>Status and source were accepted</div><div><code>origin=</code> was absent</div><div>Producer stopped safely</div> |
| 29 | + </div> |
| 30 | + <p>The exact replay emitted:</p> |
| 31 | + <pre>/tmp/PortReeve-0.1.0-preview.7-macos-arm64.dmg: accepted |
| 32 | +source=Notarized Developer ID</pre> |
| 33 | + </section> |
| 34 | + |
| 35 | + <section> |
| 36 | + <h2>The code change</h2> |
| 37 | + <pre>- if (origin !== APPLE_SIGNING_IDENTITY) throw ... |
| 38 | ++ if (origin !== undefined && origin !== APPLE_SIGNING_IDENTITY) throw ...</pre> |
| 39 | + <p>An omitted origin remains omitted in the evidence object. If the command does emit an origin, it must still exactly match <code>Developer ID Application: Trent Brown (PMWYD5A82A)</code>.</p> |
| 40 | + </section> |
| 41 | + |
| 42 | + <section> |
| 43 | + <h2>Where identity authority lives</h2> |
| 44 | + <p>Gatekeeper still must return exit zero, an anchored accepted status, and exactly <code>source=Notarized Developer ID</code>. Separately, each native evidence subject must carry exact <code>codesign</code> facts for the Developer ID identity, Team ID, hardened runtime, and secure timestamp.</p> |
| 45 | + <p>This separation matters: an optional display line cannot become the sole authority for who signed the artifact, and absent output is never synthesized.</p> |
| 46 | + </section> |
| 47 | + |
| 48 | + <section> |
| 49 | + <h2>Scope and evidence</h2> |
| 50 | + <p class="good">Slice checks pass: 577 repository tests, 3025 assertions, zero failures.</p> |
| 51 | + <p>The recovered preview .7 DMG reproduced the accepted no-origin shape locally. Direct negative tests reject a wrong displayed origin and a wrong independent signing identity. No credentials, release topology, channel, public metadata, or publication path changed.</p> |
| 52 | + <p class="pending">Feature completion is still pending.</p> |
| 53 | + <p>After merge, unused preview .8 must run from reviewed <code>main</code>, produce both native architecture evidence documents and the sealed distribution packet, and prove public state remains unchanged.</p> |
| 54 | + </section> |
| 55 | + |
| 56 | + <section class="quiz"> |
| 57 | + <h2>Review check</h2> |
| 58 | + <form id="quiz"> |
| 59 | + <div data-answer="b"><p>1. Why did preview .7 stop?</p><label><input type="radio" name="q1" value="a"> Apple rejected notarization</label><label><input type="radio" name="q1" value="b"> Gatekeeper omitted an optional origin display line</label></div> |
| 60 | + <div data-answer="a"><p>2. Does the parser invent an origin when none was printed?</p><label><input type="radio" name="q2" value="a"> No</label><label><input type="radio" name="q2" value="b"> Yes</label></div> |
| 61 | + <div data-answer="b"><p>3. What happens if Gatekeeper prints the wrong origin?</p><label><input type="radio" name="q3" value="a"> It is ignored</label><label><input type="radio" name="q3" value="b"> The evidence is rejected</label></div> |
| 62 | + <div data-answer="a"><p>4. Which independent evidence still binds the exact signer?</p><label><input type="radio" name="q4" value="a"> <code>codesign</code> identity and Team ID facts</label><label><input type="radio" name="q4" value="b"> The artifact filename</label></div> |
| 63 | + <div data-answer="b"><p>5. What proves the feature complete?</p><label><input type="radio" name="q5" value="a"> This parser correction alone</label><label><input type="radio" name="q5" value="b"> A main-pinned two-architecture nonpublishing preview .8 rehearsal</label></div> |
| 64 | + <p><button type="button" id="grade">Grade</button></p><p class="answer" id="result" aria-live="polite"></p> |
| 65 | + </form> |
| 66 | + </section> |
| 67 | + <script> |
| 68 | + document.getElementById('grade').addEventListener('click', () => { |
| 69 | + const items=[...document.querySelectorAll('[data-answer]')]; |
| 70 | + const score=items.filter((item,i)=>document.querySelector(`input[name=q${i+1}]:checked`)?.value===item.dataset.answer).length; |
| 71 | + document.getElementById('result').textContent=`${score} / ${items.length} correct`; |
| 72 | + }); |
| 73 | + </script> |
| 74 | +</body> |
| 75 | +</html> |
0 commit comments