Skip to content

Commit f20cf01

Browse files
fix(holoqr): match Meta store name and overlay-free screenshots
The privacy policy now uses the listing name HoloQR, and the five 2560x1440 screenshots are unembellished in-app captures so Asset.5 and Privacy.1 can pass on resubmit. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 78052e7 commit f20cf01

12 files changed

Lines changed: 153 additions & 18 deletions

File tree

apps/quest-universal-qr-scanner/PRIVACY.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
# Privacy Policy — Universal QR Scanner
1+
# Privacy Policy — HoloQR
22

3-
_Last updated: 2026-07-25_
3+
_Last updated: 2026-09-02_
44

5-
Universal QR Scanner ("the app") is a utility for Meta Quest 3 / 3S that reads QR codes using
5+
This Privacy Policy applies to the Meta Quest application named **HoloQR**.
6+
7+
HoloQR ("the app") is a utility for Meta Quest 3 / 3S that reads QR codes using
68
the headset's passthrough cameras and opens decoded links in the Quest Browser.
79

810
## What the app accesses

apps/quest-universal-qr-scanner/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ This is a HoloScript-authored app, not a native app with a HoloScript label. The
99
[`worlds/`](./worlds). The immersive Quest project under [`android-mr/`](./android-mr) is compiler
1010
output and a bounded native bridge for platform APIs.
1111

12-
Current store state: HoloQR `1.0.2` (`versionCode 3`) was submitted to Meta Horizon Store review on
13-
2026-07-26. See [`roadmap.md`](./roadmap.md) for the post-launch product sequence and the
12+
Current store state: HoloQR `1.0.2` was rejected on 2026-09-02. Resubmit with `1.0.3`
13+
(`versionCode 4`). See [`roadmap.md`](./roadmap.md) for the post-launch product sequence and the
1414
HoloScript-language gates that every future version must pass.
1515

1616
## Release invariant

apps/quest-universal-qr-scanner/RELEASE.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
## Current store state
44

5-
- HoloQR `1.0.2` (`versionCode 3`) was submitted to Meta Horizon Store review on 2026-07-26.
6-
- Submission metadata and the native binary both report `Submitted`; no review date is assigned yet.
7-
- Meta submission: `1114952735042547`; submitted binary: `1168245949713225`.
5+
- HoloQR `1.0.2` (`versionCode 3`) was **rejected** by Meta Horizon Store review on 2026-09-02.
6+
- Failures: `VRC.Quest.Functional.1` (blank scan HUD looked frozen), `VRC.Quest.Privacy.1`
7+
(privacy policy still said Universal QR Scanner), `VRC.Quest.Asset.5` (marketing overlays on
8+
screenshots).
9+
- Resubmit candidate: HoloQR `1.0.3` (`versionCode 4`) with a visible Scanning pill, delayed camera
10+
permission, HoloQR-named privacy policy, and overlay-free 2560×1440 screenshots.
11+
- Meta submission: `1114952735042547`; previously submitted binary: `1168245949713225`.
812
- After approval, Meta requires a separate immediate-or-scheduled release choice.
913

1014
The custody and submission procedures below remain the runbook for future updates. Product sequencing
@@ -56,7 +60,7 @@ The current submission's Data Use Checkup, Content Guidelines, IARC age rating,
5660
sharing choice, pricing, and reviewer contact are complete. For future candidates, use a
5761
**Release Channel (ALPHA/BETA)** to install the exact build on-headset before public submission.
5862

