← all audits

Making this site the place you work

How every surface gets reviewable.

Make the review site the owner's workbench

Headline finding

The review site is still a seven-route browser gallery, not the place the owner can review the whole Windows product or send a correction to an agent. [integration/full:apps/osl-hub-ui/scripts/task-7950-build-review-harness.mjs:80-101,111-119; integration/full:apps/osl-hub-ui/review-harness/owner-reviews.js:61-93]

What is wrong today

It inventories routes, not UI surfaces

TASK 7950 has a hand-written array containing Home and six OSL Chats states. Every entry is turned into review-app.html?screen=<id>, and the build refuses any count other than seven. A settings region and chat states are special cases; there is no general inventory of dialogs, sheets, popovers, toasts, carrier overlays, the protected composer, or the eye. [integration/full:apps/osl-hub-ui/scripts/task-7950-build-review-harness.mjs:34,80-101,111-140]

The review runtime repeats the same problem. It hand-codes five owner subjects and hand-drives a few onboarding, settings, chat, attachment, and Friends states. This is useful test access, but it is not a denominator for everything a person can see. [integration/full:apps/osl-hub-ui/review-harness/app/review-runtime.js:51-66,99-170]

The separate Owner Reviews page scans unfinished build: ui / who: liam tasks, then waits for somebody to hand-prepare proof/owner-materials/<task>.json. That is a task queue, not a surface inventory; a popup or eye state appears only when somebody already knew to prepare it. [integration/full:apps/osl-hub-ui/scripts/task-7997-owner-reviews-lib.mjs:38-71,324-395; TASK 8003]

This omission matters to the working product. The composer and eye overlay are explicit product surfaces, and the owner has repeatedly found dead sliders, wrong click destinations, missing tutorial layers, and broken navigation that a route screenshot did not reveal. [RULING D10; RULING D26; RULING D58; RULING D67]

The current freshness guard is not enough

requireFreshCapture uses the time of the Git commit that last changed the image and rejects it after three days. If Git cannot provide a valid timestamp, it silently allows the material. [integration/full:apps/osl-hub-ui/scripts/task-7997-owner-reviews-lib.mjs:161-189]

That catches an obviously old committed image, but it does not establish when the screen was captured or which build and operating system produced it. Recommitting old pixels makes them young; a genuine new capture with identical pixels keeps the old timestamp. The subject schema records path, image hash, canonical ancestry, and a generic shipping-product assertion, but no capture time, platform, executable digest, or capture run. [integration/full:apps/osl-hub-ui/scripts/task-7997-owner-reviews-lib.mjs:144-159,228-275; OSL-AUDITS/proof/owner-materials/0595.json:13-41]

The arbitrary three-day expiry should be cut. It hides unchanged, still-correct work and can be bypassed without recapturing. Freshness must instead mean that the capture names the build it showed and none of that surface's shipping source has changed since. This keeps the part that stops a lie and removes the calendar gate that does not. [RULING D58; RULING D59]

The feedback loop is claimed but not connected

The deployed Owner Reviews page only stores Yes or No in browser localStorage. It has no note box and no Send action, so nothing reaches the inbox or an agent. [integration/full:apps/osl-hub-ui/review-harness/owner-reviews.js:61-93,129-148]

TASK 8001's form exists in review.js, but index.html has none of the owner-review elements it expects, while owner-reviews.html loads the local-only owner-reviews.js. The form also expects the old ready_count / entries manifest while the current generator emits counts / groups / materials. [integration/full:apps/osl-hub-ui/review-harness/review.js:7-12,46-125; integration/full:apps/osl-hub-ui/review-harness/index.html:11-25; integration/full:apps/osl-hub-ui/review-harness/owner-reviews.html:11-24; integration/full:apps/osl-hub-ui/scripts/task-7997-owner-reviews-lib.mjs:360-395]

The stranded browser client and deployed Worker also disagree. The client sends X-OSL-Review-Secret, task_id, and reads /v1/tasks/<id>; the Worker requires Authorization: Bearer, taskId, returns a different response, and exposes /v1/state. The poller matches the current Worker, but its repository instructions only show a manual run command; a continuously running production poller cannot be established. Do not call TASKS 7998-8001 a working loop until one real browser submission returns one real agent result to the same card. [integration/full:apps/osl-hub-ui/review-harness/review-inbox.js:29-42,74-112; integration/full:apps/osl-hub-ui/review-harness/inbox-worker/src/worker.js:64-74,101-117,144-164,205-223,241-264; integration/full:tools/task-7999-review-poller/README.md:17-31; OSL-AUDITS/evidence/8001.md:7-31]

