ScanCraft is the blank slate: one room contract, one capture pipeline, three surfaces. Every client-facing product is a framework built on top of it, scoped to that client's professional field — real-estate staging first, paint estimating second. This sheet set stays live: as fresh scans come in from each surface, the showcase below replaces its placeholders with the real thing.
Proof over description. Once fresh scans are taken, each tile below is replaced with the real capture — same room, three surfaces. Send the screenshots/renders in and this section is republished to the same link; no self-serve upload is wired into the page itself, since asset storage isn't available for this artifact yet. Web turned out to be a special case: it's already live (Sheet A-006), so its tile is pending a screenshot, not pending a build.
ScanCraft itself stays generic on purpose — it doesn't know what a "room" is for. Everything a specific client needs is a framework layered on top, scoped to their professional field. Real-estate staging was the first framework built; paint estimating is the second. Nothing about the platform changes to add a third.
Three surfaces share one data contract — the RoomModel (walls + openings, meters). Today the PC app is the only one confirmed to read it end to end; mobile capture exists but is unrun on real hardware; the web surface turned out to already exist as a live prototype (Sheet A-006) — just not yet confirmed to speak the same contract.
capture-ios/ — a Swift RoomPlan app, written without a Mac and compiled only via .github/workflows/ios-capture.yml on GitHub's macOS runners (unsigned .ipa artifact). Its own README still says "RUNTIME UNVERIFIED — never run on a physical device." That's contradicted by evidence on this pass: real sensors.zip bundles from real scanned rooms exist (~6MB each) — a bundle that specific can only come from this app actually completing a RoomPlan/ARSession capture on real LiDAR hardware. The README needs its honest-status section updated; thermal/memory behavior and confidence-map accuracy at scale are still genuinely unproven.
One scan produces three files, dropped into the desktop app's import folder in one share-sheet send:
room.json — parametric walls/doors/windows (the RoomModel contract)room.usdz — the visual mesh backdrop, registered on the desktop sidesensors.zip — RGB + depth + pose bundle for photoreal reconstruction. Real scans have run ~6MB, comfortably under any relevant size limit, so bundles are now included going forward rather than treated as a maybe-too-big afterthought.| Path | Status | Note |
|---|---|---|
| AltStore | documented | Free Apple ID, auto-refreshes over shared Wi-Fi every 7 days. Confirmed in capture-ios/README.md. |
| Sideloadly + batch file | planned | Batch file on the Windows desktop pulls the latest Actions IPA and hands it to Sideloadly for install. Sideloadly's scriptability isn't confirmed — normally a GUI tool. Verify before building; AltStore is the fallback that's known to work headlessly. |
The first framework built on ScanCraft, and the one client vertical currently shipping. Godot 4.7, scenes/main.tscn / scripts/app.gd. Everything below reads the platform's RoomModel — nothing here reads geometry from the scan mesh directly, so none of it is actually staging-specific at the data layer, only at the UI layer.
Paint cost estimating is a separate framework (A-005), not a mode of this one — it needs none of the above, only the platform underneath it.
Every capture forks into two lanes that never touch until they land in the same app. The parametric lane is what paint, floorplan, and furniture actually read; the photoreal lane is backdrop only.
The second framework on ScanCraft, for a different client field entirely — a painter, not a real-estate agent. It shares nothing with the Staging framework except the platform underneath: same RoomModel, same three import paths (capture / trace / DXF), none of the furniture/dollhouse/lighting layer. Its only job is turning a scanned room into a number.
Cloudflare Pages, one account, three projects — confirmed on record, checked live this pass. Only parallax-scans.pages.dev is directly ScanCraft's; parallaxfuture.io hosts its inbox lane; the third is unrelated.
| Project | Domain | Role |
|---|---|---|
| parallaxfuture | parallaxfuture.io + wwwalias: parallaxfuture.pages.dev | Whole-site passphrase gate (_worker.js). Confirmed 401 live this pass. Hosts the /api/scan/* ingest lane for ScanCraft, exempted from the gate — see below. |
| parallax-scans | parallax-scans.pages.dev | Already live — checked this pass. A working "Stagecraft — prototype" demo: scan a room, place furniture, in-browser. Built for two named users, Michelle & Elisa. Self-labeled raw: unfinished walls, starter furniture. This is real evidence for Sheet A-003's staging framework, on a surface nobody had confirmed existed. |
| bulmer-consignment | bulmer-consignment.pages.dev | Thomaston auction gallery — unrelated business, noted for completeness only. |
Repo: A:\Parallax\parallaxfuture-site\
node drift-check.mjs && node build-dist.mjs
npx wrangler pages deploy _dist --project-name=parallaxfuture --branch=master --commit-dirty=true
_dist only. A 200 isn't proof — open the page and look./api/scan/* on parallaxfuture.io is gate-exempt (alongside eBay/Flip machinery routes) — reserved for ScanCraft. Its access token, SCAN_INBOX_TOKEN, has never been created. Until it is, the lane has no way to authenticate a real upload:
npx wrangler pages secret put SCAN_INBOX_TOKEN --project-name=parallaxfuture
SITE_GATE_PASS) was shared in conversation while assembling this sheet. It is deliberately not reproduced here — a live credential doesn't belong in a document that might later be shared. Rotate it via wrangler pages secret put SITE_GATE_PASS --project-name=parallaxfuture if this plan or the conversation it came from is ever shared onward.Resident-expert briefs for whichever agent (Coda CLI included) picks up work on a given surface — same idea as this sheet set, but scoped to sit next to the code as .claude/skills/<name>/SKILL.md rather than live as a standalone page. Drafted from what's actually been read this session, not guessed. Sent as .skill files rather than committed — this session has read-only access to parallax-stagecraft, no push.
| Skill | Covers | Grounded in |
|---|---|---|
| scancraft | Meta/resident brief — platform vs. framework, the RoomModel contract, where each surface's detail skill lives, pointer to this sheet set as the living source of truth. | Full repo read, Sheets A-000/A-001 |
| scancraft-godot | PC app — layout, mode table, why paint is parked and what not to do about it, the verification pattern (shot_app.gd-style driver scripts), which demo scenes are stale. | scripts/app.gd, room_model.gd, wall_builder.gd, PAINT-PARKED.md |
| scancraft-capture-ios | The no-Mac build constraint, the export + sensor-bundle contracts, sideload paths, the stale-README flag (RFI 09). | capture-ios/README.md, the CI workflow |
| scancraft-refinery | Python/Open3D environment quirks, the pose-conversion math, why trimesh over Open3D's own GLB writer, what's proven vs. still synthetic-only. | tools/refinery/README.md |
Deliberately skipped rather than guessed. parallaxfuture-site and scan-showcase live at local paths (A:\Parallax\...) not attached to or confirmed present on GitHub in this session — no code has actually been read, only the deployed output (Sheet A-006). Writing a "frontend" skill without reading the frontend would be exactly the kind of fabrication these skills are meant to prevent.
.skill file's SKILL.md into .claude/skills/<name>/SKILL.md in the parallax-stagecraft repo (or wherever Coda CLI's skills directory is configured). They validated clean against skill-creator's checker but were not run through its full eval loop — reasonable for resident-brief documentation skills, less so if any of them grow real generative behavior later.Two tracks that share almost no files, so they run in parallel by default: Meta/Marketing, and App Coding split three ways by surface. The one thing that crosses tracks is the RoomModel/export contract — whoever touches it posts to the Hub before changing it, since Web, iPhone, and PC all read it.
Mockups, brand testing, the mission statement — lives on parallaxfuture.io (the gated hub), separate from parallax-scans.pages.dev, which is Group W's product surface, not Group M's marketing surface. Don't conflate the two when routing work.
| Group | Scope | Skill |
|---|---|---|
| W — Web | parallax-scans.pages.dev + the /api/scan/* ingest lane on parallaxfuture.io (Sheet A-006) | none yet — repo not attached (Sheet A-007) |
| I — iPhone | capture-ios/, Swift/RoomPlan (Sheet A-002) | scancraft-capture-ios |
| P — PC | scripts/app.gd and the Godot app (Sheet A-003), plus the Python Refinery pipeline (Sheet A-004) as PC-side tooling feeding it | scancraft-godot, scancraft-refinery |
The Hub (coda-coop-space.json) is already the shared agent door for cross-agent handoffs, per the parallax-app skill — both tracks post status and shipped-work notes there rather than only in this sheet. This sheet stays the human-readable architecture record and RFI log; the Hub is the machine-speed coordination layer underneath it.
| # | Item | Assumption made here |
|---|---|---|
| 01 | "milds" functionality on mobile | Read as MLS listing sync. Diagrammed dashed on Sheet A-001 pending confirmation. |
| 02 | Sideloadly automation | Assumed scriptable for the desktop batch file; unconfirmed. AltStore is the proven fallback (Sheet A-002). |
| 03 | Web viewer scope | Partly resolved. Web is real: parallaxfuture.io (gated) + a confirmed-live prototype at parallax-scans.pages.dev (Sheet A-006). Still open: does that prototype read the same RoomModel/export pipeline as the PC app, or is it a separate hand-built implementation? And is it the long-term Web framework, or a precursor folded into parallaxfuture.io later? |
| 04 | Paint cost formula | v1 is a flat $/sqft placeholder (Sheet A-005) to see the UI shape. Coverage rate, coat count, price source, and per-wall vs. per-room rounding are all still open from the earlier planning pass. |
| 05 | Estimate labor cost | Out of scope for v1 — materials-only placeholder, no labor field yet. |
| 06 | Product renamed to ScanCraft | Applied on this sheet set only. The name still lives in real code/config the app runs on — project.godot's config/name, the in-app HUD string ("STAGECRAFT · 58 Western Ave" in app.gd), the export source tags (stagecraft-capture-ios, stagecraft-trace), capture-ios/README.md, and the parallax-stagecraft GitHub repo name itself. Renaming those is a real change for Coda CLI to make, not done here. |
| 07 | Framework packaging | Platform/framework is a conceptual split (Sheet A-000) introduced this pass — not yet a code or repo split. Open: does each framework (Staging, Paint Estimate, future clients) ship as its own Godot export with the platform as a shared module, or do they stay modes toggled inside one app like today's app.gd? The former scales to more clients without one app accreting every vertical's UI; the latter is far less restructuring right now. Recommend Coda CLI decide this before building A-005, since it changes where estimate.gd lives. |
| 08 | SCAN_INBOX_TOKEN un-minted | The /api/scan/* lane on parallaxfuture.io is carved out and gate-exempt but has no access token yet (Sheet A-006) — it can't authenticate a real upload until one is created. On you: npx wrangler pages secret put SCAN_INBOX_TOKEN --project-name=parallaxfuture. Not something this session can run — no Cloudflare/wrangler access from here. |
| 09 | capture-ios/README.md stale status claim | Says "RUNTIME UNVERIFIED — never run on a device"; real ~6MB scan bundles say otherwise (Sheet A-002). Small fix, not yet made — flagged in the new scancraft-capture-ios skill (Sheet A-007) so whoever picks this up checks before repeating the stale claim. |
| 10 | Where branding output lands | Ichi/Shep/ComfyUI graphics and sourced SVGs (Sheet A-008) don't have a defined handoff point yet — same Hub as code status notes, a separate asset folder, or something else? Affects whether Group M's output is discoverable by the other groups or just sits wherever it was generated. |