59-
Current version: `versionCode 3` / `versionName "1.0.2"` (bump both in `scanner.holo`'s `version` block
63+
Current version: `versionCode 4` / `versionName "1.0.3"` (bump both in `scanner.holo`'s `version` block
6064
for each store re-upload — Horizon requires a strictly higher `versionCode` each time).
6165

6266
---

apps/quest-universal-qr-scanner/STORE_LISTING.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ Review flow:
9898
| Hero cover, 3000×900 | `store-assets/cover-hero-3000x900.png` | Ready |
9999
| Icon, 512×512 | `store-assets/icon-512.png` | Ready |
100100
| Spatial foreground, 180×180 | `store-assets/icon-spatialized-180.png` | Optional; ready |
101-
| Screenshots, five at 2560×1440 | On-headset capture from the release candidate | Submitted to Meta |
101+
| Screenshots, five at 2560×1440 | `store-assets/screenshots/01-welcome.png`, `02-how-it-works.png`, `03-link-found.png`, `04-tutorial-scan.png`, `05-saved-links.png` | Overlay-free Quest captures (no marketing cards) |
102102
| Trailer | None | Optional; omitted for v1 |
103103

104104
## Current review state
105105

106-
- Metadata: `Submitted`
107-
- Native binary: HoloQR `1.0.2`, `Submitted`
108-
- Submission date: 2026-07-26
109-
- Review date: not assigned
110-
- Next dashboard action: after approval, choose immediate release or schedule the release
106+
- Metadata: **rejected** on 2026-09-02 (privacy name, screenshot overlays, Functional.1 freeze)
107+
- Native binary to resubmit: HoloQR `1.0.3` (`versionCode 4`)
108+
- Privacy policy must keep the exact store name **HoloQR**
109+
- Screenshots must be the overlay-free 2560×1440 plates in `store-assets/screenshots/`
110+
- Next dashboard action: replace privacy URL content (same GitHub raw URL), replace the five screenshots, upload `1.0.3`, resubmit

apps/quest-universal-qr-scanner/roadmap.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
>
55
> **Refreshed:** 2026-07-26
66
>
7-
> **Current release:** HoloQR `1.0.2` (`versionCode 3`) is submitted to Meta Horizon
8-
> Store review. The submitted binary is the output of the HoloScript release path.
7+
> **Current release:** HoloQR `1.0.2` was rejected in Meta Horizon Store review
8+
> on 2026-09-02. The resubmit candidate is `1.0.3`, authored from this HoloScript
9+
> source path.
910
1011
HoloQR is the first paid HoloScript-built product. The launch price is USD $3. Revenue matters,
1112
but it does not weaken the product invariant: a HoloQR version does not ship unless HoloScript
@@ -46,7 +47,7 @@ hidden hand-authored native behavior is a language/compiler gap and is not ready
4647
| Private state | Saved links stay in device-private storage; diagnostic receipts omit raw payloads and form a bounded HMAC chain. | [`scanner.holo`](./scanner.holo), [`PRIVACY.md`](./PRIVACY.md) |
4748
| World entry | Bundled worlds are compiler-registered. Remote worlds require an Ed25519 signature and explicit consent. | [`scanner.holo`](./scanner.holo), [`worlds/`](./worlds) |
4849
| Release provenance | Generation and an independent byte-match check run before signing or Gradle packaging. | [`README.md`](./README.md), [`RELEASE.md`](./RELEASE.md) |
49-
| Distribution | Metadata and native binary `1.0.2` are submitted to Meta Horizon Store review. | Meta submission `1114952735042547`, verified 2026-07-26 |
50+
| Distribution | `1.0.2` was rejected; `1.0.3` is the review-repair candidate. | Meta submission `1114952735042547`; privacy/screenshots/crash repairs in this version |
5051

5152
## Version sequence
5253

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Build Meta Horizon Store screenshots at exactly 2560×1440 with no extra logos, captions,
4+
* badges, or marketing copy (VRC.Quest.Asset.5). Sources are real Quest compositor captures.
5+
* Square captures are cover-cropped so the 16:9 frame is filled (no letterboxing).
6+
*
7+
* node apps/quest-universal-qr-scanner/scripts/gen-store-screenshots.mjs
8+
*/
9+
import { createHash } from 'node:crypto';
10+
import { mkdirSync, writeFileSync } from 'node:fs';
11+
import { dirname, join } from 'node:path';
12+
import { fileURLToPath } from 'node:url';
13+
import sharp from 'sharp';
14+
15+
const here = dirname(fileURLToPath(import.meta.url));
16+
const repoRoot = join(here, '..', '..', '..');
17+
const captureDir = join(repoRoot, '.scratch', '2026-07-26-holoqr-quest');
18+
const outDir = join(here, '..', 'store-assets', 'screenshots');
19+
mkdirSync(outDir, { recursive: true });
20+
21+
const WIDTH = 2560;
22+
const HEIGHT = 1440;
23+
24+
const slides = [
25+
{ file: '01-welcome.png', source: 'meta-compositor-welcome.jpg' },
26+
{ file: '02-how-it-works.png', source: 'meta-compositor-tutorial.jpg' },
27+
{ file: '03-link-found.png', source: 'meta-compositor-link.jpg' },
28+
{ file: '04-tutorial-scan.png', source: 'agent-panel-tutorial-scanning-fast.png' },
29+
{ file: '05-saved-links.png', source: 'meta-compositor-saved-links.jpg' },
30+
];
31+
32+
async function toStoreScreenshot(sourcePath) {
33+
return sharp(sourcePath)
34+
.resize(WIDTH, HEIGHT, { fit: 'cover', position: 'centre' })
35+
.png({ compressionLevel: 9, adaptiveFiltering: true })
36+
.toBuffer();
37+
}
38+
39+
const artifacts = [];
40+
for (const slide of slides) {
41+
const sourcePath = join(captureDir, slide.source);
42+
const bytes = await toStoreScreenshot(sourcePath);
43+
const info = await sharp(bytes).metadata();
44+
if (info.width !== WIDTH || info.height !== HEIGHT) {
45+
throw new Error(`${slide.file} is ${info.width}x${info.height}, expected ${WIDTH}x${HEIGHT}`);
46+
}
47+
writeFileSync(join(outDir, slide.file), bytes);
48+
artifacts.push({
49+
file: slide.file,
50+
source: slide.source,
51+
width: info.width,
52+
height: info.height,
53+
bytes: bytes.byteLength,
54+
sha256: createHash('sha256').update(bytes).digest('hex'),
55+
});
56+
console.log(` ${slide.file}`);
57+
}
58+
59+
const { unlinkSync, existsSync } = await import('node:fs');
60+
for (const staleName of ['04-tutorial-scanning.png', '04-scanning.png']) {
61+
const stale = join(outDir, staleName);
62+
if (existsSync(stale)) unlinkSync(stale);
63+
}
64+
65+
const receipt = {
66+
schemaVersion: 'holoscript.holoqr-store-screenshot-receipt.v0.3.0',
67+
kind: 'HoloQrStoreScreenshotReceipt',
68+
createdAt: new Date().toISOString(),
69+
rule: 'VRC.Quest.Asset.5 — unembellished in-experience frames, no extra logos/text/iconography',
70+
size: { width: WIDTH, height: HEIGHT },
71+
overlays: [],
72+
artifacts,
73+
};
74+
writeFileSync(join(outDir, 'store-screenshot-receipt.json'), `${JSON.stringify(receipt, null, 2)}\n`);
75+
console.log(`gen-store-screenshots: wrote ${artifacts.length} screenshot(s) → store-assets/screenshots/`);
993 KB
Loading
750 KB
Loading
683 KB
Loading
415 KB
Loading

0 commit comments

Comments
 (0)