The site does not show an established Windows approval image

Screen Review embeds a review-only Vite bundle beside design HTML in browser iframes. Its runtime supplies a Tauri shim and synthetic state. That is a useful development preview, but it is not the packaged Windows application and must stop being labelled as the shipping view. [integration/full:apps/osl-hub-ui/scripts/task-7950-build-review-harness.mjs:125-140,163-180; integration/full:apps/osl-hub-ui/review-harness/app/review-runtime.js:1-3,15-49]

Owner Reviews currently has ten ready entries made from PNGs, but the material schema does not record platform. At least one displayed image is explicitly view-once-display-linux.png; no ready receipt establishes a Windows artifact digest. The honest description of today's page is therefore “browser previews plus mixed or unproved-platform captures,” not Windows. [/home/liamw/osl-review-build/apps/osl-hub-ui/review-harness/dist/owner-reviews.json:10-14; OSL-AUDITS/proof/owner-materials/0595.json:33-41; integration/full:apps/osl-hub-ui/scripts/task-7997-owner-reviews-lib.mjs:228-275]

Windows is the V1 product and Linux is a development/test harness. Linux/Windows pixel equality should not block V1; it buys no shipped-product correctness. Keep the Linux preview for fast iteration, but make the Windows capture the approval image and label the Linux version “development preview.” [RULING S1; OSL-AUDITS/deliverable/01-FULL-SPEC.md:27,340,354]

The smallest changes with the biggest effect

1. Replace the seven-screen list with one surface manifest

Build one review-surfaces manifest and make both Screen Review and Owner Reviews consume it. A row represents a visible state, not a route. It needs only: stable surface id, plain-English title, kind, route/parent, how to open the state, design page or design region, source paths, approval status, and the owner task ids that refer to it. One surface can satisfy several owner tasks without showing the same image several times. [integration/full:apps/osl-hub-ui/scripts/task-7950-build-review-harness.mjs:80-101; TASK 7997]

Do not start from zero. TASK 7049 already reads the shipping route unions and every rendered design page's embedded declaration, including routed, state, retired, re-homed, non-app, and not-built-yet. Use that as the route/design half of the manifest, then add the code-only native composites. [integration/full:apps/osl-hub-ui/scripts/task-7049-route-design-manifest.mjs:1-7,22-48,66-77,97-137]

The first manifest must cover these classes:

The build should fail when a live route or retained design declaration has no manifest row, when a row cannot render nonblank, or when its named design file is absent. A code-only native surface remains an explicit row because no automatic code scan can currently establish the complete native-surface denominator. Missing totality must be reported, not claimed away. [RULING D26; TASK 7950b]

Put all unsettled rows on one “Review” page, with filters for Needs review, Fixed and ready again, Approved, and Not capturable. Keep Presentation and the downloadable pack as secondary links. Decisions can remain a separate empty page until there is a real decision. This removes navigation and duplicate queues without creating a new application. [RULING D43; TASK 7997]

2. Make currentness about changed product bytes, not age

Replace the three-day test with a small capture receipt beside every capture:

The site may say “current” only when those fields exist, the artifact digest resolves, and the recorded source/design hashes still equal canonical. A changed source makes the row Stale and removes its Good button until recaptured. Recommitting the same PNG changes none of those facts. [OSL-AUDITS/proof/7317/canonical-windows-artifact.provenance.json:1-11; RULING D58]

Do not hide a visible surface because its functional gate receipts are unfinished. Show it with an honest badge such as “Visual review ready; behaviour unproved.” Gate receipts belong in details and in release proof, not in eligibility to give UI feedback. The current rule leaves 59 of 69 reviews hidden and still does not rerun their proofs; it delays product feedback without preventing a false proof claim when the badge is honest. [/home/liamw/osl-review-build/apps/osl-hub-ui/review-harness/dist/owner-reviews.json:10-14; integration/full:apps/osl-hub-ui/scripts/task-7997-owner-reviews-lib.mjs:278-298,329-376; TASK 7997]

Keep the checks that stop lies: nonblank rendering, exact design pairing, source hashes, explicit platform/build labels, and “unknown” when capture provenance is absent. Cut the arbitrary age window, capture-file commit-date churn, and gate-receipt requirement for merely appearing on the work page. [RULING D26; RULING D58; RULING D59]

3. Repair the existing feedback path instead of building another backend

Move a compact form into the renderer that actually owns each review card: Good, Bad, one note box, Send. A Bad answer requires a note; Good may carry one. Show only Unanswered, Sent, Agent working, Fixed and ready again, or Could not fix. [integration/full:apps/osl-hub-ui/review-harness/owner-reviews.js:129-148; TASK 8001]

Use the already deployed Worker and existing poller, but make one contract authoritative. The browser client must use the current Worker's Bearer header, camel-case body, response, and /v1/state; the builder must copy the client into dist; and the poller must run as a user service rather than a command somebody remembers to start. [integration/full:apps/osl-hub-ui/review-harness/inbox-worker/DEPLOYMENT.md:1-13; integration/full:tools/task-7999-review-poller/review_poller.py:175-228; integration/full:apps/osl-hub-ui/scripts/task-7950-build-review-harness.mjs:130-138]

Key feedback by surface_id + capture_run_id, not task id alone. That lets the same surface be rejected, fixed, recaptured, and reviewed again without overwriting history, and it covers surfaces that are not plan tasks. Keep one active repair agent at a time. A Good verdict records approval and rebuilds the queue; a Bad verdict dispatches one bounded repair agent, then its result returns to the card. [TASK 7999; TASK 8001; RULING D43]

Do not put the Worker secret in static JSON. The endpoint can start an agent on the owner's machine, so exposing its write credential creates real harm. Ask the owner for it once in the browser and keep it only in local browser storage, as the Worker documentation already recommends. No Cloudflare Access project or new account system is needed. [integration/full:apps/osl-hub-ui/review-harness/inbox-worker/README.md:12-15; TASK 7998]

The dispatched repair brief must say two things verbatim: never message a real third party, and never claim a proof that has not happened. Feedback text remains data, not shell input or an instruction to contact anybody. [TASK 7999; OSL-AUDITS/deliverable/01-FULL-SPEC.md:358]

4. Make Windows primary without blocking on capture protection

Run the surface sequence on the canonical packaged Windows artifact and add the resulting PNGs as the row's primary materials. The existing PowerShell capture already targets the real OSL Privacy window with PrintWindow and CopyFromScreen; it needs a manifest-driven state opener and the receipt above, not a new capture stack. The existing renderer already supports several materials per review, so showing Windows does not need a new page type. [OSL-AUDITS/proof/7317/canonical-windows-artifact.provenance.json:1-11; integration/full:apps/osl-hub-ui/screenshots/capture-osl-hub.ps1:22-46; integration/full:apps/osl-hub-ui/review-harness/owner-reviews.js:141-147]

Use the same viewport, scale, theme, state, and design page for the optional Linux/browser preview. Show both only when comparison helps; never make Linux parity a release gate. Windows is the approval artifact because Windows ships. [RULING S1; OSL-AUDITS/deliverable/01-FULL-SPEC.md:304,354]

Some shipping Windows screens deliberately exclude themselves from screen capture. For those, use a Windows review build that differs only by disabling display-affinity capture protection, label it “Windows review build — not shipping proof,” and keep the shipping artifact's UI Automation result beside it. Do not present the review-build pixels as proof of the shipping binary. Ordinary screenshots cannot honestly prove those protected windows today. [RULING D48; TASK 7317; TASK 1605; TASK 1609; TASK 4414]

Build order and finish line

1. Generate the surface manifest from TASK 7049 plus the explicit native-composite rows, and replace the seven-item array. Ship one review page that can open every row and its state sequence. [integration/full:apps/osl-hub-ui/scripts/task-7049-route-design-manifest.mjs; TASK 7950]

2. Add capture receipts and visible platform/build badges; recapture the unsettled rows on Windows first. Do not spend time making Linux pixel-identical before the Windows product works. [RULING S1; RULING D58]

3. Put Good/Bad/note/Send on the real cards, align the client with the deployed Worker, run the existing poller continuously, and prove one Bad correction goes browser → Worker → exactly one agent → result on the same card. [TASK 7998; TASK 7999; TASK 8001]

4. Prove the guards with three failures: omit a popup from the manifest, change a surface source after its capture, and disconnect the Send action. Each must fail by name. Then deploy. [TASK 7950b; TASK 8001; RULING D58]

This is finished when the owner can open one page, reach every known route and transient surface including the composer and eye, see whether each artifact is Windows or a preview and whether behaviour is proved, reject one with a note, and see one agent's result return without any claim that an unrun proof passed or any message to a real third party. [RULING D10; RULING D11; TASK 7997; TASK 8001]